[gcc r17-2516] Enhance logical AND and OR op1_range.

Andrew Macleod via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:7306944cffc49249c4947e6f9b13130986f24f5a

commit r17-2516-g7306944cffc49249c4947e6f9b13130986f24f5a
Author: Andrew MacLeod <[email protected]>
Date:   Thu Jul 16 16:43:40 2026 -0400

    Enhance logical AND and OR op1_range.
    
    The rangeops should recognize that
      [0, 0] = op1 & TRUE    -->  op1 must be [0, 0]
      [1, 1] = op1 | FALSE   -->  op1 must be [1, 1]
    
    op2_range simple transposes the operands, so this covers both cases.
    
            PR tree-optimization/126212
            * range-op.cc (operator_logical_and::op1_range): Add case for
            [0, 0] = op1 & [1, 1]
            (operator_logical_or::op1_range): Add case for [1, 1] = op1 | [0, 0]

Diff:
---
 gcc/range-op.cc | 72 +++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 45 insertions(+), 27 deletions(-)

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 94edfdc98708..a1a479a8319a 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -3420,22 +3420,31 @@ operator_logical_and::fold_range (irange &r, tree type,
 bool
 operator_logical_and::op1_range (irange &r, tree type,
 				 const irange &lhs,
-				 const irange &op2 ATTRIBUTE_UNUSED,
+				 const irange &op2,
 				 relation_trio) const
 {
-   switch (get_bool_state (r, lhs, type))
-     {
-     case BRS_TRUE:
-       // A true result means both sides of the AND must be true.
-       r = range_true (type);
-       break;
-     default:
-       // Any other result means only one side has to be false, the
-       // other side can be anything.  So we cannot be sure of any
-       // result here.
-       r = range_true_and_false (type);
-       break;
-     }
+  switch (get_bool_state (r, lhs, type))
+    {
+    case BRS_TRUE:
+      // A TRUE result means both sides of the AND must be true.
+      r = range_true (type);
+      return true;
+
+    case BRS_FALSE:
+      // A FALSE result when op2 is TRUE, must have op1 FALSE.
+      if (!op2.contains_p (wi::zero (TYPE_PRECISION (op2.type ()))))
+	{
+	  r = range_false (type);
+	  return true;
+	}
+      break;
+
+    default:
+      break;
+    }
+
+  // Any other result means we cannot be sure of any result.
+  r = range_true_and_false (type);
   return true;
 }
 
@@ -3950,22 +3959,31 @@ operator_logical_or::fold_range (irange &r, tree type ATTRIBUTE_UNUSED,
 bool
 operator_logical_or::op1_range (irange &r, tree type,
 				const irange &lhs,
-				const irange &op2 ATTRIBUTE_UNUSED,
+				const irange &op2,
 				relation_trio) const
 {
-   switch (get_bool_state (r, lhs, type))
-     {
-     case BRS_FALSE:
-       // A false result means both sides of the OR must be false.
-       r = range_false (type);
-       break;
-     default:
-       // Any other result means only one side has to be true, the
-       // other side can be anything. so we can't be sure of any result
-       // here.
-       r = range_true_and_false (type);
-       break;
+  switch (get_bool_state (r, lhs, type))
+    {
+    case BRS_FALSE:
+      // A false result means both sides of the OR must be false.
+      r = range_false (type);
+      return true;
+
+    case BRS_TRUE:
+      // A TRUE result when op2 is FALSE must have op1 TRUE.
+      if (op2.zero_p ())
+	{
+	  r = range_true (type);
+	  return true;
+	}
+      break;
+
+    default:
+      break;
     }
+
+  // Any other result means we cannot be sure of any result.
+  r = range_true_and_false (type);
   return true;
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.