calling a function with the wrong CC is undefined, turn it into an unreachable
authorChris Lattner <sabre@nondot.org>
Fri, 13 May 2005 07:09:09 +0000 (07:09 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 13 May 2005 07:09:09 +0000 (07:09 +0000)
instruction.  This is useful for catching optimizers that don't preserve
calling conventions

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

lib/Transforms/Scalar/InstructionCombining.cpp

index 27b87425adc1f313c6e81bcea3b914a50bad62f6..2077b329160e17be14509902ec940a48e15d94fd 100644 (file)
@@ -4115,6 +4115,20 @@ Instruction *InstCombiner::visitCallSite(CallSite CS) {
 
   Value *Callee = CS.getCalledValue();
 
+  if (Function *CalleeF = dyn_cast<Function>(Callee))
+    if (CalleeF->getCallingConv() != CS.getCallingConv()) {
+      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(ConstantBool::True,
+                    UndefValue::get(PointerType::get(Type::BoolTy)), OldCall);
+      if (!OldCall->use_empty())
+        OldCall->replaceAllUsesWith(UndefValue::get(OldCall->getType()));
+      if (isa<CallInst>(OldCall))   // Not worth removing an invoke here.
+        return EraseInstFromFunction(*OldCall);
+      return 0;
+    }
+
   if (isa<ConstantPointerNull>(Callee) || isa<UndefValue>(Callee)) {
     // This instruction is not reachable, just remove it.  We insert a store to
     // undef so that we know that this code is not reachable, despite the fact