https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91865
Bug ID: 91865
Summary: Combine misses opportunity to remove (sign_extend
(zero_extend)) before searching for insn patterns
Product: gcc
Version: 9.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: jozefl.gcc at gmail dot com
Target Milestone: ---
Created attachment 46913
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46913&action=edit
msp430-movqipsi.diff
The following program generates poor code for msp430-elf in the large memory
model:
const int table[2] = {1, 2};
int
foo (char i)
{
return table[i];
}
> msp430-elf-gcc -S tester.i -mlarge -Os
The RTL generated by expand uses two insns to convert "i" to a register's
natural mode; there is a sign extension which would be unnecessary if the first
instruction had a PSImode register as the lvalue:
(insn 2 4 3 2 (set (reg/v:HI 25 [ i ])
(zero_extend:HI (reg:QI 12 R12 [ i ])))
(nil))
.....
(insn 7 6 8 2 (set (reg:PSI 28)
(subreg:PSI (sign_extend:SI (reg/v:HI 25 [ i ])) 0))
(nil))
All we really need is:
(insn (set (reg:PSI 28 [ i ])
(zero_extend:PSI (reg:QI 12 R12 [ i ])))
(nil))
Combine tries to combine the insns but doesn't recognize that
the following transformation could be applied:
(sign_extend:PSI (zero_extend:HI)) -> (zero_extend:PSI)
Trying 2 -> 7:
2: r25:HI=zero_extend(R12:QI)
REG_DEAD R12:QI
7: r28:PSI=sign_extend(r25:HI)#0
REG_DEAD r25:HI
Failed to match this instruction:
(set (reg:PSI 28 [ i ])
(sign_extend:PSI (zero_extend:HI (reg:QI 12 R12 [ i ]))))
Failed to match this instruction:
(set (reg:PSI 28 [ i ])
(sign_extend:PSI (and:HI (reg:HI 12 R12)
(const_int 255 [0xff]))))
A separate issue is that the movqipsi pattern is undefined, a patch containing
the pattern is attached and would match if the above transformation were
applied by combine.