https://gcc.gnu.org/g:48923fca19458948d33351b506319efa3af9e40a

commit r16-4616-g48923fca19458948d33351b506319efa3af9e40a
Author: Andrew MacLeod <[email protected]>
Date:   Fri Oct 24 15:09:51 2025 -0400

    Refine COND_EXPR ranges better.
    
    Recognize COND_EXPRs where there is only one ssa_name used in the
    condition as well as one of the fields in the COND_EXPR.  ie:
    
      cond = ssa_name < 20
      result = cond ? ssa_name : 20
    
    Adjust the range of ssa_name to reflect the conditional value of ssa_name
    relative to whether its in the TRUE or FALSE part of the COND_EXPR.
    
            PR tree-optimization/114025
            gcc/
            * gimple-range-fold.cc (fold_using_range::condexpr_adjust): Handle
            the same ssa_name in the condition and the COND_EXPR better.
    
            gcc/testsuite/
            * g++.dg/pr114025.C: New.

Diff:
---
 gcc/gimple-range-fold.cc        | 11 +++++++++++
 gcc/testsuite/g++.dg/pr114025.C | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)

diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index d18b37b33800..06c645f3d081 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -1187,6 +1187,17 @@ fold_using_range::condexpr_adjust (vrange &r1, vrange 
&r2, gimple *, tree cond,
          ssa2, src))
        r2.intersect (tmp2);
     }
+  // If the same name is specified in the condition and COND_EXPR,
+  // combine the calculated condition range and the other one provided. ie:
+  // c_1 = b_2 < 10
+  // f_3 = c_1 ? 0 : b_2
+  // With b_2 providing the false value, the value of f_3 will be
+  // either 0 UNION  (0 = b_2 < 10), which is [-INF, 9].
+  // COND_EXPR is
+  if (ssa1 && cond_name == ssa1)
+    r1 = cond_true;
+  else if (ssa2 && cond_name == ssa2)
+    r2 = cond_false;
   return true;
 }
 
diff --git a/gcc/testsuite/g++.dg/pr114025.C b/gcc/testsuite/g++.dg/pr114025.C
new file mode 100644
index 000000000000..61bb8f151fc1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr114025.C
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options " -O3 -std=gnu++17 -ffinite-math-only -fdump-tree-optimized" } 
*/
+
+#include <algorithm>
+#include <stdexcept>
+
+#define AINLINE
+
+class TestClass
+{
+public:
+    AINLINE void SetValue(float value);
+
+private:
+    float m_Value;
+};
+
+AINLINE
+void TestClass::SetValue(float value)
+{
+    if (value >= 0.0f && value <= 100.0f) {
+        m_Value = value;
+    }
+    else {
+        throw std::out_of_range("Value must be [0, 100].");
+    }
+}
+
+void TestFunc(TestClass& t, float value)
+{
+    value = std::clamp(value, 30.0f, 50.0f);
+    // When TestClass::SetValue is inlined, the exception throwing code is not 
eliminated.
+    // Given that at this point we can prove that 'value' lies in the range 
[30.0f, 50.0f] well within the range required by the setter function, we can 
rid the not taken paths of code.
+    t.SetValue(value);
+}
+
+
+/* { dg-final { scan-tree-dump-times "std::out_of_range::out_of_range" 1 
"optimized" } } */
+

Reply via email to