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

Reply via email to