On Mon, Nov 12, 2018 at 12:53:26PM +0000, Andrew Stubbs wrote: > >>+/* Implement TARGET_LEGITIMATE_COMBINED_INSN. > >>+ > >>+ Return false if the instruction is not appropriate as a combination > >>of two > >>+ or more instructions. */ > >>+ > >>+bool > >>+gcn_legitimate_combined_insn (rtx_insn *insn) > >>+{ > >>+ rtx pat = PATTERN (insn); > >>+ > >>+ /* The combine pass tends to strip (use (exec)) patterns from insns. > >>This > >>+ means it basically switches everything to use the *_scalar form of > >>the > >>+ instructions, which is not helpful. So, this function disallows > >>such > >>+ combinations. Unfortunately, this also disallows combinations of > >>genuine > >>+ scalar-only patterns, but those only come from explicit expand code. > >>+ > >>+ Possible solutions: > >>+ - Invent TARGET_LEGITIMIZE_COMBINED_INSN. > >>+ - Remove all (use (EXEC)) and rely on md_reorg with "exec" > >>attribute. > >>+ */ > >This seems a bit hokey. Why specifically is combine removing the USE? > > I don't understand combine fully enough to explain it now, although at > the time I wrote this, and in a GCC 7 code base, I had followed the code > through and observed what it was doing. > > Basically, if you have two patterns that do the same operation, but one > has a "parallel" with an additional "use", then combine will tend to > prefer the one without the "use". That doesn't stop the code working, > but it makes a premature (accidental) decision about instruction > selection that we'd prefer to leave to the register allocator. > > I don't recall if it did this to lone instructions, but it would > certainly do so when combining two (or more) instructions, and IIRC > there are typically plenty of simple moves around that can be easily > combined.
If you don't want useless USEs deleted, use UNSPEC_VOLATILE instead? Or actually use the register, i.e. as input to an actually needed instruction. If combine is changing an X and a USE to just that X if it can, combine is doing a great job! (combine cannot "combine" one instruction, fwiw; this sometime could be useful (so just run simplification on every single instruction, see if that makes a simpler valid instruction; and indeed a common case where it can help is if the insn is a parallel and one of the arms of that isn't needed). Segher