@@ -4051,15 +4051,19 @@ static IntrinsicInst *findInitTrampoline(Value *Callee) {
40514051}
40524052
40534053Instruction *InstCombinerImpl::foldPtrAuthIntrinsicCallee (CallBase &Call) {
4054- Value *Callee = Call.getCalledOperand ();
4055- auto *IPC = dyn_cast<IntToPtrInst>(Callee);
4054+ const Value *Callee = Call.getCalledOperand ();
4055+ const auto *IPC = dyn_cast<IntToPtrInst>(Callee);
40564056 if (!IPC || !IPC->isNoopCast (DL))
40574057 return nullptr ;
40584058
4059- IntrinsicInst *II = dyn_cast<IntrinsicInst>(IPC->getOperand (0 ));
4059+ const auto *II = dyn_cast<IntrinsicInst>(IPC->getOperand (0 ));
40604060 if (!II)
40614061 return nullptr ;
40624062
4063+ Intrinsic::ID IIID = II->getIntrinsicID ();
4064+ if (IIID != Intrinsic::ptrauth_resign && IIID != Intrinsic::ptrauth_sign)
4065+ return nullptr ;
4066+
40634067 // Isolate the ptrauth bundle from the others.
40644068 std::optional<OperandBundleUse> PtrAuthBundleOrNone;
40654069 SmallVector<OperandBundleDef, 2 > NewBundles;
@@ -4071,20 +4075,23 @@ Instruction *InstCombinerImpl::foldPtrAuthIntrinsicCallee(CallBase &Call) {
40714075 NewBundles.emplace_back (Bundle);
40724076 }
40734077
4074- Value *NewCallee = nullptr ;
4075- switch (II->getIntrinsicID ()) {
4076- default :
4078+ if (!PtrAuthBundleOrNone)
40774079 return nullptr ;
40784080
4081+ Value *NewCallee = nullptr ;
4082+ switch (IIID) {
40794083 // call(ptrauth.resign(p)), ["ptrauth"()] -> call p, ["ptrauth"()]
40804084 // assuming the call bundle and the sign operands match.
40814085 case Intrinsic::ptrauth_resign: {
4082- if (!PtrAuthBundleOrNone ||
4083- II->getOperand (3 ) != PtrAuthBundleOrNone->Inputs [0 ] ||
4084- II->getOperand (4 ) != PtrAuthBundleOrNone->Inputs [1 ])
4086+ // Resign result key should match bundle.
4087+ if (II->getOperand (3 ) != PtrAuthBundleOrNone->Inputs [0 ])
4088+ return nullptr ;
4089+ // Resign result discriminator should match bundle.
4090+ if (II->getOperand (4 ) != PtrAuthBundleOrNone->Inputs [1 ])
40854091 return nullptr ;
40864092
4087- // Don't change the key used in the call; we don't know what's valid.
4093+ // Resign input (auth) key should also match: we can't change the key on
4094+ // the new call we're generating, because we don't know what keys are valid.
40884095 if (II->getOperand (1 ) != PtrAuthBundleOrNone->Inputs [0 ])
40894096 return nullptr ;
40904097
@@ -4098,26 +4105,24 @@ Instruction *InstCombinerImpl::foldPtrAuthIntrinsicCallee(CallBase &Call) {
40984105 // assuming the call bundle and the sign operands match.
40994106 // Non-ptrauth indirect calls are undesirable, but so is ptrauth.sign.
41004107 case Intrinsic::ptrauth_sign: {
4101- if (!PtrAuthBundleOrNone ||
4102- II->getOperand (1 ) != PtrAuthBundleOrNone->Inputs [0 ] ||
4103- II->getOperand (2 ) != PtrAuthBundleOrNone->Inputs [1 ])
4108+ // Sign key should match bundle.
4109+ if (II->getOperand (1 ) != PtrAuthBundleOrNone->Inputs [0 ])
4110+ return nullptr ;
4111+ // Sign discriminator should match bundle.
4112+ if (II->getOperand (2 ) != PtrAuthBundleOrNone->Inputs [1 ])
41044113 return nullptr ;
41054114 NewCallee = II->getOperand (0 );
41064115 break ;
41074116 }
4117+ default :
4118+ llvm_unreachable (" unexpected intrinsic ID" );
41084119 }
41094120
41104121 if (!NewCallee)
41114122 return nullptr ;
41124123
41134124 NewCallee = Builder.CreateBitOrPointerCast (NewCallee, Callee->getType ());
4114- CallBase *NewCall = nullptr ;
4115- if (auto *CI = dyn_cast<CallInst>(&Call)) {
4116- NewCall = CallInst::Create (CI, NewBundles);
4117- } else {
4118- auto *IKI = cast<InvokeInst>(&Call);
4119- NewCall = InvokeInst::Create (IKI, NewBundles);
4120- }
4125+ CallBase *NewCall = CallBase::Create (&Call, NewBundles);
41214126 NewCall->setCalledOperand (NewCallee);
41224127 return NewCall;
41234128}
0 commit comments