OSDN Git Service

Optimize pointer comparison into the typesafe form, now that the backends will
authorNick Lewycky <nicholas@mxc.ca>
Sat, 2 Jan 2010 15:25:44 +0000 (15:25 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Sat, 2 Jan 2010 15:25:44 +0000 (15:25 +0000)
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

lib/Transforms/Scalar/InstructionCombining.cpp
test/Transforms/InstCombine/or.ll

index 6cda71b..e208d69 100644 (file)
@@ -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));
index 5055215..33058b5 100644 (file)
@@ -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