[llvm] 8398e61 - [AutoUpgrade] Also upgrade intrinsics in invokes
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 8 07:00:00 PST 2022
Author: Nikita Popov
Date: 2022-02-08T15:59:52+01:00
New Revision: 8398e61f93ee65700bed6395cd2a9704edad4afe
URL: https://github.com/llvm/llvm-project/commit/8398e61f93ee65700bed6395cd2a9704edad4afe
DIFF: https://github.com/llvm/llvm-project/commit/8398e61f93ee65700bed6395cd2a9704edad4afe.diff
LOG: [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.
Added:
llvm/test/Assembler/invoke-intrinsic-upgrade.ll
Modified:
llvm/include/llvm/IR/AutoUpgrade.h
llvm/lib/IR/AutoUpgrade.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/AutoUpgrade.h b/llvm/include/llvm/IR/AutoUpgrade.h
index f331fc3c413fd..b0db790da99d1 100644
--- a/llvm/include/llvm/IR/AutoUpgrade.h
+++ b/llvm/include/llvm/IR/AutoUpgrade.h
@@ -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
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index c82a79c3bddca..8102e176407eb 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -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();
diff --git a/llvm/test/Assembler/invoke-intrinsic-upgrade.ll b/llvm/test/Assembler/invoke-intrinsic-upgrade.ll
new file mode 100644
index 0000000000000..eb24dfd238ee1
--- /dev/null
+++ b/llvm/test/Assembler/invoke-intrinsic-upgrade.ll
@@ -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, ...)
More information about the llvm-commits
mailing list