https://gcc.gnu.org/g:d4b40362327691b903fee90c01fe9586d2b60ecf

commit r15-11225-gd4b40362327691b903fee90c01fe9586d2b60ecf
Author: Jakub Jelinek <[email protected]>
Date:   Tue Apr 28 09:28:44 2026 +0200

    range-op-float: Fix ICE on undefined_p ranges [PR125039]
    
    The following testcase ICEs at -O1 since r14-4153.
    lower_bound/upper_bound methods on frange (and others) assert
    they aren't called on undefined_p () ranges, because such ranges
    don't really have any lower or upper bound.
    Most fold_range virtual methods call empty_range_varying early
    which checks if the operand ranges aren't undefined and in that case
    return true and set r to varying, and then can safely use
    lower_bound/upper_bound etc.
    Now, operator_not_equal::fold_range did that until r14-4152 indirectly,
    by calling it in frelop_early_resolve which it called unconditionally.
    r14-4153 changed it not to call frelop_early_resolve in some cases
    because it could misbehave as mentioned in the comment.
    frelop_early_resolve has 3 conditionals it handles.
      if (!maybe_isnan (op1, op2) && relation_union (rel, my_rel) == my_rel)
    doesn't apply for this case, because the
      if (rel == VREL_EQ && maybe_isnan (op1, op2))
    condition means maybe_isnan (op1, op2) will be true.
      if (relation_intersect (rel, my_rel) == VREL_UNDEFINED)
    is the condition which r14-4153 wanted to avoid.  And finally
      if (empty_range_varying (r, type, op1, op2))
    is the condition the following patch readds, so that we don't ICE on those.
    
    2026-04-27  Jakub Jelinek  <[email protected]>
    
            PR tree-optimization/125039
            * range-op-float.cc (operator_not_equal::fold_range): Call
            empty_range_varying when not calling frelop_early_resolve.
    
            * gcc.c-torture/compile/pr125039.c: New test.
    
    Reviewed-by: Richard Biener <[email protected]>
    (cherry picked from commit 62d5880b9599c3bdbc22b80d522b0bea14f4beaf)

Diff:
---
 gcc/range-op-float.cc                          |  3 +++
 gcc/testsuite/gcc.c-torture/compile/pr125039.c | 12 ++++++++++++
 2 files changed, 15 insertions(+)

diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index 4719829974de..dad3675308f0 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -759,6 +759,9 @@ operator_not_equal::fold_range (irange &r, tree type,
       // Avoid frelop_early_resolve() below as it could fold to FALSE
       // without regards to NANs.  This would be incorrect if trying
       // to fold x_5 != x_5 without prior knowledge of NANs.
+      // Still, if either operand is undefined, return VARYING.
+      if (empty_range_varying (r, type, op1, op2))
+       return true;
     }
   else if (frelop_early_resolve (r, type, op1, op2, trio, VREL_NE))
     return true;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr125039.c 
b/gcc/testsuite/gcc.c-torture/compile/pr125039.c
new file mode 100644
index 000000000000..955b24709c4f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr125039.c
@@ -0,0 +1,12 @@
+/* PR tree-optimization/125039 */
+
+void
+foo ()
+{
+  double b = b, c = c;
+  if (c)
+    c = -c;
+  double d = b == c ? b : c;
+  if (c != d)
+    foo ();
+}

Reply via email to