[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