https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24021
Aldy Hernandez <aldyh at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jeffreyalaw at gmail dot com, | |richard.guenther at gmail dot com --- Comment #6 from Aldy Hernandez <aldyh at gcc dot gnu.org> --- Preview of what's to come. Implementing a bare bones frange class and associated relational operators in range-ops we can get: void link_error(); void func(); int foo(float f) { if (f > 3.0) { func(); if (f < 2.0) link_error(); } } Folding statement: if (f_2(D) > 3.0e+0) Not folded Folding statement: func (); Not folded Folding statement: if (f_2(D) < 2.0e+0) Folding predicate f_2(D) < 2.0e+0 to 0 Folded into: if (0 != 0) And we can also get symbolics: int bar(float f, float g) { if (f > g) { func(); if (f < g) link_error(); } } Folding statement: if (f_2(D) < g_3(D)) folding with relation f_2(D) > g_3(D) Folding predicate f_2(D) < g_3(D) to 0 Folded into: if (0 != 0) My proof of concept has ranger dumps looking like: =========== BB 2 ============ Imports: f_2(D) Exports: f_2(D) f_2(D) float VARYING <bb 2> : if (f_2(D) > 3.0e+0) goto <bb 3>; [INV] else goto <bb 5>; [INV] 2->3 (T) f_2(D) : float (3.0e+0, +Inf] 2->5 (F) f_2(D) : float [-Inf, 3.0e+0] Interestingly, since the threader uses ranger, I had to turn off the threader for the above snippets, because ethread gets the first one before evrp even gets a whack at it: [1] Registering jump thread: (2, 3) incoming edge; (3, 5) nocopy; path: 2->3->5 SUCCESS Removing basic block 3 ;; basic block 3, loop depth 0 ;; pred: func (); if (f_2(D) < 2.0e+0) goto <bb 4>; [INV] else goto <bb 5>; [INV] ;; succ: 4 ;; 5 As I've mentioned, I'm hoping some floating expert can take this across to goal line, as my head will start spinning as soon as we start talking about NANs and such. The range-op work will likely require floating specialized knowledge.