[PATCH] D18841: [InstCombine] Canonicalize icmp instructions based on dominating conditions.

Balaram Makam via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 6 12:53:09 PDT 2016


bmakam created this revision.
bmakam added reviewers: mcrosier, gberry, t.p.northover, llvm-commits.
Herald added a subscriber: mcrosier.

    This patch canonicalizes conditions when the dominating branch condition is a sign bit check.
    For example:

      %cmp = icmp slt i64 %a, 0
      br i1 %cmp, label %land.lhs.true, label %lor.rhs
      lor.rhs:
        %cmp2 = icmp sgt i64 %a, 0

    Would now be canonicalized into:

      %cmp = icmp slt i64 %a, 0
      br i1 %cmp, label %land.lhs.true, label %lor.rhs
      lor.rhs:
        %cmp2 = icmp ne i64 %a, 0

    This will enable more opportunities in codegen to fuse compare and branch on zero/non-zero.

http://reviews.llvm.org/D18841

Files:
  lib/Transforms/InstCombine/InstCombineCompares.cpp
  test/Transforms/InstCombine/icmp.ll

Index: test/Transforms/InstCombine/icmp.ll
===================================================================
--- test/Transforms/InstCombine/icmp.ll
+++ test/Transforms/InstCombine/icmp.ll
@@ -1684,3 +1684,26 @@
   %cmp = icmp uge i32 %addx, %addy
   ret i1 %cmp
 }
+
+; CHECK-LABEL: @idom_sign_bit_check
+define void @idom_sign_bit_check(i64 %a) {
+entry:
+  %cmp = icmp slt i64 %a, 0
+  br i1 %cmp, label %land.lhs.true, label %lor.rhs
+
+land.lhs.true:                                    ; preds = %entry
+  br label %lor.end
+
+; CHECK-LABEL: lor.rhs:
+; CHECK-NOT: icmp sgt i64 %a, 0
+; CHECK: icmp eq i64 %a, 0
+lor.rhs:                                          ; preds = %entry
+  %cmp2 = icmp sgt i64 %a, 0
+  br i1 %cmp2, label %land.rhs, label %lor.end
+
+land.rhs:                                         ; preds = %lor.rhs
+  br label %lor.end
+
+lor.end:                                          ; preds = %land.rhs, %lor.rhs, %land.lhs.true
+  ret void
+}
Index: lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3242,6 +3242,53 @@
                           Builder->getInt(CI->getValue()-1));
     }
 
+
+    // If the immediately dominating branch condition is a sign bit check,
+    // turn it into the appropriate icmp eq/ne Op0 0 instruction.
+    BasicBlock *Parent = I.getParent();
+    DomTreeNode *Node = DT ? DT->getNode(Parent) : nullptr;
+    DomTreeNode *IDomNode = Node ? Node->getIDom() : nullptr;
+    BasicBlock *IDom = IDomNode ? IDomNode->getBlock() : nullptr;
+    auto *BI =
+        IDom ? dyn_cast_or_null<BranchInst>(IDom->getTerminator()) : nullptr;
+    ICmpInst::Predicate Pred;
+    BasicBlock *TrueBB, *FalseBB;
+    ConstantInt *CI2;
+    bool TrueIfSigned = false;
+    if (BI && match(BI, m_Br(m_ICmp(Pred, m_Specific(Op0), m_ConstantInt(CI2)),
+                             TrueBB, FalseBB)) &&
+        isSignBitCheck(Pred, CI2, TrueIfSigned)) {
+      if ((TrueIfSigned && Parent == FalseBB) ||
+          (!TrueIfSigned && Parent == TrueBB)) {
+        if (CI->isZero()) {
+          switch (I.getPredicate()) {
+          default:
+            break;
+          case ICmpInst::ICMP_SGT:
+          case ICmpInst::ICMP_UGT:
+            return new ICmpInst(ICmpInst::ICMP_NE, Op0, CI);
+          case ICmpInst::ICMP_SLE:
+          case ICmpInst::ICMP_ULE:
+            return new ICmpInst(ICmpInst::ICMP_EQ, Op0, CI);
+          }
+        }
+        if (CI->isOne()) {
+          switch (I.getPredicate()) {
+          default:
+            break;
+          case ICmpInst::ICMP_SGE:
+          case ICmpInst::ICMP_UGE:
+            return new ICmpInst(ICmpInst::ICMP_NE, Op0,
+                                Builder->getInt(CI->getValue() - 1));
+          case ICmpInst::ICMP_SLT:
+          case ICmpInst::ICMP_ULT:
+            return new ICmpInst(ICmpInst::ICMP_EQ, Op0,
+                                Builder->getInt(CI->getValue() - 1));
+          }
+        }
+      }
+    }
+
     if (I.isEquality()) {
       ConstantInt *CI2;
       if (match(Op0, m_AShr(m_ConstantInt(CI2), m_Value(A))) ||


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D18841.52839.patch
Type: text/x-patch
Size: 3246 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160406/10ea6a57/attachment.bin>


More information about the llvm-commits mailing list