aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@redhat.com>2024-10-31 14:07:00 -0400
committerAndrew MacLeod <amacleod@redhat.com>2024-11-01 15:24:10 -0400
commit253fe0f6269516e37b3ef12a0d18e539b3cabd62 (patch)
tree71d80c21ee2b6be000cb45b59887a28c71164bea
parent62420dbd105bbc4fe732881875c5c85aa55b6069 (diff)
downloadgcc-253fe0f6269516e37b3ef12a0d18e539b3cabd62.zip
gcc-253fe0f6269516e37b3ef12a0d18e539b3cabd62.tar.gz
gcc-253fe0f6269516e37b3ef12a0d18e539b3cabd62.tar.bz2
Update bitwise_or op_range.
If the LHS of a bitwise OR is positive, then so are both operands when using op1_range or op2_range. gcc/ * range-op.cc (operator_bitwise_or::op1_range): If LHS is signed positive, so are both operands. gcc/testsuite * g++.dg/cpp23/attr-assume-opt.C (f2b): Alternate flow test.
-rw-r--r--gcc/range-op.cc13
-rw-r--r--gcc/testsuite/g++.dg/cpp23/attr-assume-opt.C37
2 files changed, 49 insertions, 1 deletions
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 58734cd..5a1eb59 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -3822,6 +3822,19 @@ operator_bitwise_or::op1_range (irange &r, tree type,
r.set_zero (type);
return true;
}
+
+ // if (A < 0 && B < 0)
+ // Sometimes gets translated to
+ // _1 = A | B
+ // if (_1 < 0))
+ // It is useful for ranger to recognize a positive LHS means the RHS
+ // operands are also positive when dealing with the ELSE range..
+ if (TYPE_SIGN (type) == SIGNED && wi::ge_p (lhs.lower_bound (), 0, SIGNED))
+ {
+ unsigned prec = TYPE_PRECISION (type);
+ r.set (type, wi::zero (prec), wi::max_value (prec, SIGNED));
+ return true;
+ }
r.set_varying (type);
return true;
}
diff --git a/gcc/testsuite/g++.dg/cpp23/attr-assume-opt.C b/gcc/testsuite/g++.dg/cpp23/attr-assume-opt.C
index 88d5e78..e61ba7a 100644
--- a/gcc/testsuite/g++.dg/cpp23/attr-assume-opt.C
+++ b/gcc/testsuite/g++.dg/cpp23/attr-assume-opt.C
@@ -38,5 +38,40 @@ f3 (int x, int y, int z)
return 1;
}
+// This is the same as f2, except there is more complicated flow and
+// required a range-op update to bitwise or.
+
+void barn(int x);
+// assume (x+12 == 14 && y >= 0 && y + 10 < 13 && z + 4 >= 4 && z - 2 < 18)
+// in different order and form with function calls to cause branches.
+bool assume_func (int x, int y, int z)
+{
+ if (z - 2 >= 18)
+ return false;
+ if (x+12 != 14)
+ return false;
+ barn (x);
+ if (y < 0)
+ return false;
+ if (z + 4 < 4)
+ return false;
+ barn (y);
+ if (y + 10 >= 13)
+ return false;
+ barn (z);
+ return true;
+}
+
+int
+f2b (int x, int y, int z)
+{
+ [[assume (assume_func (x, y, z))]];
+ unsigned q = x + y + z;
+ if (q*2 > 46)
+ return 0;
+ return 1;
+}
+
+
/* { dg-final { scan-tree-dump-times "return 0" 0 "vrp2" } } */
-/* { dg-final { scan-tree-dump-times "return 1" 3 "vrp2" } } */
+/* { dg-final { scan-tree-dump-times "return 1" 4 "vrp2" } } */