[Bug tree-optimization/114041] wrong code with _BitInt() and -O -fgraphite-identity
jakub at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Tue Feb 27 16:50:15 GMT 2024
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114041
--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Reduced testcase:
unsigned a[24], b[24];
__attribute__((noipa)) unsigned
foo (unsigned _BitInt(4) x)
{
for (int i = 0; i < 24; ++i)
a[i] = i;
unsigned e = __builtin_stdc_bit_ceil (x);
for (int i = 0; i < 24; ++i)
b[i] = i;
return e;
}
int
main ()
{
if (foo (0) != 1)
__builtin_abort ();
}
I have to confirm Andrew's comment, before the graphite dump there was
if (x_14(D) > 1)
goto <bb 5>; [59.00%]
else
goto <bb 11>; [41.00%]
<bb 11> [local count: 17609365]:
goto <bb 6>; [100.00%]
<bb 5> [local count: 25340307]:
_2 = x_14(D) + 15;
_3 = (unsigned int) _2;
_4 = __builtin_clz (_3);
_5 = 31 - _4;
_6 = 2 << _5;
iftmp.1_15 = (unsigned int) _6;
<bb 6> [local count: 42949672]:
# iftmp.1_10 = PHI <iftmp.1_15(5), 1(11)>
This isn't part of any kind of loop, it is in between 2 different loops.
Graphite hoists some of the statements to bb 2 where it is unconditional:
_32 = x_14(D) + 15;
_33 = (unsigned int) _32;
the rest of it remains after the first loop, but is now unconditional:
<bb 18> [count: 0]:
_47 = 1;
_31 = __builtin_clz (_33);
_34 = 31 - _31;
_35 = 2 << _34;
iftmp.1_36 = (unsigned int) _35;
_48 = iftmp.1_36;
iftmp.1_37 = _48;
In the testcase x is 0, so __builtin_stdc_bit_ceil returns 1, but when we take
the > 1
path, it is 2 << (31 - 24) instead.
The above feels like what ifcvt would do, if that _47 in there stands for one
of the phi arguments and _48 for the other. Except __builtin_clz invokes UB
when run on 0 (which is one of the reasons why it was guarded) and there is no
conditional merging at the end.
More information about the Gcc-bugs
mailing list