[llvm] [InstCombine] Combine ptrauth intrin. callee into same-key bundle. (PR #94707)
Ahmed Bougacha via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 15 11:48:32 PDT 2025
================
@@ -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.
----------------
ahmedbougacha wrote:
I'd argue unauthenticated calls are better because they can be scanned for trivially, flagged for audit, rejected, etc.; silent raw signs are more insidious.
It's true we're not supposed to have these, but if nothing else, compilers do learn new IRGen every once in a while (maybe less often for c/c++ than other frontends), which can end up with this.
https://github.com/llvm/llvm-project/pull/94707
More information about the llvm-commits
mailing list