InstSimplify: Don't simplify gep X, (Y-X) to Y if types differ
authorDavid Majnemer <david.majnemer@gmail.com>
Wed, 27 Aug 2014 20:08:34 +0000 (20:08 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Wed, 27 Aug 2014 20:08:34 +0000 (20:08 +0000)
It's incorrect to perform this simplification if the types differ.
A bitcast would need to be inserted for this to work.

This fixes PR20771.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216597 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/InstructionSimplify.cpp
test/Transforms/InstSimplify/gep.ll

index 118579d5b72ef18f47ef94bf5cee4caa3261717c..9f3b2876afed95441d9960bf4a441a0e8c5bdcc8 100644 (file)
@@ -2837,7 +2837,8 @@ static Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const Query &Q, unsigned) {
             return Constant::getNullValue(GEPTy);
           Value *Temp;
           if (match(P, m_PtrToInt(m_Value(Temp))))
-            return Temp;
+            if (Temp->getType() == GEPTy)
+              return Temp;
           return nullptr;
         };
 
index d1704bf80bc0eac224addf4e077f7fda5b2f7178..49a97f133cefde1e055cc99d04c1be9ab5c88b27 100644 (file)
@@ -64,3 +64,17 @@ define i64* @test6(i64* %b) {
 ; CHECK-LABEL: @test6
 ; CHECK-NEXT: ret i64* null
 }
+
+define i8* @test7(i8* %b, i8** %e) {
+  %e_ptr = ptrtoint i8** %e to i64
+  %b_ptr = ptrtoint i8* %b to i64
+  %sub = sub i64 %e_ptr, %b_ptr
+  %gep = getelementptr inbounds i8* %b, i64 %sub
+  ret i8* %gep
+; CHECK-LABEL: @test7
+; CHECK-NEXT: ptrtoint
+; CHECK-NEXT: ptrtoint
+; CHECK-NEXT: sub
+; CHECK-NEXT: getelementptr
+; CHECK-NEXT: ret
+}