diff options
author | Chris Lattner <sabre@nondot.org> | 2005-05-13 07:09:09 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-05-13 07:09:09 +0000 |
commit | 08b22ecc8870b3657d94ebf7d1f91d9fd5d47744 (patch) | |
tree | d8c1f84451c40a8799022b2f547c723cb6c8b69e /lib/Transforms | |
parent | 712ad0c36dcfacb30620c793a6ffe4e80bd5d569 (diff) |
calling a function with the wrong CC is undefined, turn it into an unreachable
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
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 27b87425ad..2077b32916 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -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 |