forked from OSchip/llvm-project
Keep attributes, calling convention, etc, when remangling intrinsic
Summary: Fix issue reported where intrinsic calling convention is dropped after r295253. Reviewers: sanjoy Subscribers: materi, llvm-commits Differential Revision: https://reviews.llvm.org/D30422 llvm-svn: 296563
This commit is contained in:
parent
1bf65c8c0d
commit
3f91004ce7
|
@ -1911,20 +1911,14 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
|
|||
return;
|
||||
}
|
||||
|
||||
std::string Name = CI->getName();
|
||||
if (!Name.empty())
|
||||
CI->setName(Name + ".old");
|
||||
|
||||
CallInst *NewCall = nullptr;
|
||||
switch (NewFn->getIntrinsicID()) {
|
||||
default: {
|
||||
// Handle generic mangling change, but nothing else
|
||||
assert(
|
||||
(CI->getCalledFunction()->getName() != NewFn->getName()) &&
|
||||
"Unknown function for CallInst upgrade and isn't just a name change");
|
||||
SmallVector<Value *, 4> Args(CI->arg_operands().begin(),
|
||||
CI->arg_operands().end());
|
||||
CI->replaceAllUsesWith(Builder.CreateCall(NewFn, Args));
|
||||
CI->eraseFromParent();
|
||||
CI->setCalledFunction(NewFn);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1944,47 +1938,39 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
|
|||
case Intrinsic::arm_neon_vst4lane: {
|
||||
SmallVector<Value *, 4> Args(CI->arg_operands().begin(),
|
||||
CI->arg_operands().end());
|
||||
CI->replaceAllUsesWith(Builder.CreateCall(NewFn, Args));
|
||||
CI->eraseFromParent();
|
||||
return;
|
||||
NewCall = Builder.CreateCall(NewFn, Args);
|
||||
break;
|
||||
}
|
||||
|
||||
case Intrinsic::bitreverse:
|
||||
CI->replaceAllUsesWith(Builder.CreateCall(NewFn, {CI->getArgOperand(0)}));
|
||||
CI->eraseFromParent();
|
||||
return;
|
||||
NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)});
|
||||
break;
|
||||
|
||||
case Intrinsic::ctlz:
|
||||
case Intrinsic::cttz:
|
||||
assert(CI->getNumArgOperands() == 1 &&
|
||||
"Mismatch between function args and call args");
|
||||
CI->replaceAllUsesWith(Builder.CreateCall(
|
||||
NewFn, {CI->getArgOperand(0), Builder.getFalse()}, Name));
|
||||
CI->eraseFromParent();
|
||||
return;
|
||||
NewCall =
|
||||
Builder.CreateCall(NewFn, {CI->getArgOperand(0), Builder.getFalse()});
|
||||
break;
|
||||
|
||||
case Intrinsic::objectsize:
|
||||
CI->replaceAllUsesWith(Builder.CreateCall(
|
||||
NewFn, {CI->getArgOperand(0), CI->getArgOperand(1)}, Name));
|
||||
CI->eraseFromParent();
|
||||
return;
|
||||
NewCall =
|
||||
Builder.CreateCall(NewFn, {CI->getArgOperand(0), CI->getArgOperand(1)});
|
||||
break;
|
||||
|
||||
case Intrinsic::ctpop:
|
||||
CI->replaceAllUsesWith(Builder.CreateCall(NewFn, {CI->getArgOperand(0)}));
|
||||
CI->eraseFromParent();
|
||||
return;
|
||||
NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)});
|
||||
break;
|
||||
|
||||
case Intrinsic::convert_from_fp16:
|
||||
CI->replaceAllUsesWith(Builder.CreateCall(NewFn, {CI->getArgOperand(0)}));
|
||||
CI->eraseFromParent();
|
||||
return;
|
||||
NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0)});
|
||||
break;
|
||||
|
||||
case Intrinsic::x86_xop_vfrcz_ss:
|
||||
case Intrinsic::x86_xop_vfrcz_sd:
|
||||
CI->replaceAllUsesWith(
|
||||
Builder.CreateCall(NewFn, {CI->getArgOperand(1)}, Name));
|
||||
CI->eraseFromParent();
|
||||
return;
|
||||
NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(1)});
|
||||
break;
|
||||
|
||||
case Intrinsic::x86_xop_vpermil2pd:
|
||||
case Intrinsic::x86_xop_vpermil2ps:
|
||||
|
@ -1995,9 +1981,8 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
|
|||
VectorType *FltIdxTy = cast<VectorType>(Args[2]->getType());
|
||||
VectorType *IntIdxTy = VectorType::getInteger(FltIdxTy);
|
||||
Args[2] = Builder.CreateBitCast(Args[2], IntIdxTy);
|
||||
CI->replaceAllUsesWith(Builder.CreateCall(NewFn, Args, Name));
|
||||
CI->eraseFromParent();
|
||||
return;
|
||||
NewCall = Builder.CreateCall(NewFn, Args);
|
||||
break;
|
||||
}
|
||||
|
||||
case Intrinsic::x86_sse41_ptestc:
|
||||
|
@ -2019,10 +2004,8 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
|
|||
Value *BC0 = Builder.CreateBitCast(Arg0, NewVecTy, "cast");
|
||||
Value *BC1 = Builder.CreateBitCast(Arg1, NewVecTy, "cast");
|
||||
|
||||
CallInst *NewCall = Builder.CreateCall(NewFn, {BC0, BC1}, Name);
|
||||
CI->replaceAllUsesWith(NewCall);
|
||||
CI->eraseFromParent();
|
||||
return;
|
||||
NewCall = Builder.CreateCall(NewFn, {BC0, BC1});
|
||||
break;
|
||||
}
|
||||
|
||||
case Intrinsic::x86_sse41_insertps:
|
||||
|
@ -2038,17 +2021,13 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
|
|||
|
||||
// Replace the last argument with a trunc.
|
||||
Args.back() = Builder.CreateTrunc(Args.back(), Type::getInt8Ty(C), "trunc");
|
||||
|
||||
CallInst *NewCall = Builder.CreateCall(NewFn, Args);
|
||||
CI->replaceAllUsesWith(NewCall);
|
||||
CI->eraseFromParent();
|
||||
return;
|
||||
NewCall = Builder.CreateCall(NewFn, Args);
|
||||
break;
|
||||
}
|
||||
|
||||
case Intrinsic::thread_pointer: {
|
||||
CI->replaceAllUsesWith(Builder.CreateCall(NewFn, {}));
|
||||
CI->eraseFromParent();
|
||||
return;
|
||||
NewCall = Builder.CreateCall(NewFn, {});
|
||||
break;
|
||||
}
|
||||
|
||||
case Intrinsic::invariant_start:
|
||||
|
@ -2057,11 +2036,19 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
|
|||
case Intrinsic::masked_store: {
|
||||
SmallVector<Value *, 4> Args(CI->arg_operands().begin(),
|
||||
CI->arg_operands().end());
|
||||
CI->replaceAllUsesWith(Builder.CreateCall(NewFn, Args));
|
||||
CI->eraseFromParent();
|
||||
return;
|
||||
NewCall = Builder.CreateCall(NewFn, Args);
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(NewCall && "Should have either set this variable or returned through "
|
||||
"the default case");
|
||||
std::string Name = CI->getName();
|
||||
if (!Name.empty()) {
|
||||
CI->setName(Name + ".old");
|
||||
NewCall->setName(Name);
|
||||
}
|
||||
CI->replaceAllUsesWith(NewCall);
|
||||
CI->eraseFromParent();
|
||||
}
|
||||
|
||||
void llvm::UpgradeCallsToIntrinsic(Function *F) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
; RUN: opt -verify -S < %s
|
||||
; RUN: opt -S < %s | FileCheck %s
|
||||
|
||||
; Tests the name mangling performed by the codepath following
|
||||
; getMangledTypeStr(). Only tests that code with the various manglings
|
||||
|
@ -67,7 +68,9 @@ entry:
|
|||
|
||||
define %i32* @test_broken_names(%i32* %v) gc "statepoint-example" {
|
||||
entry:
|
||||
%tok = call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.deadbeef(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, %i32* %v)
|
||||
%tok = call fastcc token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.deadbeef(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0, %i32* %v)
|
||||
; Make sure we do not destroy the calling convention when remangling
|
||||
; CHECK: fastcc
|
||||
%v-new = call %i32* @llvm.experimental.gc.relocate.beefdead(token %tok, i32 7, i32 7)
|
||||
ret %i32* %v-new
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue