aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2010-01-02 15:25:44 +0000
committerNick Lewycky <nicholas@mxc.ca>2010-01-02 15:25:44 +0000
commit546d63176eecb2786f9fcd587ccb2c1ef604278b (patch)
tree618708edf4e18d220b37d805ce6ed6b8aa5dee07
parentbef37376be2880690445a41e5b2d73c084bd3957 (diff)
Optimize pointer comparison into the typesafe form, now that the backends will
handle them efficiently. This is the opposite direction of the transformation we used to have here. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@92418 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp22
-rw-r--r--test/Transforms/InstCombine/or.ll13
2 files changed, 33 insertions, 2 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 6cda71b8a3..e208d69f7c 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -4432,8 +4432,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
// See if we can simplify any instructions used by the instruction whose sole
// purpose is to compute bits we don't care about.
if (SimplifyDemandedInstructionBits(I))
- return &I;
-
+ return &I;
if (ConstantInt *AndRHS = dyn_cast<ConstantInt>(Op1)) {
const APInt &AndRHSMask = AndRHS->getValue();
@@ -7312,6 +7311,25 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
}
}
break;
+
+ case Instruction::Or: {
+ if (!ICI.isEquality() || !RHS->isNullValue() || !LHSI->hasOneUse())
+ break;
+ Value *P, *Q;
+ if (match(LHSI, m_Or(m_PtrToInt(m_Value(P)), m_PtrToInt(m_Value(Q))))) {
+ // Simplify icmp eq (or (ptrtoint P), (ptrtoint Q)), 0
+ // -> and (icmp eq P, null), (icmp eq Q, null).
+
+ Value *ICIP = Builder->CreateICmp(ICI.getPredicate(), P,
+ Constant::getNullValue(P->getType()));
+ Value *ICIQ = Builder->CreateICmp(ICI.getPredicate(), Q,
+ Constant::getNullValue(Q->getType()));
+ Instruction *And = BinaryOperator::CreateAnd(ICIP, ICIQ, "");
+ And->takeName(&ICI);
+ return And;
+ }
+ break;
+ }
case Instruction::Shl: { // (icmp pred (shl X, ShAmt), CI)
ConstantInt *ShAmt = dyn_cast<ConstantInt>(LHSI->getOperand(1));
diff --git a/test/Transforms/InstCombine/or.ll b/test/Transforms/InstCombine/or.ll
index 50552158c9..33058b5334 100644
--- a/test/Transforms/InstCombine/or.ll
+++ b/test/Transforms/InstCombine/or.ll
@@ -268,6 +268,19 @@ define i1 @test26(i32 %A, i32 %B) {
; CHECK: ret i1
}
+define i1 @test27(i32* %A, i32* %B) {
+ %C1 = ptrtoint i32* %A to i32
+ %C2 = ptrtoint i32* %B to i32
+ %D = or i32 %C1, %C2
+ %E = icmp eq i32 %D, 0
+ ret i1 %E
+; CHECK: @test27
+; CHECK: icmp eq i32* %A, null
+; CHECK: icmp eq i32* %B, null
+; CHECK: and i1
+; CHECK: ret i1
+}
+
; PR5634
define i1 @test28(i32 %A, i32 %B) {
%C1 = icmp ne i32 %A, 0