Ignore shifts larger than precision in operator_rshift::op1_range.
authorAldy Hernandez <aldyh@redhat.com>
Mon, 12 Oct 2020 08:08:28 +0000 (04:08 -0400)
committerAldy Hernandez <aldyh@redhat.com>
Mon, 12 Oct 2020 09:48:10 +0000 (05:48 -0400)
gcc/ChangeLog:

PR tree-optimization/97371
* range-op.cc (operator_rshift::op1_range): Ignore shifts larger than
or equal to type precision.

gcc/testsuite/ChangeLog:

* gcc.dg/pr97371.c: New test.

gcc/range-op.cc
gcc/testsuite/gcc.dg/pr97371.c [new file with mode: 0644]

index d1a11b34894e9410cf43d2744b2d348f219e0576..ce6ae2de20c7ca4611ce90fe1d25dc9de84d4955 100644 (file)
@@ -1626,6 +1626,13 @@ operator_rshift::op1_range (irange &r,
   tree shift;
   if (op2.singleton_p (&shift))
     {
+      // Ignore nonsensical shifts.
+      unsigned prec = TYPE_PRECISION (type);
+      if (wi::ge_p (wi::to_wide (shift),
+                   wi::uhwi (prec, TYPE_PRECISION (TREE_TYPE (shift))),
+                   UNSIGNED))
+       return false;
+
       // Folding the original operation may discard some impossible
       // ranges from the LHS.
       int_range_max lhs_refined;
diff --git a/gcc/testsuite/gcc.dg/pr97371.c b/gcc/testsuite/gcc.dg/pr97371.c
new file mode 100644 (file)
index 0000000..ffefad0
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -w" } */
+
+int a, b;
+void c() {
+  if (b >> 38)
+    a = b;
+}