[llvm] r216441 - InstSimplify: Fold gep X, (sub 0, ptrtoint(X)) to null

David Majnemer david.majnemer at gmail.com
Tue Aug 26 00:08:04 PDT 2014


Author: majnemer
Date: Tue Aug 26 02:08:03 2014
New Revision: 216441

URL: http://llvm.org/viewvc/llvm-project?rev=216441&view=rev
Log:
InstSimplify: Fold gep X, (sub 0, ptrtoint(X)) to null

Save InstCombine some work if we can perform this fold during
InstSimplify.

Modified:
    llvm/trunk/lib/Analysis/InstructionSimplify.cpp
    llvm/trunk/test/Transforms/InstSimplify/gep.ll

Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=216441&r1=216440&r2=216441&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Tue Aug 26 02:08:03 2014
@@ -2789,14 +2789,14 @@ static Value *SimplifyGEPInst(ArrayRef<V
   if (Ops.size() == 1)
     return Ops[0];
 
-  if (isa<UndefValue>(Ops[0])) {
-    // Compute the (pointer) type returned by the GEP instruction.
-    Type *LastType = GetElementPtrInst::getIndexedType(PtrTy, Ops.slice(1));
-    Type *GEPTy = PointerType::get(LastType, AS);
-    if (VectorType *VT = dyn_cast<VectorType>(Ops[0]->getType()))
-      GEPTy = VectorType::get(GEPTy, VT->getNumElements());
+  // Compute the (pointer) type returned by the GEP instruction.
+  Type *LastType = GetElementPtrInst::getIndexedType(PtrTy, Ops.slice(1));
+  Type *GEPTy = PointerType::get(LastType, AS);
+  if (VectorType *VT = dyn_cast<VectorType>(Ops[0]->getType()))
+    GEPTy = VectorType::get(GEPTy, VT->getNumElements());
+
+  if (isa<UndefValue>(Ops[0]))
     return UndefValue::get(GEPTy);
-  }
 
   if (Ops.size() == 2) {
     // getelementptr P, 0 -> P.
@@ -2816,26 +2816,37 @@ static Value *SimplifyGEPInst(ArrayRef<V
       // doesn't truncate the pointers.
       if (Ops[1]->getType()->getScalarSizeInBits() ==
           Q.DL->getPointerSizeInBits(AS)) {
-        // getelementptr P, (sub Q, P) -> Q if P points to a type of size 1.
+        auto PtrToIntOrZero = [GEPTy](Value *P) -> Value * {
+          if (match(P, m_Zero()))
+            return Constant::getNullValue(GEPTy);
+          Value *Temp;
+          if (match(P, m_PtrToInt(m_Value(Temp))))
+            return Temp;
+          return nullptr;
+        };
+
+        // getelementptr V, (sub P, V) -> P if P points to a type of size 1.
         if (TyAllocSize == 1 &&
-            match(Ops[1], m_Sub(m_PtrToInt(m_Value(P)),
-                                m_PtrToInt(m_Specific(Ops[0])))))
-          return P;
+            match(Ops[1], m_Sub(m_Value(P), m_PtrToInt(m_Specific(Ops[0])))))
+          if (Value *R = PtrToIntOrZero(P))
+            return R;
 
-        // getelementptr P, (ashr (sub Q, P), C) -> Q
+        // getelementptr V, (ashr (sub P, V), C) -> Q
         // if P points to a type of size 1 << C.
-        if (match(Ops[1], m_AShr(m_Sub(m_PtrToInt(m_Value(P)),
-                                       m_PtrToInt(m_Specific(Ops[0]))),
-                                 m_ConstantInt(C))) &&
+        if (match(Ops[1],
+                  m_AShr(m_Sub(m_Value(P), m_PtrToInt(m_Specific(Ops[0]))),
+                         m_ConstantInt(C))) &&
             TyAllocSize == 1ULL << C)
-          return P;
+          if (Value *R = PtrToIntOrZero(P))
+            return R;
 
-        // getelementptr P, (sdiv (sub Q, P), C) -> Q
+        // getelementptr V, (sdiv (sub P, V), C) -> Q
         // if P points to a type of size C.
-        if (match(Ops[1], m_SDiv(m_Sub(m_PtrToInt(m_Value(P)),
-                                       m_PtrToInt(m_Specific(Ops[0]))),
-                                 m_SpecificInt(TyAllocSize))))
-          return P;
+        if (match(Ops[1],
+                  m_SDiv(m_Sub(m_Value(P), m_PtrToInt(m_Specific(Ops[0]))),
+                         m_SpecificInt(TyAllocSize))))
+          if (Value *R = PtrToIntOrZero(P))
+            return R;
       }
     }
   }

Modified: llvm/trunk/test/Transforms/InstSimplify/gep.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/gep.ll?rev=216441&r1=216440&r2=216441&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/gep.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/gep.ll Tue Aug 26 02:08:03 2014
@@ -35,3 +35,32 @@ define i64* @test3(i64* %b, i64* %e) {
 ; CHECK-LABEL: @test3
 ; CHECK-NEXT: ret i64* %e
 }
+
+define %struct.A* @test4(%struct.A* %b) {
+  %b_ptr = ptrtoint %struct.A* %b to i64
+  %sub = sub i64 0, %b_ptr
+  %sdiv = sdiv exact i64 %sub, 7
+  %gep = getelementptr inbounds %struct.A* %b, i64 %sdiv
+  ret %struct.A* %gep
+; CHECK-LABEL: @test4
+; CHECK-NEXT: ret %struct.A* null
+}
+
+define i8* @test5(i8* %b) {
+  %b_ptr = ptrtoint i8* %b to i64
+  %sub = sub i64 0, %b_ptr
+  %gep = getelementptr inbounds i8* %b, i64 %sub
+  ret i8* %gep
+; CHECK-LABEL: @test5
+; CHECK-NEXT: ret i8* null
+}
+
+define i64* @test6(i64* %b) {
+  %b_ptr = ptrtoint i64* %b to i64
+  %sub = sub i64 0, %b_ptr
+  %ashr = ashr exact i64 %sub, 3
+  %gep = getelementptr inbounds i64* %b, i64 %ashr
+  ret i64* %gep
+; CHECK-LABEL: @test6
+; CHECK-NEXT: ret i64* null
+}





More information about the llvm-commits mailing list