Hi all,
I'm investigating a testsuite failure on arm: gcc.target/arm/unsigned-extend-1.c
For code:
unsigned char foo (unsigned char c)
{
return (c >= '0') && (c <= '9');
}
we end up generating:
sub r0, r0, #48
uxtb r0, r0
cmp r0, #9
movhi r0, #0
movls r0, #1
bx lr
The extra uxtb (extend) is causing the test to fail. We started generating the
extra extend when a particular optimisation went in with (revision r191928).
The comment in simplify-rtx.c says it transforms
(truncate:SI (op:DI (x:DI) (y:DI)))
into
(op:SI (truncate:SI (x:DI)) (truncate:SI (x:DI)))
but from what I can see it also transforms
(truncate:QI (op:SI (x:SI) (y:SI)))
into
(op:QI (truncate:QI (x:SI)) (truncate:QI (x:SI)))
From the combine dump I see that the sub and extend operations come from the
RTL:
(insn 6 3 7 2 (set (reg:SI 116)
(plus:SI (reg:SI 0 r0 [ c ])
(const_int -48 [0xffffffffffffffd0])))
(insn 7 6 8 2 (set (reg:SI 117)
(zero_extend:SI (subreg:QI (reg:SI 116) 0)))
If I add a QImode compare pattern to the arm backend it gets matched and the
extra extend goes away, but it seems to me that that's not the correct solution.
Ideally, if a QImode operation is performed as an SImode operation on a target
(like the sub and compare operations on arm) then we should not be doing this
optimisation?
My question is, how does one express that information in the simplify-rtx.c
code?
It seems that the PR that optimisation fixed (54457) only cared about DI -> SI
truncations, so perhaps we should disable it for conversions between other modes
where it's not beneficial altogether?
Thanks,
Kyrill