fix PR8807 by making transformConstExprCastCall aware of byval arguments.
authorChris Lattner <sabre@nondot.org>
Mon, 20 Dec 2010 08:36:38 +0000 (08:36 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 20 Dec 2010 08:36:38 +0000 (08:36 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122238 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineCalls.cpp
test/Transforms/InstCombine/crash.ll

index 57510ddca13dbb10310dc59686dd63145c4bf44f..f872a9b5aefd91c6f8e2a4648912cef21125e3f1 100644 (file)
@@ -1015,9 +1015,22 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
     if (!CastInst::isCastable(ActTy, ParamTy))
       return false;   // Cannot transform this parameter value.
 
-    if (CallerPAL.getParamAttributes(i + 1) 
-        & Attribute::typeIncompatible(ParamTy))
+    unsigned Attrs = CallerPAL.getParamAttributes(i + 1);
+    if (Attrs & Attribute::typeIncompatible(ParamTy))
       return false;   // Attribute not compatible with transformed value.
+    
+    // If the parameter is passed as a byval argument, then we have to have a
+    // sized type and the sized type has to have the same size as the old type.
+    if (ParamTy != ActTy && (Attrs & Attribute::ByVal)) {
+      const PointerType *ParamPTy = dyn_cast<PointerType>(ParamTy);
+      if (ParamPTy == 0 || !ParamPTy->getElementType()->isSized() || TD == 0)
+        return false;
+      
+      const Type *CurElTy = cast<PointerType>(ActTy)->getElementType();
+      if (TD->getTypeAllocSize(CurElTy) !=
+          TD->getTypeAllocSize(ParamPTy->getElementType()))
+        return false;
+    }
 
     // Converting from one pointer type to another or between a pointer and an
     // integer of the same size is safe even if we do not have a body.
index a600af0da7faabe673a5d2db4e6c4fdf6875aec4..deb7277c5e5bcb3542efcba23ab2fef373829ec1 100644 (file)
@@ -285,3 +285,16 @@ entry:
   store i32 %19, i32* undef, align 8
   unreachable
 }
+
+
+; PR8807
+declare i32 @test14f(i8* (i8*)*) nounwind
+
+define void @test14() nounwind readnone {
+entry:
+  %tmp = bitcast i32 (i8* (i8*)*)* @test14f to i32 (i32*)*
+  %call10 = call i32 %tmp(i32* byval undef)
+  ret void
+}
+
+