http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49263
Oleg Endo <olegendo at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|RESOLVED |REOPENED
Last reconfirmed| |2012-08-27
Resolution|FIXED |
AssignedTo|unassigned at gcc dot |olegendo at gcc dot gnu.org
|gnu.org |
Ever Confirmed|0 |1
--- Comment #18 from Oleg Endo <olegendo at gcc dot gnu.org> 2012-08-27
19:51:42 UTC ---
Not quite so done, actually. The following example case does not work
properly:
void test00 (int* x, int xb)
{
if (! (xb & 128))
x[0] = 0;
}
-O2 -m4:
mov r5,r0
and #128,r0
tst r0,r0
bf .L3
mov.l r0,@r4
.L3:
rts
nop
void test01 (int* x, int xb)
{
if (! (xb & 0x55))
x[0] = 0;
}
-O2 -m4:
mov r5,r0
and #85,r0
tst r0,r0
bf .L7
mov.l r0,@r4
.L7:
rts
nop
It seems that combine is trying to look for the following patterns:
Failed to match this instruction:
(set (pc)
(if_then_else (ne (zero_extract:SI (reg:SI 5 r5 [ xb ])
(const_int 1 [0x1])
(const_int 7 [0x7]))
(const_int 0 [0]))
(label_ref:SI 15)
(pc)))
Failed to match this instruction:
(set (pc)
(if_then_else (ne (and:SI (reg:SI 5 r5 [ xb ])
(const_int 85 [0x55]))
(const_int 0 [0]))
(label_ref:SI 15)
(pc)))
Another case that could see some improvement ...
bool test04 (int* x, int xb)
{
return ! (xb & 0x55);
}
-O2 -m4 (OK):
mov r5,r0
tst #85,r0
rts
movt r0
bool test02 (int* x, int xb)
{
return ! (xb & (1 << 6));
}
-O2 -m4 (NG):
mov r5,r0
mov #-6,r1
shld r1,r0
xor #1,r0
rts
and #1,r0