https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67028
--- Comment #2 from renlin at gcc dot gnu.org ---
(In reply to Segher Boessenkool from comment #1)
> I have a hard time reproducing this. Could you show the generated
> assembler code, and say why you think it is a combine bug?
This is my generated asm with this command "cc1 -O3 -march=armv7-a test.c"
stmfd sp!, {r4, lr}
mov r1, #0
movw r0, #:lower16:.LC0
movt r0, #:upper16:.LC0
bl printf
mov r0, #0
ldmfd sp!, {r4, pc}
In simplify_comparison(), for the following rtx pattern,
and:M1 (subreg:M2 X 0) (const_int C1))
the code will try to permute the SUBREG and AND when WORD_REGISTER_OPERATIONS
is defined and the subreg here is Paradoxical. There is an assumption here: the
upper bits of the subreg should all be zeros.
However, this is not always true. In this particular test case, the AND
operation, which ensures the higher bits are zero, is removed. The register
here has two CONST_INT values in a if-then-else pattern. When further
simplifying this if-then-else pattern, subreg is applied to those two CONST_INT
value.
In simplify_immed_subreg, CONST_INT is always signed extended to a larger mode.
The different assumptions cause the wrong code-generation.
What's more, in the gcc internal documentation, it's written: "subregs of
subregs are not supported"
However, "subreg of subreg" pattern will be generated by combine pass, and
simplified by simplify_subreg().
For example:
subreg:SI (subreg:HI reg:SI r10) ----> reg:SI r10