[llvm] [IR][AArch64] Add "ptrauth(...)" Constant to represent signed pointers. (PR #85738)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 19 04:14:34 PDT 2024
================
@@ -2015,6 +2018,118 @@ Value *NoCFIValue::handleOperandChangeImpl(Value *From, Value *To) {
return nullptr;
}
+//---- ConstantPtrAuth::get() implementations.
+//
+
+static bool areEquivalentAddrDiscriminators(const Value *V1, const Value *V2,
+ const DataLayout &DL) {
+ APInt V1Off(DL.getPointerSizeInBits(), 0);
+ APInt V2Off(DL.getPointerSizeInBits(), 0);
+
+ if (auto *V1Cast = dyn_cast<PtrToIntOperator>(V1))
+ V1 = V1Cast->getPointerOperand();
+ if (auto *V2Cast = dyn_cast<PtrToIntOperator>(V2))
+ V2 = V2Cast->getPointerOperand();
+ auto *V1Base = V1->stripAndAccumulateConstantOffsets(
+ DL, V1Off, /*AllowNonInbounds=*/true);
+ auto *V2Base = V2->stripAndAccumulateConstantOffsets(
+ DL, V2Off, /*AllowNonInbounds=*/true);
+ return V1Base == V2Base && V1Off == V2Off;
+}
+
+bool ConstantPtrAuth::isCompatibleWith(const Value *Key,
+ const Value *Discriminator,
+ const DataLayout &DL) const {
+ // If the keys are different, there's no chance for this to be compatible.
+ if (Key != getKey())
+ return false;
+
+ // If the discriminators are the same, this is compatible iff there is no
+ // address discriminator.
+ if (Discriminator == getDiscriminator())
+ return getAddrDiscriminator()->isNullValue();
+
+ // If we dynamically blend the discriminator with the address discriminator,
+ // this is compatible.
+ if (auto *DiscBlend = dyn_cast<IntrinsicInst>(Discriminator)) {
+ if (DiscBlend->getIntrinsicID() == Intrinsic::ptrauth_blend &&
+ DiscBlend->getOperand(1) == getDiscriminator() &&
+ areEquivalentAddrDiscriminators(DiscBlend->getOperand(0),
+ getAddrDiscriminator(), DL))
+ return true;
+ }
+
+ // If we don't have a non-address discriminator, we don't need a blend in
+ // the first place: accept the address discriminator as the discriminator.
+ if (getDiscriminator()->isNullValue() &&
+ areEquivalentAddrDiscriminators(getAddrDiscriminator(), Discriminator,
+ DL))
+ return true;
+
+ // Otherwise, we don't know.
+ return false;
+}
+
+ConstantPtrAuth *ConstantPtrAuth::getWithSameSchema(Constant *Pointer) const {
+ return get(Pointer, getKey(), getAddrDiscriminator(), getDiscriminator());
+}
+
+ConstantPtrAuth *ConstantPtrAuth::get(Constant *Ptr, ConstantInt *Key,
+ Constant *AddrDisc, ConstantInt *Disc) {
+ Constant *ArgVec[] = {Ptr, Key, AddrDisc, Disc};
+ ConstantPtrAuthKeyType MapKey(ArgVec);
+ LLVMContextImpl *pImpl = Ptr->getContext().pImpl;
+ return pImpl->ConstantPtrAuths.getOrCreate(Ptr->getType(), MapKey);
+}
+
+ConstantPtrAuth::ConstantPtrAuth(Constant *Ptr, ConstantInt *Key,
+ Constant *AddrDisc, ConstantInt *Disc)
+ : Constant(Ptr->getType(), Value::ConstantPtrAuthVal, &Op<0>(), 4) {
+#ifndef NDEBUG
----------------
nikic wrote:
Explicit NDEBUG check unnecessary.
https://github.com/llvm/llvm-project/pull/85738
More information about the llvm-commits
mailing list