@@ -2021,59 +2021,6 @@ Value *NoCFIValue::handleOperandChangeImpl(Value *From, Value *To) {
2021
2021
// ---- ConstantPtrAuth::get() implementations.
2022
2022
//
2023
2023
2024
- static bool areEquivalentAddrDiscriminators (const Value *V1, const Value *V2,
2025
- const DataLayout &DL) {
2026
- APInt Off1 (DL.getTypeSizeInBits (V1->getType ()), 0 );
2027
- APInt Off2 (DL.getTypeSizeInBits (V2->getType ()), 0 );
2028
-
2029
- if (auto *V1Cast = dyn_cast<PtrToIntOperator>(V1))
2030
- V1 = V1Cast->getPointerOperand ();
2031
- if (auto *V2Cast = dyn_cast<PtrToIntOperator>(V2))
2032
- V2 = V2Cast->getPointerOperand ();
2033
- auto *V1Base = V1->stripAndAccumulateConstantOffsets (
2034
- DL, Off1, /* AllowNonInbounds=*/ true );
2035
- auto *V2Base = V2->stripAndAccumulateConstantOffsets (
2036
- DL, Off2, /* AllowNonInbounds=*/ true );
2037
- return V1Base == V2Base && Off1 == Off2;
2038
- }
2039
-
2040
- bool ConstantPtrAuth::isCompatibleWith (const Value *Key,
2041
- const Value *Discriminator,
2042
- const DataLayout &DL) const {
2043
- // If the keys are different, there's no chance for this to be compatible.
2044
- if (Key != getKey ())
2045
- return false ;
2046
-
2047
- // If the discriminators are the same, this is compatible iff there is no
2048
- // address discriminator.
2049
- if (Discriminator == getDiscriminator ())
2050
- return getAddrDiscriminator ()->isNullValue ();
2051
-
2052
- // If we dynamically blend the discriminator with the address discriminator,
2053
- // this is compatible.
2054
- if (auto *DiscBlend = dyn_cast<IntrinsicInst>(Discriminator)) {
2055
- if (DiscBlend->getIntrinsicID () == Intrinsic::ptrauth_blend &&
2056
- DiscBlend->getOperand (1 ) == getDiscriminator () &&
2057
- areEquivalentAddrDiscriminators (DiscBlend->getOperand (0 ),
2058
- getAddrDiscriminator (), DL))
2059
- return true ;
2060
- }
2061
-
2062
- // If we don't have a non-address discriminator, we don't need a blend in
2063
- // the first place: accept the address discriminator as the discriminator.
2064
- if (getDiscriminator ()->isNullValue () &&
2065
- areEquivalentAddrDiscriminators (getAddrDiscriminator (), Discriminator,
2066
- DL))
2067
- return true ;
2068
-
2069
- // Otherwise, we don't know.
2070
- return false ;
2071
- }
2072
-
2073
- ConstantPtrAuth *ConstantPtrAuth::getWithSameSchema (Constant *Pointer) const {
2074
- return get (Pointer, getKey (), getDiscriminator (), getAddrDiscriminator ());
2075
- }
2076
-
2077
2024
ConstantPtrAuth *ConstantPtrAuth::get (Constant *Ptr , ConstantInt *Key,
2078
2025
ConstantInt *Disc, Constant *AddrDisc) {
2079
2026
Constant *ArgVec[] = {Ptr , Key, Disc, AddrDisc};
@@ -2082,6 +2029,10 @@ ConstantPtrAuth *ConstantPtrAuth::get(Constant *Ptr, ConstantInt *Key,
2082
2029
return pImpl->ConstantPtrAuths .getOrCreate (Ptr ->getType (), MapKey);
2083
2030
}
2084
2031
2032
+ ConstantPtrAuth *ConstantPtrAuth::getWithSameSchema (Constant *Pointer) const {
2033
+ return get (Pointer, getKey (), getDiscriminator (), getAddrDiscriminator ());
2034
+ }
2035
+
2085
2036
ConstantPtrAuth::ConstantPtrAuth (Constant *Ptr , ConstantInt *Key,
2086
2037
ConstantInt *Disc, Constant *AddrDisc)
2087
2038
: Constant(Ptr ->getType (), Value::ConstantPtrAuthVal, &Op<0>(), 4) {
@@ -2125,6 +2076,66 @@ Value *ConstantPtrAuth::handleOperandChangeImpl(Value *From, Value *ToV) {
2125
2076
Values, this , From, To, NumUpdated, OperandNo);
2126
2077
}
2127
2078
2079
+ bool ConstantPtrAuth::isKnownCompatibleWith (const Value *Key,
2080
+ const Value *Discriminator,
2081
+ const DataLayout &DL) const {
2082
+ // If the keys are different, there's no chance for this to be compatible.
2083
+ if (getKey () != Key)
2084
+ return false ;
2085
+
2086
+ // We can have 3 kinds of discriminators:
2087
+ // - simple, integer-only: `i64 x, ptr null` vs. `i64 x`
2088
+ // - address-only: `i64 0, ptr p` vs. `ptr p`
2089
+ // - blended address/integer: `i64 x, ptr p` vs. `@llvm.ptrauth.blend(p, x)`
2090
+
2091
+ // If this constant has a simple discriminator (integer, no address), easy:
2092
+ // it's compatible iff the provided full discriminator is also a simple
2093
+ // discriminator, identical to our integer discriminator.
2094
+ if (!hasAddressDiscriminator ())
2095
+ return getDiscriminator () == Discriminator;
2096
+
2097
+ // Otherwise, we can isolate address and integer discriminator components.
2098
+ const Value *AddrDiscriminator = nullptr ;
2099
+
2100
+ // This constant may or may not have an integer discriminator (instead of 0).
2101
+ if (!getDiscriminator ()->isNullValue ()) {
2102
+ // If it does, there's an implicit blend. We need to have a matching blend
2103
+ // intrinsic in the provided full discriminator.
2104
+ if (!match (Discriminator,
2105
+ m_Intrinsic<Intrinsic::ptrauth_blend>(
2106
+ m_Value (AddrDiscriminator), m_Specific (getDiscriminator ()))))
2107
+ return false ;
2108
+ } else {
2109
+ // Otherwise, interpret the provided full discriminator as address-only.
2110
+ AddrDiscriminator = Discriminator;
2111
+ }
2112
+
2113
+ // Either way, we can now focus on comparing the address discriminators.
2114
+
2115
+ // Discriminators are i64, so the provided addr disc may be a ptrtoint.
2116
+ if (auto *Cast = dyn_cast<PtrToIntOperator>(AddrDiscriminator))
2117
+ AddrDiscriminator = Cast->getPointerOperand ();
2118
+
2119
+ // Beyond that, we're only interested in compatible pointers.
2120
+ if (getAddrDiscriminator ()->getType () != AddrDiscriminator->getType ())
2121
+ return false ;
2122
+
2123
+ // These are often the same constant GEP, making them trivially equivalent.
2124
+ if (getAddrDiscriminator () == AddrDiscriminator)
2125
+ return true ;
2126
+
2127
+ // Finally, they may be equivalent base+offset expressions.
2128
+ APInt Off1 (DL.getIndexTypeSizeInBits (getAddrDiscriminator ()->getType ()), 0 );
2129
+ auto *Base1 = getAddrDiscriminator ()->stripAndAccumulateConstantOffsets (
2130
+ DL, Off1, /* AllowNonInbounds=*/ true );
2131
+
2132
+ APInt Off2 (DL.getIndexTypeSizeInBits (AddrDiscriminator->getType ()), 0 );
2133
+ auto *Base2 = AddrDiscriminator->stripAndAccumulateConstantOffsets (
2134
+ DL, Off2, /* AllowNonInbounds=*/ true );
2135
+
2136
+ return Base1 == Base2 && Off1 == Off2;
2137
+ }
2138
+
2128
2139
// ---- ConstantExpr::get() implementations.
2129
2140
//
2130
2141
0 commit comments