[PATCH] D16240: [InstCombine] Simplify a known nonzero incoming value of PHI

Jun Bum Lim via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 19 16:25:14 PST 2016


junbuml updated this revision to Diff 45317.
junbuml marked 2 inline comments as done.
junbuml added a comment.
Herald added a subscriber: mcrosier.

Addressed comments from Sanjoy and David.

> My gut reaction would be to ask why we aren't trying to fold the comparison across the PHI as that would catch this case (and others) quite naturally.


The main purpose of this change is not to fold the cmp, but to replace incoming values to a nonzero constant because for a phi with multiple non constant operands, only some of its operands could be a known nonzero. By replacing some of incoming values with constants, we can expect to make the incoming value dead as well as increase chances to fold users (e.g., the cmp) of the phi.


http://reviews.llvm.org/D16240

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

Index: test/Transforms/InstCombine/phi.ll
===================================================================
--- test/Transforms/InstCombine/phi.ll
+++ test/Transforms/InstCombine/phi.ll
@@ -760,3 +760,27 @@
 ; CHECK-NEXT: ret i1 %[[RES]]
 }
 
+; CHECK-LABEL: @phi_knownnonzero
+; CHECK-LABEL: if.then:
+; CHECK-NOT: select
+; CHECK-LABEL: if.end:
+; CHECK: phi i32 [ 1, %if.then ]
+
+
+define i1 @phi_knownnonzero(i32 %n, i32 %s, i32* nocapture readonly %P) {
+entry:
+  %tobool = icmp slt  i32 %n, %s
+  br i1 %tobool, label %if.end, label %if.then
+
+if.then:                                          ; preds = %entry
+  %0 = load i32, i32* %P
+  %cmp = icmp eq i32 %n, %0
+  %1 = select i1 %cmp, i32 1, i32 2
+  br label %if.end
+
+if.end:                                           ; preds = %entry, %if.then
+  %a.0 = phi i32 [ %1,  %if.then ], [ %n, %entry ]
+  %cmp1 = icmp eq i32 %a.0, 0
+  ret i1  %cmp1
+}
+
Index: lib/Transforms/InstCombine/InstCombinePHI.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -15,6 +15,8 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Analysis/InstructionSimplify.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/PatternMatch.h"
 #include "llvm/Transforms/Utils/Local.h"
 using namespace llvm;
 
@@ -919,6 +921,30 @@
         PHIUser->user_back() == &PN) {
       return ReplaceInstUsesWith(PN, UndefValue::get(PN.getType()));
     }
+
+    // When a PHI is used only to be compared with zero, it is safe to replace
+    // an incoming value proved as known nonzero with any non-zero constant.
+    // For example, in below code, the incoming value %v can be replaced with
+    // any non-zero constant based on the fact that the PHI is only used to be
+    // compared with zero and %v is a known non-zero value:
+    // %v = select %cond, 1, 2
+    // %p = phi [%v, BB] ...
+    //      icmp eq, %p, 0
+    ICmpInst *CmpInst = dyn_cast<ICmpInst>(PHIUser);
+    // FIXME: To be simple, handle only integer type for now.
+    if (CmpInst && isa<IntegerType>(PN.getType()) && CmpInst->isEquality() &&
+        (match(CmpInst->getOperand(1), PatternMatch::m_Zero()) ||
+         match(CmpInst->getOperand(0), PatternMatch::m_Zero()))) {
+      for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
+        BasicBlock *InBB = PN.getIncomingBlock(i);
+        Instruction *CtxI = (InBB && InBB->getTerminator())
+                                ? (Instruction *)InBB->getTerminator()
+                                : (Instruction *)&PN;
+        Value *VA = PN.getIncomingValue(i);
+        if (!isa<ConstantInt>(VA) && isKnownNonZero(VA, DL, 0, AC, CtxI, DT))
+          PN.setIncomingValue(i, ConstantInt::get(PN.getType(), 1));
+      }
+    }
   }
 
   // We sometimes end up with phi cycles that non-obviously end up being the


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D16240.45317.patch
Type: text/x-patch
Size: 2966 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160120/8f56867d/attachment.bin>


More information about the llvm-commits mailing list