pshor...@dataworx.com.au writes: > Found it ... > > I had > > (define_expand "zero_extendhisi2" > [ > (set (subreg:HI (match_operand:SI 0 "general_operand" "")0) > (match_operand:HI 1 "general_operand" "")) > (set (subreg:HI (match_dup 0)2) > (const_int 0)) > ] > "" > "" > )
FWIW, in general you shouldn't use subregs in expanders, but instead use something like: (define_expand "zero_extendhisi2" [(set (match_operand:SI 0 "general_operand" "") (zero_extend:SI (match_operand:HI 1 "general_operand" "")))] "" { emit_move_insn (gen_lowpart (HImode, operands[0]), operands[1]); emit_move_insn (gen_highpart (HImode, operands[0]), const0_rtx); DONE; }) 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[0], <MODE>mode ) && !register_operand( operands[1], <MODE>mode )) { /* one of the operands must be in a register. */ operands[1] = copy_to_mode_reg (<MODE>mode, operands[1]); } 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. Thanks, Richard