]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Check for equivalences between PHI argument and def.
authorAndrew MacLeod <amacleod@redhat.com>
Tue, 23 Nov 2021 19:12:29 +0000 (14:12 -0500)
committerAndrew MacLeod <amacleod@redhat.com>
Thu, 25 Nov 2021 13:44:27 +0000 (08:44 -0500)
If a PHI argument on an edge is equivalent with the DEF, then it doesn't
provide any new information, defer processing it unless they are all
equivalences.

PR tree-optimization/103359
gcc/
* gimple-range-fold.cc (fold_using_range::range_of_phi): If arg is
equivalent to def, don't initially include it's range.

gcc/testsuite/
* gcc.dg/pr103359.c: New.

gcc/gimple-range-fold.cc
gcc/testsuite/gcc.dg/pr103359.c [new file with mode: 0644]

index ec9690b05e49901d8f3c348cfbb5c2e2eec1ebde..d66ada5bb7c469f3962abf44b5783885942d0866 100644 (file)
@@ -771,6 +771,7 @@ fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src)
   tree phi_def = gimple_phi_result (phi);
   tree type = gimple_range_type (phi);
   int_range_max arg_range;
+  int_range_max equiv_range;
   unsigned x;
 
   if (!type)
@@ -794,6 +795,16 @@ fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src)
       // Get the range of the argument on its edge.
       src.get_phi_operand (arg_range, arg, e);
 
+      // Likewise, if the incoming PHI argument is equivalent to this
+      // PHI definition, it provides no new info.  Accumulate these ranges
+      // in case all arguments are equivalences.
+      if (src.query ()->query_relation (e, arg, phi_def, false) == EQ_EXPR)
+       {
+         single_arg = arg;
+         equiv_range.union_(arg_range);
+         continue;
+       }
+
       if (!arg_range.undefined_p ())
        {
          // Register potential dependencies for stale value tracking.
@@ -816,6 +827,11 @@ fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src)
        break;
     }
 
+    // If all arguments were equivalences, use the equivalence ranges as no
+    // arguments were processed.
+    if (!seen_arg)
+      r = equiv_range;
+
     // If the PHI boils down to a single effective argument, look at it.
     if (single_arg)
       {
diff --git a/gcc/testsuite/gcc.dg/pr103359.c b/gcc/testsuite/gcc.dg/pr103359.c
new file mode 100644 (file)
index 0000000..13406f9
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-evrp" } */
+
+void foo();
+static char a, c;
+static int d, e;
+static short b(short f, short g) { return f * g; }
+int main() {
+  short h = 4;
+  for (; d;)
+    if (h)
+      if(e) {
+        if (!b(a & 1 | h, 3))
+          c = 0;
+        h = 1;
+      }
+  if (c)
+    foo();
+}
+
+/* { dg-final { scan-tree-dump-not "c = 0" "evrp" } } */