[PATCH] D20174: [InstCombine] Allow removal of PHI cycles which only contain PHIs

silviu.baranga@arm.com via llvm-commits llvm-commits at lists.llvm.org
Wed May 11 09:40:38 PDT 2016


sbaranga created this revision.
sbaranga added reviewers: majnemer, jmolloy.
sbaranga added a subscriber: llvm-commits.

This teaches instcombine to be able to remove PHI cycles which
only contain PHIs.

When a PHI doesn't have a non-PHI incoming value, we will now
try to resolve the PHI to each of the incoming values.

http://reviews.llvm.org/D20174

Files:
  lib/Transforms/InstCombine/InstCombinePHI.cpp
  test/Transforms/InstCombine/phi-cycle.ll

Index: lib/Transforms/InstCombine/InstCombinePHI.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -591,10 +591,10 @@
   return false;
 }
 
-/// Return true if this phi node is always equal to NonPhiInVal.
+/// Return true if this phi node is always equal to Val.
 /// This happens with mutually cyclic phi nodes like:
 ///   z = some value; x = phi (y, z); y = phi (x, z)
-static bool PHIsEqualValue(PHINode *PN, Value *NonPhiInVal,
+static bool PHIsEqualValue(PHINode *PN, Value *Val,
                            SmallPtrSetImpl<PHINode*> &ValueEqualPHIs) {
   // See if we already saw this PHI node.
   if (!ValueEqualPHIs.insert(PN).second)
@@ -607,11 +607,14 @@
   // Scan the operands to see if they are either phi nodes or are equal to
   // the value.
   for (Value *Op : PN->incoming_values()) {
-    if (PHINode *OpPN = dyn_cast<PHINode>(Op)) {
-      if (!PHIsEqualValue(OpPN, NonPhiInVal, ValueEqualPHIs))
-        return false;
-    } else if (Op != NonPhiInVal)
-      return false;
+    if (Val == Op)
+      continue;
+
+    if (PHINode *OpPN = dyn_cast<PHINode>(Op))
+      if (PHIsEqualValue(OpPN, Val, ValueEqualPHIs))
+        continue;
+
+    return false;
   }
 
   return true;
@@ -962,6 +965,21 @@
         if (PHIsEqualValue(&PN, NonPhiInVal, ValueEqualPHIs))
           return replaceInstUsesWith(PN, NonPhiInVal);
       }
+    } else {
+      // This is a PHI of PHIs. See if any one of the incoming values
+      // can be proven to be the equal with this PHI.
+      InValNo = 0;
+      while (InValNo != NumIncomingVals) {
+        Value *Val = PN.getIncomingValue(InValNo);
+
+        // Scan to see if we can prove that this is a phi cycle equal to
+        // Val.
+        SmallPtrSet<PHINode*, 16> ValueEqualPHIs;
+        if (PHIsEqualValue(&PN, Val, ValueEqualPHIs))
+          return replaceInstUsesWith(PN, Val);
+
+        ++InValNo;
+      }
     }
   }
 
Index: test/Transforms/InstCombine/phi-cycle.ll
===================================================================
--- /dev/null
+++ test/Transforms/InstCombine/phi-cycle.ll
@@ -0,0 +1,36 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128:n8:16:32:64"
+
+; Check that we can remove a dead phi cycle made up
+; entirely out of PHIs.
+
+; CHECK-LABEL: func1
+define i32 @func1(i1 %c, i1 %c2, i32 %x) {
+entry:
+  br i1 %c, label %if.else, label %pre
+
+if.else:
+  br label %pre
+
+pre:
+  %p0 = phi i32 [ %x, %entry ], [ 1, %if.else ]
+  br label %loop
+
+loop:
+  %p1 = phi i32 [ %p2, %loop-bb1 ], [ %p0, %pre ]
+  br i1 %c2, label %loop-bb1, label %loop-bb2
+
+loop-bb2:
+  br label %loop-bb1
+
+loop-bb1:
+  %p2 = phi i32 [ %p0, %loop ] , [ %p1, %loop-bb2 ]
+  br i1 %c, label %loop, label %exit
+
+exit:
+
+; CHECK: ret i32 %p0
+  ret i32 %p1
+}
+


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D20174.56931.patch
Type: text/x-patch
Size: 3028 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160511/08c586bc/attachment.bin>


More information about the llvm-commits mailing list