https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102546
--- Comment #8 from Andrew Macleod <amacleod at redhat dot com> --- On 10/1/21 5:18 AM, aldyh at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102546 > > Aldy Hernandez <aldyh at gcc dot gnu.org> changed: > > What |Removed |Added > ---------------------------------------------------------------------------- > Last reconfirmed| |2021-10-01 > Status|UNCONFIRMED |NEW > Ever confirmed|0 |1 > Assignee|unassigned at gcc dot gnu.org |aldyh at gcc dot > gnu.org > > --- Comment #5 from Aldy Hernandez <aldyh at gcc dot gnu.org> --- > (In reply to Richard Biener from comment #4) >> (In reply to Aldy Hernandez from comment #2) >>> By VRP1 we seem to be calculating the following: >>> >>> (f_8 << f_8) && (f_8 == 0) >>> >>> This would fold to false, which would elide the foo(): >>> >>> <bb 7> [local count: 59055800]: >>> b = 0; >>> _3 = f_8 << f_8; >>> _4 = (char) _3; >>> _5 = (int) _4; >>> if (_4 > 0) >>> goto <bb 8>; [64.06%] >>> else >>> goto <bb 10>; [35.94%] >>> >>> <bb 8> [local count: 34842922]: >>> if (f_8 == 0) >>> goto <bb 9>; [71.10%] >>> else >>> goto <bb 10>; [28.90%] >>> >>> <bb 9> [local count: 12809203]: >>> foo (); >> I think it's similar to in the other PR, with old EVRP when visiting BB 8 >> we pushed [1, +INF] as the global range for _4, then supposedly ranger >> manages to evaluate f_8 == 0 with its backward infering somehow. >> >> We no longer do this "path sensitive" adjustment of (global) ranges since >> you removed the EVRP DOM walk algorithm. > The hybrid threader does path sensitive ranges and relationals. What's > missing > is the range-op entry for the following relation: > > ~[0,0] = x << x > > In this case, we know that X cannot be 0. Fixing this, causes all the right > things to happen. > > However, I see that the none of the op1_range entries are being called with a > relation. Presumably this was an oversight on Andrew's part, but can easily > be > fixed. Not an oversight. I believe I added the infrastructure to pass relations to GORI when I introduce relations to range-ops for folding, but there has not been time to flush out actually utilizing them yet. I can maybe take a look at that next week. maybe. It also opens up some possibilities for solving unsigned overflow questions: c_1 = a_2 + 2 if (c_1 < a_2) // check overflow condition On the true edge, solving [1,1] = c_1 < a_2... would propagate c_1 < a_2 to the defining insn as: [varying] = a_2 + 2, (LHS < a_2). op1_range for PLUS can use that relation to determine that a_2 must be fully contained in [INF - 1, INF] on the TRUE side, and therefore c_1 is [0,1]. The false side would then also calculate a_2 = [0, INF - 2] and c_1 as [2, INF] > Interestingly on this case, the VRP threader shouldn't even need to step up > here. VRP1 should have folded the conditional in BB8. The new evrp can > though. If I tweak range-ops, and call execute_early_vrp() from VRP1, evrp > folds the conditional and there's no need to thread. > > Now before Andrew asks why evrp doesn't clean this up earlier (with the > range-ops tweak), it's because the IL is different. See my question about the > "a" present in earlier passes. ;-) > > So...mine. I'll address all the issues pointed out. >