https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93917
Bug ID: 93917 Summary: VRP forgets range of value read from memory Product: gcc Version: 10.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: glisse at gcc dot gnu.org Target Milestone: --- First a case that works: void f(int n){ if(n<0)__builtin_unreachable(); } EVRP assigns a range to n, and VRP1 folds the comparison to false. Let's add an indirection: void f(int*n){ if(*n<0)__builtin_unreachable(); } EVRP still assigns a range to *n, but now VRP1 seems to forget that range, does not fold the comparison, and reassigns a range to *n. And again in VRP2. __builtin_unreachable survives all the way to FAB, which in my original code prevents any loop optimization. I know of plans to fold __builtin_unreachable earlier always, which would likely solve the issue, but independently of that, it seems that VRP is dropping some interesting information present in old ranges, possibly because a memory read is not considered an interesting statement.