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.

Reply via email to