https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71563
Marc Glisse <glisse at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2016-06-17 Summary|Regression in GCC-7.0.0's |[6/7 Regression] Regression |optimizer. |in GCC-7.0.0's optimizer. Ever confirmed|0 |1 --- Comment #1 from Marc Glisse <glisse at gcc dot gnu.org> --- Surprisingly, in gcc-5, this all gets simplified in RTL. In gcc-6, we do the first step of the optimization in gimple, and that prevents RTL from doing the rest, probably because we lose the fact that (1/k)<<8 is used in a (truncated) shift. In gimple, we have now: k.0_1 ={v} k; _2 = 1 / k.0_1; _3 = _2 << 8; if (_3 != 0) We could turn (a << 8) != 0 into a != 0 because of the range of a. More generally, we could produce (a & CST) != 0, but I am not sure it is always a win, and then we still need to drop the & CST. And then we would be left with (1 / k) != 0 (the range is [-1,1]), which could possibly become (unsigned)k+1<=2, but not a constant. So the first optimization from (1 << X) != 1 to X != 0 lost the information. To preserve it, we would need, before that transformation, to notice that (1/k)<<8 has enough low-order zero bits that 0 is the only valid value it can have in a shift. CCP seems like the only time this could happen (though the transformation itself could be in match.pd or elsewhere). Note that in any case the optimization will be fragile. That could be because the testcase seems a bit artificial.