[llvm-commits] [llvm] r94986 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineCalls.cpp test/Transforms/InstCombine/call.ll

Chris Lattner sabre at nondot.org
Mon Feb 1 10:11:34 PST 2010


Author: lattner
Date: Mon Feb  1 12:11:34 2010
New Revision: 94986

URL: http://llvm.org/viewvc/llvm-project?rev=94986&view=rev
Log:
fix rdar://7590304, a miscompilation of objc apps on arm.  The caller
of objc message send was getting marked arm_apcscc, but the prototype
isn't.  This is fine at runtime because objcmsgsend is implemented in
assembly.  Only turn a mismatched caller and callee into 'unreachable'
if the callee is a definition.

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
    llvm/trunk/test/Transforms/InstCombine/call.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=94986&r1=94985&r2=94986&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Mon Feb  1 12:11:34 2010
@@ -692,10 +692,14 @@
   Value *Callee = CS.getCalledValue();
 
   if (Function *CalleeF = dyn_cast<Function>(Callee))
-    if (CalleeF->getCallingConv() != CS.getCallingConv()) {
+    // If the call and callee calling conventions don't match, this call must
+    // be unreachable, as the call is undefined.
+    if (CalleeF->getCallingConv() != CS.getCallingConv() &&
+        // Only do this for calls to a function with a body.  A prototype may
+        // not actually end up matching the implementation's calling conv for a
+        // variety of reasons (e.g. it may be written in assembly).
+        !CalleeF->isDeclaration()) {
       Instruction *OldCall = CS.getInstruction();
-      // If the call and callee calling conventions don't match, this call must
-      // be unreachable, as the call is undefined.
       new StoreInst(ConstantInt::getTrue(Callee->getContext()),
                 UndefValue::get(Type::getInt1PtrTy(Callee->getContext())), 
                                   OldCall);

Modified: llvm/trunk/test/Transforms/InstCombine/call.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/call.ll?rev=94986&r1=94985&r2=94986&view=diff

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/call.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/call.ll Mon Feb  1 12:11:34 2010
@@ -75,7 +75,7 @@
 declare i32 @test6a(i32)
 
 define i32 @test6() {
-        %X = call i32 bitcast (i32 (i32)* @test6a to i32 ()*)( )                ; <i32> [#uses=1]
+        %X = call i32 bitcast (i32 (i32)* @test6a to i32 ()*)( )
         ret i32 %X
 ; CHECK: %X1 = call i32 @test6a(i32 0)
 ; CHECK: ret i32 %X1
@@ -96,3 +96,23 @@
 }
 
 
+; rdar://7590304
+declare void @test8a()
+
+define i8* @test8() {
+  invoke arm_apcscc void @test8a()
+          to label %invoke.cont unwind label %try.handler
+
+invoke.cont:                                      ; preds = %entry
+  unreachable
+
+try.handler:                                      ; preds = %entry
+  ret i8* null
+}
+
+; Don't turn this into "unreachable": the callee and caller don't agree in
+; calling conv, but the implementation of test8a may actually end up using the
+; right calling conv.
+; CHECK: @test8() {
+; CHECK-NEXT: invoke arm_apcscc void @test8a()
+





More information about the llvm-commits mailing list