Convert foo() into baz(). void bar (void); void foo (int a) { int b = 1 << a; if (b & 1) bar (); } void baz (int a) { if (a == 0) bar (); } You might think this is so artificial but actually comes from simplify_comparison() in combine.c, a part of which looks like <L344>:; T.4338_976 = (int)T.4337_966; T.4546_977 = T.4338_976 - 1; T.4547_978 = 1 << T.4546_977; T.4548_979 = T.4547_978 & 1; T.4549_980 = (_Bool)T.4548_979; if (T.4549_980 == 0) goto <L555>; else goto <L345>;
Confirmed.
As of today, the last tree-ssa form of foo() looks like: foo (a) { int b; _Bool T.1; int T.0; <bb 0>: b_2 = 1 << a_1; T.0_3 = b_2 & 1; if (T.0_3 != 0) goto <L0>; else goto <L1>; <L0>:; bar () [tail call]; <L1>:; return; }
When fold could optimize (1 << a) & 1, PR 15495 will fix the testcase in this bug.
Hmm, we do optimize this with ashiftrt but not with ashift. We also fold ((1 << a) & 1) != 0 into ((1 >> a & 1) != 0) which gets optimized on the RTL level.
This was fixed in gcc-5.