[llvm] [InstCombine] Combine ptrauth intrin. callee into same-key bundle. (PR #94707)
Daniil Kovalev via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 17 06:49:28 PDT 2024
================
@@ -3665,6 +3665,78 @@ static IntrinsicInst *findInitTrampoline(Value *Callee) {
return nullptr;
}
+Instruction *InstCombinerImpl::foldPtrAuthIntrinsicCallee(CallBase &Call) {
+ Value *Callee = Call.getCalledOperand();
+ auto *IPC = dyn_cast<IntToPtrInst>(Callee);
+ if (!IPC || !IPC->isNoopCast(DL))
+ return nullptr;
+
+ IntrinsicInst *II = dyn_cast<IntrinsicInst>(IPC->getOperand(0));
+ if (!II)
+ return nullptr;
+
+ // Isolate the ptrauth bundle from the others.
+ std::optional<OperandBundleUse> PtrAuthBundleOrNone;
+ SmallVector<OperandBundleDef, 2> NewBundles;
+ for (unsigned BI = 0, BE = Call.getNumOperandBundles(); BI != BE; ++BI) {
+ OperandBundleUse Bundle = Call.getOperandBundleAt(BI);
+ if (Bundle.getTagID() == LLVMContext::OB_ptrauth)
+ PtrAuthBundleOrNone = Bundle;
+ else
+ NewBundles.emplace_back(Bundle);
+ }
+
+ Value *NewCallee = nullptr;
+ switch (II->getIntrinsicID()) {
+ default:
+ return nullptr;
+
+ // call(ptrauth.resign(p)), ["ptrauth"()] -> call p, ["ptrauth"()]
+ // assuming the call bundle and the sign operands match.
+ case Intrinsic::ptrauth_resign: {
+ if (!PtrAuthBundleOrNone ||
+ II->getOperand(3) != PtrAuthBundleOrNone->Inputs[0] ||
+ II->getOperand(4) != PtrAuthBundleOrNone->Inputs[1])
+ return nullptr;
+
+ // Don't change the key used in the call; we don't know what's valid.
+ if (II->getOperand(1) != PtrAuthBundleOrNone->Inputs[0])
+ return nullptr;
+
+ Value *NewBundleOps[] = {II->getOperand(1), II->getOperand(2)};
+ NewBundles.emplace_back("ptrauth", NewBundleOps);
+ NewCallee = II->getOperand(0);
+ break;
+ }
+
+ // call(ptrauth.sign(p)), ["ptrauth"()] -> call p
+ // assuming the call bundle and the sign operands match.
+ // Non-ptrauth indirect calls are undesirable, but so is ptrauth.sign.
----------------
kovdan01 wrote:
Yes, both of these are bad options - not sure though what is worse, but I'm happy with having unauthenticated indirect calls here if everyone else is happy with this as well.
It's actually interesting, can we have such an IR in "wild nature" when: 1) generating IR from C/C++ code and not manually writing it; 2) not using ptrauth intrinsics in code explicitly? If yes, could you please provide an example of such code?
https://github.com/llvm/llvm-project/pull/94707
More information about the llvm-commits
mailing list