This is the mail archive of the
mailing list for the GCC project.
Re: Unable to match instruction pattern
- From: Paul Shortis <pshortis at dataworx dot com dot au>
- To: gcc at gcc dot gnu dot org
- Date: Tue, 15 Apr 2014 08:05:13 +1000
- Subject: Re: Unable to match instruction pattern
- Authentication-results: sourceware.org; auth=none
- References: <534476C4 dot 3060809 at dataworx dot com dot au> <5345D557 dot 8010809 at davidgf dot es> <de7ea6ac386b258d36741347e2c14068 at dataworx dot com dot au> <87fvljzpzv dot fsf at talisman dot default>
- Reply-to: pshortis at dataworx dot com dot au
That worked just as you suggested, and ... when I removed my
zero_extendhisi2 the IIRC the target-independent optabs code
generated exactly the same sequence.
Interestingly, I noticed that changing from my define_insn
"zero_extendhisi2" back to the define_expand "zero_extendhisi2"
caused some optimisation opportunities to be missed where an
expression calculated in 32 bits could equally well performed at
the natural 16 bit word width (because the result of the
calculation was truncated to 16 bits) :-)
On 12/04/14 04:21, Richard Sandiford wrote:
Found it ...
(set (subreg:HI (match_operand:SI 0 "general_operand" "")0)
(match_operand:HI 1 "general_operand" ""))
(set (subreg:HI (match_dup 0)2)
FWIW, in general you shouldn't use subregs in expanders, but instead use
[(set (match_operand:SI 0 "general_operand" "")
(zero_extend:SI (match_operand:HI 1 "general_operand" "")))]
emit_move_insn (gen_lowpart (HImode, operands), operands);
emit_move_insn (gen_highpart (HImode, operands), const0_rtx);
This allows MEMs to be simplified to smaller MEMs, which is preferable
to keeping them as SUBREGs. It also allows subregs of hard registers
to be simplified to simple REGs and handles constants correctly.
IMO SUBREGs of MEMs should go away. There's this strange convention
that (subreg (mem ...)) is treated as a register_operand before reload,
which is why:
if( !register_operand( operands, <MODE>mode )
&& !register_operand( operands, <MODE>mode ))
/* one of the operands must be in a register. */
operands = copy_to_mode_reg (<MODE>mode, operands);
wouldn't trigger for a move between a constant and a subreg of a MEM.
OTOH, you should be better off not defining the zero_extendhisi2 at all,
since IIRC the target-independent optabs code would generate the same
sequence for you.