operator_lshift::op1_rangeĀ  was not handling UNDEFINED properly if it determined that there was no combination of LHS and OP2 that resulted in a value.

Return false which indicates we should stop trying to calculate a range, which will also terminate the reverse search for a value. If the edge or block is undefined, trying to produce a value has little value.

Bootstrapped on x86_64-pc-linux-gnu with no regressions. Pushed.

Andrew

From 0bf6e399dbc8e1f6d2b3f7e0f3a0cab9ac55b572 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <[email protected]>
Date: Wed, 5 Aug 2026 14:05:33 -0400
Subject: [PATCH 1/4] Check for undefined in operator_lshift::op1_range.

If we conclude that the op1_range calculation is undefined, simply
abort the calculation.

	PR tree-optimization/126648
	gcc/
	* range-op.cc (operator_lshift::op1_range): Handle undefined.

	gcc/testsuite/
	* gcc.dg/pr126648.c: New.
---
 gcc/range-op.cc                 |  4 ++++
 gcc/testsuite/gcc.dg/pr126648.c | 31 +++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/pr126648.c

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 07413ef7054..333ac748815 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -2897,6 +2897,10 @@ operator_lshift::op1_range (irange &r,
       else
 	op_rshift.fold_range (tmp_range, utype, lhs, op2);
 
+      // If no valid range is found, abort the calculation and return falae.
+      if (tmp_range.undefined_p ())
+	return false;
+
       // Start with ranges which can produce the LHS by right shifting the
       // result by the shift amount.
       // ie   [0x08, 0xF0] = op1 << 2 will start with
diff --git a/gcc/testsuite/gcc.dg/pr126648.c b/gcc/testsuite/gcc.dg/pr126648.c
new file mode 100644
index 00000000000..44272d20e44
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr126648.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+long a;
+char b;
+short c;
+int f(int g) {
+  {
+    unsigned h = g;
+    {
+      long d = h;
+      int e = 0;
+      do {
+        if ((h & 15) == 4)
+          d = d + (h << 5);
+        if (d == 5)
+          break;
+        e = e + 1;
+      } while (e < 3);
+      c = d;
+    }
+  }
+  return c;
+}
+char k() {
+  long i;
+  unsigned j = b % 6u + 4;
+  while (a)
+    i = f(j + 826);
+  return i;
+}
+int main() {}
-- 
2.45.0

Reply via email to