https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85941
Bug ID: 85941 Summary: Zero extend from QI->SI lost if QI is referred to via subreg:HI Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: jozef.l at mittosystems dot com Target Milestone: --- Created attachment 44190 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44190&action=edit testcase In the combine RTL stage, (zero_extend:SI (subreg:HI (reg:QI 28) 0))) becomes (zero_extend:SI (reg:HI 12 R12))) at -O1 and above. A reduced test case based on pr39240.c is attached, observed with msp430-elf. It fails on execution with current trunk as the necessary instruction to zero extend R12 (AND #0xff, R12) is lost. On native x86_64, a subreg expression is not used to reference the QI reg, so this problem isn't seen. See zero_extendqisi2 in gcc/config/msp430/msp430.md: (define_insn "zero_extendqisi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=r") (zero_extend:SI (subreg:HI (match_operand:QI 1 "nonimmediate_operand" "rm") 0)))] If the subreg:HI expression is removed from the insn pattern, the zero extension from QI->SI is present in the output assembly, and the test case executes correctly: (define_insn "zero_extendqisi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=r") (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))] I am not aware of why the first pattern would be incorrect, so is this a bug in combine rather than the insn pattern? Observed with 7.3.1 and current trunk 9.0.0.