forked from OSchip/llvm-project
[AutoUpgrade] Also upgrade intrinsics in invokes
We currently don't have any specialized upgrades for intrinsics that can be used in invokes, but they can still be subject to a generic remangling upgrade. In particular, this happens when upgrading statepoint intrinsics under -opaque-pointers. This patch just changes the upgrade code to work on CallBase instead of CallInst in particular.
This commit is contained in:
parent
f8ffac5987
commit
8398e61f93
|
@ -17,7 +17,7 @@
|
|||
|
||||
namespace llvm {
|
||||
class AttrBuilder;
|
||||
class CallInst;
|
||||
class CallBase;
|
||||
class Constant;
|
||||
class Function;
|
||||
class Instruction;
|
||||
|
@ -35,7 +35,7 @@ namespace llvm {
|
|||
|
||||
/// This is the complement to the above, replacing a specific call to an
|
||||
/// intrinsic function with a call to the specified new function.
|
||||
void UpgradeIntrinsicCall(CallInst *CI, Function *NewFn);
|
||||
void UpgradeIntrinsicCall(CallBase *CB, Function *NewFn);
|
||||
|
||||
// This upgrades the comment for objc retain release markers in inline asm
|
||||
// calls
|
||||
|
|
|
@ -1238,7 +1238,7 @@ static Value *UpgradeX86ALIGNIntrinsics(IRBuilder<> &Builder, Value *Op0,
|
|||
return EmitX86Select(Builder, Mask, Align, Passthru);
|
||||
}
|
||||
|
||||
static Value *UpgradeX86VPERMT2Intrinsics(IRBuilder<> &Builder, CallInst &CI,
|
||||
static Value *UpgradeX86VPERMT2Intrinsics(IRBuilder<> &Builder, CallBase &CI,
|
||||
bool ZeroMask, bool IndexForm) {
|
||||
Type *Ty = CI.getType();
|
||||
unsigned VecWidth = Ty->getPrimitiveSizeInBits();
|
||||
|
@ -1299,7 +1299,7 @@ static Value *UpgradeX86VPERMT2Intrinsics(IRBuilder<> &Builder, CallInst &CI,
|
|||
return EmitX86Select(Builder, CI.getArgOperand(3), V, PassThru);
|
||||
}
|
||||
|
||||
static Value *UpgradeX86BinaryIntrinsics(IRBuilder<> &Builder, CallInst &CI,
|
||||
static Value *UpgradeX86BinaryIntrinsics(IRBuilder<> &Builder, CallBase &CI,
|
||||
Intrinsic::ID IID) {
|
||||
Type *Ty = CI.getType();
|
||||
Value *Op0 = CI.getOperand(0);
|
||||
|
@ -1315,7 +1315,7 @@ static Value *UpgradeX86BinaryIntrinsics(IRBuilder<> &Builder, CallInst &CI,
|
|||
return Res;
|
||||
}
|
||||
|
||||
static Value *upgradeX86Rotate(IRBuilder<> &Builder, CallInst &CI,
|
||||
static Value *upgradeX86Rotate(IRBuilder<> &Builder, CallBase &CI,
|
||||
bool IsRotateRight) {
|
||||
Type *Ty = CI.getType();
|
||||
Value *Src = CI.getArgOperand(0);
|
||||
|
@ -1342,7 +1342,7 @@ static Value *upgradeX86Rotate(IRBuilder<> &Builder, CallInst &CI,
|
|||
return Res;
|
||||
}
|
||||
|
||||
static Value *upgradeX86vpcom(IRBuilder<> &Builder, CallInst &CI, unsigned Imm,
|
||||
static Value *upgradeX86vpcom(IRBuilder<> &Builder, CallBase &CI, unsigned Imm,
|
||||
bool IsSigned) {
|
||||
Type *Ty = CI.getType();
|
||||
Value *LHS = CI.getArgOperand(0);
|
||||
|
@ -1381,7 +1381,7 @@ static Value *upgradeX86vpcom(IRBuilder<> &Builder, CallInst &CI, unsigned Imm,
|
|||
return Ext;
|
||||
}
|
||||
|
||||
static Value *upgradeX86ConcatShift(IRBuilder<> &Builder, CallInst &CI,
|
||||
static Value *upgradeX86ConcatShift(IRBuilder<> &Builder, CallBase &CI,
|
||||
bool IsShiftRight, bool ZeroMask) {
|
||||
Type *Ty = CI.getType();
|
||||
Value *Op0 = CI.getArgOperand(0);
|
||||
|
@ -1460,7 +1460,7 @@ static Value *UpgradeMaskedLoad(IRBuilder<> &Builder,
|
|||
return Builder.CreateMaskedLoad(ValTy, Ptr, Alignment, Mask, Passthru);
|
||||
}
|
||||
|
||||
static Value *upgradeAbs(IRBuilder<> &Builder, CallInst &CI) {
|
||||
static Value *upgradeAbs(IRBuilder<> &Builder, CallBase &CI) {
|
||||
Type *Ty = CI.getType();
|
||||
Value *Op0 = CI.getArgOperand(0);
|
||||
Function *F = Intrinsic::getDeclaration(CI.getModule(), Intrinsic::abs, Ty);
|
||||
|
@ -1470,7 +1470,7 @@ static Value *upgradeAbs(IRBuilder<> &Builder, CallInst &CI) {
|
|||
return Res;
|
||||
}
|
||||
|
||||
static Value *upgradePMULDQ(IRBuilder<> &Builder, CallInst &CI, bool IsSigned) {
|
||||
static Value *upgradePMULDQ(IRBuilder<> &Builder, CallBase &CI, bool IsSigned) {
|
||||
Type *Ty = CI.getType();
|
||||
|
||||
// Arguments have a vXi32 type so cast to vXi64.
|
||||
|
@ -1522,7 +1522,7 @@ static Value *ApplyX86MaskOn1BitsVec(IRBuilder<> &Builder, Value *Vec,
|
|||
return Builder.CreateBitCast(Vec, Builder.getIntNTy(std::max(NumElts, 8U)));
|
||||
}
|
||||
|
||||
static Value *upgradeMaskedCompare(IRBuilder<> &Builder, CallInst &CI,
|
||||
static Value *upgradeMaskedCompare(IRBuilder<> &Builder, CallBase &CI,
|
||||
unsigned CC, bool Signed) {
|
||||
Value *Op0 = CI.getArgOperand(0);
|
||||
unsigned NumElts = cast<FixedVectorType>(Op0->getType())->getNumElements();
|
||||
|
@ -1554,7 +1554,7 @@ static Value *upgradeMaskedCompare(IRBuilder<> &Builder, CallInst &CI,
|
|||
}
|
||||
|
||||
// Replace a masked intrinsic with an older unmasked intrinsic.
|
||||
static Value *UpgradeX86MaskedShift(IRBuilder<> &Builder, CallInst &CI,
|
||||
static Value *UpgradeX86MaskedShift(IRBuilder<> &Builder, CallBase &CI,
|
||||
Intrinsic::ID IID) {
|
||||
Function *Intrin = Intrinsic::getDeclaration(CI.getModule(), IID);
|
||||
Value *Rep = Builder.CreateCall(Intrin,
|
||||
|
@ -1562,7 +1562,7 @@ static Value *UpgradeX86MaskedShift(IRBuilder<> &Builder, CallInst &CI,
|
|||
return EmitX86Select(Builder, CI.getArgOperand(3), Rep, CI.getArgOperand(2));
|
||||
}
|
||||
|
||||
static Value* upgradeMaskedMove(IRBuilder<> &Builder, CallInst &CI) {
|
||||
static Value* upgradeMaskedMove(IRBuilder<> &Builder, CallBase &CI) {
|
||||
Value* A = CI.getArgOperand(0);
|
||||
Value* B = CI.getArgOperand(1);
|
||||
Value* Src = CI.getArgOperand(2);
|
||||
|
@ -1577,7 +1577,7 @@ static Value* upgradeMaskedMove(IRBuilder<> &Builder, CallInst &CI) {
|
|||
}
|
||||
|
||||
|
||||
static Value* UpgradeMaskToInt(IRBuilder<> &Builder, CallInst &CI) {
|
||||
static Value* UpgradeMaskToInt(IRBuilder<> &Builder, CallBase &CI) {
|
||||
Value* Op = CI.getArgOperand(0);
|
||||
Type* ReturnOp = CI.getType();
|
||||
unsigned NumElts = cast<FixedVectorType>(CI.getType())->getNumElements();
|
||||
|
@ -1587,7 +1587,7 @@ static Value* UpgradeMaskToInt(IRBuilder<> &Builder, CallInst &CI) {
|
|||
|
||||
// Replace intrinsic with unmasked version and a select.
|
||||
static bool upgradeAVX512MaskToSelect(StringRef Name, IRBuilder<> &Builder,
|
||||
CallInst &CI, Value *&Rep) {
|
||||
CallBase &CI, Value *&Rep) {
|
||||
Name = Name.substr(12); // Remove avx512.mask.
|
||||
|
||||
unsigned VecWidth = CI.getType()->getPrimitiveSizeInBits();
|
||||
|
@ -1835,7 +1835,7 @@ void llvm::UpgradeInlineAsmString(std::string *AsmStr) {
|
|||
}
|
||||
}
|
||||
|
||||
static Value *UpgradeARMIntrinsicCall(StringRef Name, CallInst *CI, Function *F,
|
||||
static Value *UpgradeARMIntrinsicCall(StringRef Name, CallBase *CI, Function *F,
|
||||
IRBuilder<> &Builder) {
|
||||
if (Name == "mve.vctp64.old") {
|
||||
// Replace the old v4i1 vctp64 with a v2i1 vctp and predicate-casts to the
|
||||
|
@ -1922,12 +1922,12 @@ static Value *UpgradeARMIntrinsicCall(StringRef Name, CallInst *CI, Function *F,
|
|||
Function *Fn = Intrinsic::getDeclaration(F->getParent(), ID, Tys);
|
||||
return Builder.CreateCall(Fn, Ops, CI->getName());
|
||||
}
|
||||
llvm_unreachable("Unknown function for ARM CallInst upgrade.");
|
||||
llvm_unreachable("Unknown function for ARM CallBase upgrade.");
|
||||
}
|
||||
|
||||
/// Upgrade a call to an old intrinsic. All argument and return casting must be
|
||||
/// provided to seamlessly integrate with existing context.
|
||||
void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
|
||||
void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) {
|
||||
Function *F = CI->getCalledFunction();
|
||||
LLVMContext &C = CI->getContext();
|
||||
IRBuilder<> Builder(C);
|
||||
|
@ -3775,7 +3775,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
|
|||
} else if (IsARM) {
|
||||
Rep = UpgradeARMIntrinsicCall(Name, CI, F, Builder);
|
||||
} else {
|
||||
llvm_unreachable("Unknown function for CallInst upgrade.");
|
||||
llvm_unreachable("Unknown function for CallBase upgrade.");
|
||||
}
|
||||
|
||||
if (Rep)
|
||||
|
@ -3788,7 +3788,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {
|
|||
// 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");
|
||||
"Unknown function for CallBase upgrade and isn't just a name change");
|
||||
CI->setCalledFunction(NewFn);
|
||||
};
|
||||
CallInst *NewCall = nullptr;
|
||||
|
@ -4075,8 +4075,8 @@ void llvm::UpgradeCallsToIntrinsic(Function *F) {
|
|||
// Replace all users of the old function with the new function or new
|
||||
// instructions. This is not a range loop because the call is deleted.
|
||||
for (User *U : make_early_inc_range(F->users()))
|
||||
if (CallInst *CI = dyn_cast<CallInst>(U))
|
||||
UpgradeIntrinsicCall(CI, NewFn);
|
||||
if (CallBase *CB = dyn_cast<CallBase>(U))
|
||||
UpgradeIntrinsicCall(CB, NewFn);
|
||||
|
||||
// Remove old function, no longer used, from the module.
|
||||
F->eraseFromParent();
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt -S -opaque-pointers < %s | FileCheck %s
|
||||
|
||||
; Make sure that an intrinsic remangling upgrade works for invokes as well.
|
||||
|
||||
declare i32* @fake_personality_function()
|
||||
declare void @func()
|
||||
|
||||
define void @test_invoke(i32 addrspace(1)* %b) gc "statepoint-example" personality i32* ()* @fake_personality_function {
|
||||
; CHECK-LABEL: @test_invoke(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: [[D:%.*]] = getelementptr i32, ptr addrspace(1) [[B:%.*]], i64 16
|
||||
; CHECK-NEXT: [[SAFEPOINT_TOKEN:%.*]] = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) [ "gc-live"(ptr addrspace(1) [[B]], ptr addrspace(1) [[B]], ptr addrspace(1) [[D]], ptr addrspace(1) [[D]]) ]
|
||||
; CHECK-NEXT: to label [[NORMAL_DEST:%.*]] unwind label [[UNWIND_DEST:%.*]]
|
||||
; CHECK: normal_dest:
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: unwind_dest:
|
||||
; CHECK-NEXT: [[LPAD:%.*]] = landingpad token
|
||||
; CHECK-NEXT: cleanup
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
%d = getelementptr i32, i32 addrspace(1)* %b, i64 16
|
||||
%safepoint_token = invoke token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* elementtype(void ()) @func, i32 0, i32 0, i32 0, i32 0) ["gc-live" (i32 addrspace(1)* %b, i32 addrspace(1)* %b, i32 addrspace(1)* %d, i32 addrspace(1)* %d)]
|
||||
to label %normal_dest unwind label %unwind_dest
|
||||
|
||||
normal_dest:
|
||||
ret void
|
||||
|
||||
unwind_dest:
|
||||
%lpad = landingpad token
|
||||
cleanup
|
||||
ret void
|
||||
}
|
||||
|
||||
declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
|
Loading…
Reference in New Issue