diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index da72a43643a54..73a8c28fbefc4 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -5622,43 +5622,79 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_ptrauth_sign_constant: return RValue::get(ConstantEmitter(*this).emitAbstract(E, E->getType())); + case Builtin::BI__builtin_ptrauth_blend_discriminator: { + CGM.Error(E->getExprLoc(), "Standalone blend builtin is not supported"); + llvm::Type *Ty = ConvertType(E->getType()); + return RValue::get(llvm::UndefValue::get(Ty)); + } + case Builtin::BI__builtin_ptrauth_auth: case Builtin::BI__builtin_ptrauth_auth_and_resign: - case Builtin::BI__builtin_ptrauth_blend_discriminator: case Builtin::BI__builtin_ptrauth_sign_generic_data: case Builtin::BI__builtin_ptrauth_sign_unauthenticated: case Builtin::BI__builtin_ptrauth_strip: { - // Emit the arguments. - SmallVector Args; - for (auto argExpr : E->arguments()) - Args.push_back(EmitScalarExpr(argExpr)); + SmallVector Args; + SmallVector OBs; + + auto ConvertToInt64 = [&](llvm::Value *V) { + if (V->getType()->isPointerTy()) + return Builder.CreatePtrToInt(V, IntPtrTy); + return Builder.CreateZExt(V, IntPtrTy); + }; + + auto AddPtrAuthBundle = [&](const Expr *KeyExpr, const Expr *DiscrExpr) { + llvm::Value *Key = ConvertToInt64(EmitScalarExpr(KeyExpr)); + llvm::Value *IntDiscr = Builder.getInt64(0); + llvm::Value *AddrDiscr = Builder.getInt64(0); + + const CallExpr *MaybeBlend = dyn_cast(DiscrExpr); + if (MaybeBlend && MaybeBlend->getBuiltinCallee() == + Builtin::BI__builtin_ptrauth_blend_discriminator) { + // Assign modifiers according to blend arguments. + IntDiscr = ConvertToInt64(EmitScalarExpr(MaybeBlend->getArg(1))); + AddrDiscr = ConvertToInt64(EmitScalarExpr(MaybeBlend->getArg(0))); + } else { + // Check if discriminator is a small integer constant and fallback to + // passing an arbitrary raw value otherwise. + llvm::Value *Discr = ConvertToInt64(EmitScalarExpr(DiscrExpr)); + llvm::ConstantInt *DiscrConst = dyn_cast(Discr); + if (DiscrConst && isUInt<16>(DiscrConst->getZExtValue())) + IntDiscr = Discr; + else + AddrDiscr = Discr; + } + llvm::Value *Inputs[] = {Key, IntDiscr, AddrDiscr}; + OBs.emplace_back("ptrauth", Inputs); + }; // Cast the value to intptr_t, saving its original type. + Args.push_back(EmitScalarExpr(E->getArg(0))); llvm::Type *OrigValueType = Args[0]->getType(); - if (OrigValueType->isPointerTy()) - Args[0] = Builder.CreatePtrToInt(Args[0], IntPtrTy); + Args[0] = ConvertToInt64(Args[0]); switch (BuiltinID) { + default: + llvm_unreachable("bad ptrauth intrinsic"); case Builtin::BI__builtin_ptrauth_auth_and_resign: - if (Args[4]->getType()->isPointerTy()) - Args[4] = Builder.CreatePtrToInt(Args[4], IntPtrTy); - [[fallthrough]]; + AddPtrAuthBundle(E->getArg(1), E->getArg(2)); + AddPtrAuthBundle(E->getArg(3), E->getArg(4)); + break; case Builtin::BI__builtin_ptrauth_auth: case Builtin::BI__builtin_ptrauth_sign_unauthenticated: - if (Args[2]->getType()->isPointerTy()) - Args[2] = Builder.CreatePtrToInt(Args[2], IntPtrTy); + AddPtrAuthBundle(E->getArg(1), E->getArg(2)); break; case Builtin::BI__builtin_ptrauth_sign_generic_data: - if (Args[1]->getType()->isPointerTy()) - Args[1] = Builder.CreatePtrToInt(Args[1], IntPtrTy); + Args.push_back(ConvertToInt64(EmitScalarExpr(E->getArg(1)))); break; - case Builtin::BI__builtin_ptrauth_blend_discriminator: - case Builtin::BI__builtin_ptrauth_strip: + case Builtin::BI__builtin_ptrauth_strip: { + llvm::Value *Key = ConvertToInt64(EmitScalarExpr(E->getArg(1))); + OBs.emplace_back("ptrauth", ArrayRef({Key})); break; } + } // Call the intrinsic. auto IntrinsicID = [&]() -> unsigned { @@ -5667,8 +5703,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, return Intrinsic::ptrauth_auth; case Builtin::BI__builtin_ptrauth_auth_and_resign: return Intrinsic::ptrauth_resign; - case Builtin::BI__builtin_ptrauth_blend_discriminator: - return Intrinsic::ptrauth_blend; case Builtin::BI__builtin_ptrauth_sign_generic_data: return Intrinsic::ptrauth_sign_generic; case Builtin::BI__builtin_ptrauth_sign_unauthenticated: @@ -5679,10 +5713,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, llvm_unreachable("bad ptrauth intrinsic"); }(); auto Intrinsic = CGM.getIntrinsic(IntrinsicID); - llvm::Value *Result = EmitRuntimeCall(Intrinsic, Args); + llvm::Value *Result = EmitRuntimeCall(Intrinsic, Args, OBs); if (BuiltinID != Builtin::BI__builtin_ptrauth_sign_generic_data && - BuiltinID != Builtin::BI__builtin_ptrauth_blend_discriminator && OrigValueType->isPointerTy()) { Result = Builder.CreateIntToPtr(Result, OrigValueType); } diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index efacb3cc04c01..4dad5e528a0c4 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -5039,10 +5039,21 @@ CodeGenFunction::getBundlesForFunclet(llvm::Value *Callee) { llvm::CallInst *CodeGenFunction::EmitRuntimeCall(llvm::FunctionCallee callee, ArrayRef args, const llvm::Twine &name) { + return EmitRuntimeCall(callee, args, {}, name); +} + +llvm::CallInst *CodeGenFunction::EmitRuntimeCall( + llvm::FunctionCallee callee, ArrayRef args, + ArrayRef extraBundles, const Twine &name) { + SmallVector allBundles; + llvm::append_range(allBundles, getBundlesForFunclet(callee.getCallee())); + llvm::append_range(allBundles, extraBundles); llvm::CallInst *call = Builder.CreateCall( - callee, args, getBundlesForFunclet(callee.getCallee()), name); + callee, args, allBundles, name); call->setCallingConv(getRuntimeCC()); + // FIXME Attach "convergencectrl" bundle right away instead of re-creating + // the call instruction. if (CGM.shouldEmitConvergenceTokens() && call->isConvergent()) return cast(addConvergenceControlToken(call)); return call; diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index f782b0cd17da4..d28d3012e0622 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -2775,7 +2775,7 @@ llvm::Value *CodeGenFunction::GetVTablePtr(Address This, } else { VTable = cast(EmitPointerAuthAuth( CGPointerAuthInfo(0, PointerAuthenticationMode::Strip, false, false, - nullptr), + 0, nullptr), VTable)); } } diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 0eec4dba4824a..af333bcbcf782 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -2227,9 +2227,7 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) { return ConstantLValue(nullptr); C = applyOffset(C); - C = CGM.getConstantSignedPointer( - C, AuthInfo.getKey(), nullptr, - cast_or_null(AuthInfo.getDiscriminator())); + C = CGM.getConstantSignedPointer(C, AuthInfo); return ConstantLValue(C, /*applied offset*/ true, /*signed*/ true); } diff --git a/clang/lib/CodeGen/CGPointerAuth.cpp b/clang/lib/CodeGen/CGPointerAuth.cpp index a49a0c91681fe..c4e0a1f0d6d79 100644 --- a/clang/lib/CodeGen/CGPointerAuth.cpp +++ b/clang/lib/CodeGen/CGPointerAuth.cpp @@ -23,25 +23,23 @@ using namespace CodeGen; /// Given a pointer-authentication schema, return a concrete "other" /// discriminator for it. -llvm::ConstantInt *CodeGenModule::getPointerAuthOtherDiscriminator( +unsigned CodeGenModule::getPointerAuthOtherDiscriminator( const PointerAuthSchema &Schema, GlobalDecl Decl, QualType Type) { switch (Schema.getOtherDiscrimination()) { case PointerAuthSchema::Discrimination::None: - return nullptr; + return 0; case PointerAuthSchema::Discrimination::Type: assert(!Type.isNull() && "type not provided for type-discriminated schema"); - return llvm::ConstantInt::get( - IntPtrTy, getContext().getPointerAuthTypeDiscriminator(Type)); + return getContext().getPointerAuthTypeDiscriminator(Type); case PointerAuthSchema::Discrimination::Decl: assert(Decl.getDecl() && "declaration not provided for decl-discriminated schema"); - return llvm::ConstantInt::get(IntPtrTy, - getPointerAuthDeclDiscriminator(Decl)); + return getPointerAuthDeclDiscriminator(Decl); case PointerAuthSchema::Discrimination::Constant: - return llvm::ConstantInt::get(IntPtrTy, Schema.getConstantDiscrimination()); + return Schema.getConstantDiscrimination(); } llvm_unreachable("bad discrimination kind"); } @@ -79,23 +77,17 @@ CGPointerAuthInfo CodeGenModule::getFunctionPointerAuthInfo(QualType T) { assert(!Schema.isAddressDiscriminated() && "function pointers cannot use address-specific discrimination"); - llvm::Constant *Discriminator = nullptr; if (T->isFunctionPointerType() || T->isFunctionReferenceType()) T = T->getPointeeType(); + + unsigned IntDiscriminator = 0; if (T->isFunctionType()) - Discriminator = getPointerAuthOtherDiscriminator(Schema, GlobalDecl(), T); + IntDiscriminator = getPointerAuthOtherDiscriminator(Schema, GlobalDecl(), + T); return CGPointerAuthInfo(Schema.getKey(), Schema.getAuthenticationMode(), /*IsaPointer=*/false, /*AuthenticatesNull=*/false, - Discriminator); -} - -llvm::Value * -CodeGenFunction::EmitPointerAuthBlendDiscriminator(llvm::Value *StorageAddress, - llvm::Value *Discriminator) { - StorageAddress = Builder.CreatePtrToInt(StorageAddress, IntPtrTy); - auto Intrinsic = CGM.getIntrinsic(llvm::Intrinsic::ptrauth_blend); - return Builder.CreateCall(Intrinsic, {StorageAddress, Discriminator}); + IntDiscriminator, /*AddrDiscriminator=*/nullptr); } /// Emit the concrete pointer authentication informaton for the @@ -106,23 +98,21 @@ CGPointerAuthInfo CodeGenFunction::EmitPointerAuthInfo( if (!Schema) return CGPointerAuthInfo(); - llvm::Value *Discriminator = + unsigned IntDiscriminator = CGM.getPointerAuthOtherDiscriminator(Schema, SchemaDecl, SchemaType); + llvm::Value *AddrDiscriminator = nullptr; if (Schema.isAddressDiscriminated()) { assert(StorageAddress && "address not provided for address-discriminated schema"); - if (Discriminator) - Discriminator = - EmitPointerAuthBlendDiscriminator(StorageAddress, Discriminator); - else - Discriminator = Builder.CreatePtrToInt(StorageAddress, IntPtrTy); + AddrDiscriminator = Builder.CreatePtrToInt(StorageAddress, IntPtrTy); } return CGPointerAuthInfo(Schema.getKey(), Schema.getAuthenticationMode(), Schema.isIsaPointer(), - Schema.authenticatesNullValues(), Discriminator); + Schema.authenticatesNullValues(), IntDiscriminator, + AddrDiscriminator); } CGPointerAuthInfo @@ -132,24 +122,19 @@ CodeGenFunction::EmitPointerAuthInfo(PointerAuthQualifier Qual, if (Qual.hasKeyNone()) return CGPointerAuthInfo(); - llvm::Value *Discriminator = nullptr; - if (unsigned Extra = Qual.getExtraDiscriminator()) - Discriminator = llvm::ConstantInt::get(IntPtrTy, Extra); + unsigned IntDiscriminator = Qual.getExtraDiscriminator(); + llvm::Value *AddrDiscriminator = nullptr; if (Qual.isAddressDiscriminated()) { assert(StorageAddress.isValid() && "address discrimination without address"); llvm::Value *StoragePtr = StorageAddress.emitRawPointer(*this); - if (Discriminator) - Discriminator = - EmitPointerAuthBlendDiscriminator(StoragePtr, Discriminator); - else - Discriminator = Builder.CreatePtrToInt(StoragePtr, IntPtrTy); + AddrDiscriminator = Builder.CreatePtrToInt(StoragePtr, IntPtrTy); } return CGPointerAuthInfo(Qual.getKey(), Qual.getAuthenticationMode(), Qual.isIsaPointer(), Qual.authenticatesNullValues(), - Discriminator); + IntDiscriminator, AddrDiscriminator); } /// Return the natural pointer authentication for values of the given @@ -278,32 +263,6 @@ llvm::Value *CodeGenFunction::EmitPointerAuthUnqualify( IsKnownNonNull); } -static bool isZeroConstant(const llvm::Value *Value) { - if (const auto *CI = dyn_cast(Value)) - return CI->isZero(); - return false; -} - -static bool equalAuthPolicies(const CGPointerAuthInfo &Left, - const CGPointerAuthInfo &Right) { - assert((Left.isSigned() || Right.isSigned()) && - "shouldn't be called if neither is signed"); - if (Left.isSigned() != Right.isSigned()) - return false; - return Left.getKey() == Right.getKey() && - Left.getAuthenticationMode() == Right.getAuthenticationMode() && - Left.isIsaPointer() == Right.isIsaPointer() && - Left.authenticatesNullValues() == Right.authenticatesNullValues() && - Left.getDiscriminator() == Right.getDiscriminator(); -} - -// Return the discriminator or return zero if the discriminator is null. -static llvm::Value *getDiscriminatorOrZero(const CGPointerAuthInfo &Info, - CGBuilderTy &Builder) { - llvm::Value *Discriminator = Info.getDiscriminator(); - return Discriminator ? Discriminator : Builder.getSize(0); -} - llvm::Value * CodeGenFunction::emitPointerAuthResignCall(llvm::Value *Value, const CGPointerAuthInfo &CurAuth, @@ -321,18 +280,14 @@ CodeGenFunction::emitPointerAuthResignCall(llvm::Value *Value, auto *OrigType = Value->getType(); Value = Builder.CreatePtrToInt(Value, IntPtrTy); - auto *CurKey = Builder.getInt32(CurAuth.getKey()); - auto *NewKey = Builder.getInt32(NewAuth.getKey()); - - llvm::Value *CurDiscriminator = getDiscriminatorOrZero(CurAuth, Builder); - llvm::Value *NewDiscriminator = getDiscriminatorOrZero(NewAuth, Builder); + SmallVector OBs; + EmitPointerAuthOperandBundle(CurAuth, OBs); + EmitPointerAuthOperandBundle(NewAuth, OBs); - // call i64 @llvm.ptrauth.resign(i64 %pointer, - // i32 %curKey, i64 %curDiscriminator, - // i32 %newKey, i64 %newDiscriminator) + // call i64 @llvm.ptrauth.resign(i64 %pointer) [ "ptrauth"(), + // "ptrauth"() ] auto *Intrinsic = CGM.getIntrinsic(llvm::Intrinsic::ptrauth_resign); - Value = EmitRuntimeCall( - Intrinsic, {Value, CurKey, CurDiscriminator, NewKey, NewDiscriminator}); + Value = EmitRuntimeCall(Intrinsic, {Value}, OBs); // Convert back to the original type. Value = Builder.CreateIntToPtr(Value, OrigType); @@ -358,16 +313,8 @@ llvm::Value *CodeGenFunction::emitPointerAuthResign( return Value; // If both schemas sign the same way, we're done. - if (equalAuthPolicies(CurAuthInfo, NewAuthInfo)) { - const llvm::Value *CurD = CurAuthInfo.getDiscriminator(); - const llvm::Value *NewD = NewAuthInfo.getDiscriminator(); - if (CurD == NewD) - return Value; - - if ((CurD == nullptr && isZeroConstant(NewD)) || - (NewD == nullptr && isZeroConstant(CurD))) - return Value; - } + if (CurAuthInfo == NewAuthInfo) + return Value; llvm::BasicBlock *InitBB = Builder.GetInsertBlock(); llvm::BasicBlock *ResignBB = nullptr, *ContBB = nullptr; @@ -420,6 +367,14 @@ void CodeGenFunction::EmitPointerAuthCopy(PointerAuthQualifier Qual, QualType T, Builder.CreateStore(Value, DestAddress); } +llvm::Constant *CodeGenModule::getConstantSignedPointer( + llvm::Constant *Pointer, CGPointerAuthInfo Info) { + auto *AddrDisc = + dyn_cast_or_null(Info.getAddrDiscriminator()); + auto *IntDisc = llvm::ConstantInt::get(Int64Ty, Info.getIntDiscriminator()); + return getConstantSignedPointer(Pointer, Info.getKey(), AddrDisc, IntDisc); +} + llvm::Constant * CodeGenModule::getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key, llvm::Constant *StorageAddress, @@ -427,9 +382,10 @@ CodeGenModule::getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key, llvm::Constant *AddressDiscriminator; if (StorageAddress) { assert(StorageAddress->getType() == DefaultPtrTy); - AddressDiscriminator = StorageAddress; + AddressDiscriminator = llvm::ConstantExpr::getPtrToInt(StorageAddress, + Int64Ty); } else { - AddressDiscriminator = llvm::Constant::getNullValue(DefaultPtrTy); + AddressDiscriminator = llvm::ConstantInt::get(Int64Ty, 0); } llvm::ConstantInt *IntegerDiscriminator; @@ -440,10 +396,15 @@ CodeGenModule::getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key, IntegerDiscriminator = llvm::ConstantInt::get(Int64Ty, 0); } - return llvm::ConstantPtrAuth::get( - Pointer, llvm::ConstantInt::get(Int32Ty, Key), IntegerDiscriminator, - AddressDiscriminator, - /*DeactivationSymbol=*/llvm::Constant::getNullValue(DefaultPtrTy)); + SmallVector Schema; + Schema.push_back(llvm::ConstantInt::get(Int64Ty, Key)); + Schema.push_back(IntegerDiscriminator); + Schema.push_back(AddressDiscriminator); + + llvm::Constant *Null = llvm::Constant::getNullValue(DefaultPtrTy); + + return llvm::ConstantPtrAuth::get(Pointer, Schema, + /*DeactivationSymbol=*/Null); } /// Does a given PointerAuthScheme require us to sign a value @@ -460,11 +421,12 @@ llvm::Constant *CodeGenModule::getConstantSignedPointer( llvm::Constant *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType) { assert(shouldSignPointer(Schema)); - llvm::ConstantInt *OtherDiscriminator = + unsigned Disc = getPointerAuthOtherDiscriminator(Schema, SchemaDecl, SchemaType); + auto *IntDiscriminator = llvm::ConstantInt::get(Int64Ty, Disc); return getConstantSignedPointer(Pointer, Schema.getKey(), StorageAddress, - OtherDiscriminator); + IntDiscriminator); } llvm::Constant * @@ -484,9 +446,7 @@ llvm::Constant *CodeGenModule::getFunctionPointer(llvm::Constant *Pointer, FunctionType->isFunctionPointerType()); if (auto PointerAuth = getFunctionPointerAuthInfo(FunctionType)) - return getConstantSignedPointer( - Pointer, PointerAuth.getKey(), /*StorageAddress=*/nullptr, - cast_or_null(PointerAuth.getDiscriminator())); + return getConstantSignedPointer(Pointer, PointerAuth); return Pointer; } @@ -515,19 +475,18 @@ CGPointerAuthInfo CodeGenModule::getMemberFunctionPointerAuthInfo(QualType FT) { assert(!Schema.isAddressDiscriminated() && "function pointers cannot use address-specific discrimination"); - llvm::ConstantInt *Discriminator = + unsigned IntDiscriminator = getPointerAuthOtherDiscriminator(Schema, GlobalDecl(), FT); return CGPointerAuthInfo(Schema.getKey(), Schema.getAuthenticationMode(), /* IsIsaPointer */ false, - /* AuthenticatesNullValues */ false, Discriminator); + /* AuthenticatesNullValues */ false, + IntDiscriminator, /*AddrDiscriminator=*/nullptr); } llvm::Constant *CodeGenModule::getMemberFunctionPointer(llvm::Constant *Pointer, QualType FT) { if (CGPointerAuthInfo PointerAuth = getMemberFunctionPointerAuthInfo(FT)) - return getConstantSignedPointer( - Pointer, PointerAuth.getKey(), nullptr, - cast_or_null(PointerAuth.getDiscriminator())); + return getConstantSignedPointer(Pointer, PointerAuth); if (const auto *MFT = dyn_cast(FT.getTypePtr())) { if (MFT->hasPointeeToToCFIUncheckedCalleeFunctionType()) @@ -635,24 +594,20 @@ CodeGenModule::getVTablePointerAuthInfo(CodeGenFunction *CGF, if (!Authentication) return std::nullopt; - llvm::Value *Discriminator = nullptr; - if (auto ExtraDiscriminator = Authentication->getExtraDiscriminator()) - Discriminator = llvm::ConstantInt::get(IntPtrTy, ExtraDiscriminator); + unsigned IntDiscriminator = Authentication->getExtraDiscriminator(); + llvm::Value *AddrDiscriminator = nullptr; if (Authentication->isAddressDiscriminated()) { assert(StorageAddress && "address not provided for address-discriminated schema"); - if (Discriminator) - Discriminator = - CGF->EmitPointerAuthBlendDiscriminator(StorageAddress, Discriminator); - else - Discriminator = CGF->Builder.CreatePtrToInt(StorageAddress, IntPtrTy); + AddrDiscriminator = CGF->Builder.CreatePtrToInt(StorageAddress, IntPtrTy); } return CGPointerAuthInfo(Authentication->getKey(), PointerAuthenticationMode::SignAndAuth, /* IsIsaPointer */ false, - /* AuthenticatesNullValues */ false, Discriminator); + /* AuthenticatesNullValues */ false, IntDiscriminator, + AddrDiscriminator); } llvm::Value *CodeGenFunction::authPointerToPointerCast(llvm::Value *ResultPtr, diff --git a/clang/lib/CodeGen/CGPointerAuthInfo.h b/clang/lib/CodeGen/CGPointerAuthInfo.h index 0a0c11fb423f2..91dc2fb7219d5 100644 --- a/clang/lib/CodeGen/CGPointerAuthInfo.h +++ b/clang/lib/CodeGen/CGPointerAuthInfo.h @@ -13,35 +13,31 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_CGPOINTERAUTHINFO_H #define LLVM_CLANG_LIB_CODEGEN_CGPOINTERAUTHINFO_H -#include "clang/AST/Type.h" #include "clang/Basic/LangOptions.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" +#include namespace clang { namespace CodeGen { class CGPointerAuthInfo { -private: - PointerAuthenticationMode AuthenticationMode : 2; - unsigned IsIsaPointer : 1; - unsigned AuthenticatesNullValues : 1; - unsigned Key : 2; - llvm::Value *Discriminator; - public: CGPointerAuthInfo() : AuthenticationMode(PointerAuthenticationMode::None), IsIsaPointer(false), AuthenticatesNullValues(false), Key(0), - Discriminator(nullptr) {} + IntDiscriminator(0), AddrDiscriminator(nullptr) {} CGPointerAuthInfo(unsigned Key, PointerAuthenticationMode AuthenticationMode, bool IsIsaPointer, bool AuthenticatesNullValues, - llvm::Value *Discriminator) + unsigned IntDiscriminator, + llvm::Value *AddrDiscriminator) : AuthenticationMode(AuthenticationMode), IsIsaPointer(IsIsaPointer), AuthenticatesNullValues(AuthenticatesNullValues), Key(Key), - Discriminator(Discriminator) { - assert(!Discriminator || Discriminator->getType()->isIntegerTy() || - Discriminator->getType()->isPointerTy()); + IntDiscriminator(IntDiscriminator), + AddrDiscriminator(AddrDiscriminator) { + assert(llvm::isUInt<16>(IntDiscriminator)); + assert(!AddrDiscriminator || AddrDiscriminator->getType()->isIntegerTy() || + AddrDiscriminator->getType()->isPointerTy()); } explicit operator bool() const { return isSigned(); } @@ -54,9 +50,15 @@ class CGPointerAuthInfo { assert(isSigned()); return Key; } - llvm::Value *getDiscriminator() const { + + unsigned getIntDiscriminator() const { + assert(isSigned()); + return IntDiscriminator; + } + + llvm::Value *getAddrDiscriminator() const { assert(isSigned()); - return Discriminator; + return AddrDiscriminator; } PointerAuthenticationMode getAuthenticationMode() const { @@ -83,14 +85,26 @@ class CGPointerAuthInfo { friend bool operator!=(const CGPointerAuthInfo &LHS, const CGPointerAuthInfo &RHS) { - return LHS.Key != RHS.Key || LHS.Discriminator != RHS.Discriminator || - LHS.AuthenticationMode != RHS.AuthenticationMode; + return !(LHS == RHS); } friend bool operator==(const CGPointerAuthInfo &LHS, const CGPointerAuthInfo &RHS) { - return !(LHS != RHS); + auto AsTuple = [](const CGPointerAuthInfo &Info) { + return std::make_tuple(Info.AuthenticationMode, Info.IsIsaPointer, + Info.AuthenticatesNullValues, Info.Key, + Info.IntDiscriminator, Info.AddrDiscriminator); + }; + return AsTuple(LHS) == AsTuple(RHS); } + +private: + PointerAuthenticationMode AuthenticationMode : 2; + unsigned IsIsaPointer : 1; + unsigned AuthenticatesNullValues : 1; + unsigned Key : 2; + unsigned IntDiscriminator; + llvm::Value *AddrDiscriminator; }; } // end namespace CodeGen diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index ac25bd95f0463..da78bf1a41578 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -3308,13 +3308,13 @@ void CodeGenFunction::EmitPointerAuthOperandBundle( if (!PointerAuth.isSigned()) return; - auto *Key = Builder.getInt32(PointerAuth.getKey()); + llvm::Value *Key = Builder.getInt64(PointerAuth.getKey()); + llvm::Value *IntDisc = Builder.getInt64(PointerAuth.getIntDiscriminator()); + llvm::Value *AddrDisc = PointerAuth.getAddrDiscriminator(); + if (!AddrDisc) + AddrDisc = Builder.getInt64(0); - llvm::Value *Discriminator = PointerAuth.getDiscriminator(); - if (!Discriminator) - Discriminator = Builder.getSize(0); - - llvm::Value *Args[] = {Key, Discriminator}; + llvm::Value *Args[] = {Key, IntDisc, AddrDisc}; Bundles.emplace_back("ptrauth", Args); } @@ -3325,20 +3325,16 @@ static llvm::Value *EmitPointerAuthCommon(CodeGenFunction &CGF, if (!PointerAuth) return Pointer; - auto Key = CGF.Builder.getInt32(PointerAuth.getKey()); - - llvm::Value *Discriminator = PointerAuth.getDiscriminator(); - if (!Discriminator) { - Discriminator = CGF.Builder.getSize(0); - } + SmallVector OBs; + CGF.EmitPointerAuthOperandBundle(PointerAuth, OBs); // Convert the pointer to intptr_t before signing it. auto OrigType = Pointer->getType(); Pointer = CGF.Builder.CreatePtrToInt(Pointer, CGF.IntPtrTy); - // call i64 @llvm.ptrauth.sign.i64(i64 %pointer, i32 %key, i64 %discriminator) + // call i64 @llvm.ptrauth.(i64 %pointer) [ "ptrauth"()] auto Intrinsic = CGF.CGM.getIntrinsic(IntrinsicID); - Pointer = CGF.EmitRuntimeCall(Intrinsic, {Pointer, Key, Discriminator}); + Pointer = CGF.EmitRuntimeCall(Intrinsic, {Pointer}, OBs); // Convert back to the original type. Pointer = CGF.Builder.CreateIntToPtr(Pointer, OrigType); @@ -3354,24 +3350,24 @@ CodeGenFunction::EmitPointerAuthSign(const CGPointerAuthInfo &PointerAuth, llvm::Intrinsic::ptrauth_sign); } -static llvm::Value *EmitStrip(CodeGenFunction &CGF, - const CGPointerAuthInfo &PointerAuth, - llvm::Value *Pointer) { - auto StripIntrinsic = CGF.CGM.getIntrinsic(llvm::Intrinsic::ptrauth_strip); +llvm::Value *CodeGenFunction::emitStrip(const CGPointerAuthInfo &PointerAuth, + llvm::Value *Pointer) { + auto StripIntrinsic = CGM.getIntrinsic(llvm::Intrinsic::ptrauth_strip); - auto Key = CGF.Builder.getInt32(PointerAuth.getKey()); + auto Key = Builder.getInt64(PointerAuth.getKey()); // Convert the pointer to intptr_t before signing it. auto OrigType = Pointer->getType(); - Pointer = CGF.EmitRuntimeCall( - StripIntrinsic, {CGF.Builder.CreatePtrToInt(Pointer, CGF.IntPtrTy), Key}); - return CGF.Builder.CreateIntToPtr(Pointer, OrigType); + llvm::OperandBundleDef OB("ptrauth", ArrayRef({Key})); + Pointer = EmitRuntimeCall( + StripIntrinsic, {Builder.CreatePtrToInt(Pointer, IntPtrTy)}, {OB}); + return Builder.CreateIntToPtr(Pointer, OrigType); } llvm::Value * CodeGenFunction::EmitPointerAuthAuth(const CGPointerAuthInfo &PointerAuth, llvm::Value *Pointer) { if (PointerAuth.shouldStrip()) { - return EmitStrip(*this, PointerAuth, Pointer); + return emitStrip(PointerAuth, Pointer); } if (!PointerAuth.shouldAuth()) { return Pointer; diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 8c4c1c8c2dc95..fbf0df3407375 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -4553,6 +4553,10 @@ class CodeGenFunction : public CodeGenTypeCache { llvm::CallInst *EmitRuntimeCall(llvm::FunctionCallee callee, ArrayRef args, const Twine &name = ""); + llvm::CallInst *EmitRuntimeCall(llvm::FunctionCallee callee, + ArrayRef args, + ArrayRef extraBundles, + const Twine &name = ""); llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name = ""); llvm::CallInst *EmitNounwindRuntimeCall(llvm::FunctionCallee callee, @@ -4587,9 +4591,6 @@ class CodeGenFunction : public CodeGenTypeCache { /// Check whether the underlying base pointer is a constant null. bool isUnderlyingBasePointerConstantNull(const Expr *E); - /// Create the discriminator from the storage address and the entity hash. - llvm::Value *EmitPointerAuthBlendDiscriminator(llvm::Value *StorageAddress, - llvm::Value *Discriminator); CGPointerAuthInfo EmitPointerAuthInfo(const PointerAuthSchema &Schema, llvm::Value *StorageAddress, GlobalDecl SchemaDecl, @@ -4608,6 +4609,8 @@ class CodeGenFunction : public CodeGenTypeCache { llvm::Value *emitPointerAuthResignCall(llvm::Value *Pointer, const CGPointerAuthInfo &CurInfo, const CGPointerAuthInfo &NewInfo); + llvm::Value *emitStrip(const CGPointerAuthInfo &PointerAuth, + llvm::Value *Pointer); void EmitPointerAuthOperandBundle( const CGPointerAuthInfo &Info, diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index a253bcda2d06c..5761ac0f52f16 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1057,12 +1057,15 @@ class CodeGenModule : public CodeGenTypeCache { GlobalDecl SchemaDecl, QualType SchemaType); + llvm::Constant * + getConstantSignedPointer(llvm::Constant *Pointer, CGPointerAuthInfo Info); + llvm::Constant * getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key, llvm::Constant *StorageAddress, llvm::ConstantInt *OtherDiscriminator); - llvm::ConstantInt * + unsigned getPointerAuthOtherDiscriminator(const PointerAuthSchema &Schema, GlobalDecl SchemaDecl, QualType SchemaType); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 65c47633bc5c4..47db6847063ac 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -871,11 +871,27 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( CGM.getMemberFunctionPointerAuthInfo(QualType(MPT, 0)); assert(Schema.getKey() == AuthInfo.getKey() && "Keys for virtual and non-virtual member functions must match"); - auto *NonVirtualDiscriminator = AuthInfo.getDiscriminator(); + auto *NonVirtualDiscriminator = + Builder.getInt64(AuthInfo.getIntDiscriminator()); + assert(!AuthInfo.getAddrDiscriminator()); + // FIXME Investigate re-signing VirtualFn pointer in FnVirtual basic block + // to the same non-zero discriminator or other safer options. + // + // Depending on its origin, CalleePtr is authenticated using one of + // two possible constant discriminators. That integer discriminator + // may end up being spilled to the stack and thus be susceptible to + // substitution by the attacker. Authenticating CalleePtr at this + // point is not an option, as it would make things even worse by + // exposing completely unprotected function pointer instead of less + // sensitive discriminator value. + // + // "Upgrading" VirtualFn's schema to a custom constant discriminator + // would probably help, but it still requires investigation. + DiscriminatorPHI->addIncoming(NonVirtualDiscriminator, FnNonVirtual); PointerAuth = CGPointerAuthInfo( Schema.getKey(), Schema.getAuthenticationMode(), Schema.isIsaPointer(), - Schema.authenticatesNullValues(), DiscriminatorPHI); + Schema.authenticatesNullValues(), 0, DiscriminatorPHI); } CGCallee Callee(FPT, CalleePtr, PointerAuth); @@ -907,14 +923,14 @@ static llvm::Constant *pointerAuthResignConstant( if (!CPA) return nullptr; - assert(CPA->getKey()->getZExtValue() == CurAuthInfo.getKey() && - CPA->getAddrDiscriminator()->isZeroValue() && - CPA->getDiscriminator() == CurAuthInfo.getDiscriminator() && - "unexpected key or discriminators"); + assert(CPA->getKey()->getZExtValue() == CurAuthInfo.getKey()); + assert(CPA->getDiscriminator()->getZExtValue() == + CurAuthInfo.getIntDiscriminator()); + assert(!CurAuthInfo.getAddrDiscriminator() && + !NewAuthInfo.getAddrDiscriminator() && + CPA->getAddrDiscriminator()->isZeroValue()); - return CGM.getConstantSignedPointer( - CPA->getPointer(), NewAuthInfo.getKey(), nullptr, - cast(NewAuthInfo.getDiscriminator())); + return CGM.getConstantSignedPointer(CPA->getPointer(), NewAuthInfo); } /// Perform a bitcast, derived-to-base, or base-to-derived member pointer @@ -1769,7 +1785,7 @@ llvm::Value *ItaniumCXXABI::emitExactDynamicCast( // authenticate the resulting v-table at the end of the cast check. PerformPostCastAuthentication = CGF.getLangOpts().PointerAuthCalls; CGPointerAuthInfo StrippingAuthInfo(0, PointerAuthenticationMode::Strip, - false, false, nullptr); + false, false, 0, nullptr); Address VTablePtrPtr = ThisAddr.withElementType(CGF.VoidPtrPtrTy); VTable = CGF.Builder.CreateLoad(VTablePtrPtr, "vtable"); if (PerformPostCastAuthentication) diff --git a/clang/test/CodeGen/ptrauth-function-init.c b/clang/test/CodeGen/ptrauth-function-init.c index bf8ee53364ecc..89dad8953edaf 100644 --- a/clang/test/CodeGen/ptrauth-function-init.c +++ b/clang/test/CodeGen/ptrauth-function-init.c @@ -12,7 +12,7 @@ void f(void); #ifdef __cplusplus // CXX: define {{(dso_local )?}}internal void @__cxx_global_var_init() -// CXX: store ptr getelementptr inbounds (i32, ptr ptrauth (ptr @f, i32 0), i64 2), ptr @_ZL2fp, align 8 +// CXX: store ptr getelementptr inbounds (i32, ptr ptrauth (ptr @f, [i64 0, i64 0, i64 0]), i64 2), ptr @_ZL2fp, align 8 // This is rejected in C mode as adding a non-zero constant to a signed pointer // is unrepresentable in relocations. In C++ mode, this can be done dynamically @@ -25,7 +25,7 @@ void (*const fp)(void) = (void (*)(void))((int *)&f + 2); // CHECK: define {{(dso_local )?}}void @t1() void t1() { // CHECK: [[PF:%.*]] = alloca ptr - // CHECK: store ptr getelementptr inbounds (i32, ptr ptrauth (ptr @f, i32 0), i64 2), ptr [[PF]] + // CHECK: store ptr getelementptr inbounds (i32, ptr ptrauth (ptr @f, [i64 0, i64 0, i64 0]), i64 2), ptr [[PF]] void (*pf)(void) = (void (*)(void))((int *)&f + 2); (void)pf; diff --git a/clang/test/CodeGen/ptrauth-function-lvalue-cast-disc.c b/clang/test/CodeGen/ptrauth-function-lvalue-cast-disc.c index 40bba99478192..15328df75f4dd 100644 --- a/clang/test/CodeGen/ptrauth-function-lvalue-cast-disc.c +++ b/clang/test/CodeGen/ptrauth-function-lvalue-cast-disc.c @@ -12,8 +12,8 @@ void (*fptr)(void); void test1() { // TYPE: [[LOAD:%.*]] = load ptr, ptr @cptr // TYPE: [[TOINT:%.*]] = ptrtoint ptr [[LOAD]] to i64 - // TYPE: call i64 @llvm.ptrauth.resign(i64 [[TOINT]], i32 0, i64 0, i32 0, i64 18983) - // TYPE: call void {{.*}}() [ "ptrauth"(i32 0, i64 18983) ] + // TYPE: call i64 @llvm.ptrauth.resign(i64 [[TOINT]]) [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 0, i64 18983, i64 0) ] + // TYPE: call void {{.*}}() [ "ptrauth"(i64 0, i64 18983, i64 0) ] // ZERO-NOT: @llvm.ptrauth.resign (*(fptr_t)cptr)(); @@ -29,7 +29,7 @@ char test2() { // TYPE: [[NONNULL]]: // TYPE: [[TOINT:%.*]] = ptrtoint ptr [[LOAD]] to i64 - // TYPE: [[CALL:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[TOINT]], i32 0, i64 18983, i32 0, i64 0) + // TYPE: [[CALL:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[TOINT]]) [ "ptrauth"(i64 0, i64 18983, i64 0), "ptrauth"(i64 0, i64 0, i64 0) ] // TYPE: [[TOPTR:%.*]] = inttoptr i64 [[CALL]] to ptr // TYPE: [[CONT]]: @@ -43,11 +43,11 @@ void test4() { // CHECK: [[LOAD:%.*]] = load ptr, ptr @cptr // TYPE-NEXT: [[CAST4:%.*]] = ptrtoint ptr [[LOAD]] to i64 - // TYPE-NEXT: [[RESIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[CAST4]], i32 0, i64 0, i32 0, i64 18983) + // TYPE-NEXT: [[RESIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[CAST4]]) [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 0, i64 18983, i64 0) ] // TYPE-NEXT: [[CAST5:%.*]] = inttoptr i64 [[RESIGN]] to ptr - // TYPE-NEXT: call void [[CAST5]]() [ "ptrauth"(i32 0, i64 18983) ] + // TYPE-NEXT: call void [[CAST5]]() [ "ptrauth"(i64 0, i64 18983, i64 0) ] // ZERO-NOT: @llvm.ptrauth.resign - // ZERO: call void [[LOAD]]() [ "ptrauth"(i32 0, i64 0) ] + // ZERO: call void [[LOAD]]() [ "ptrauth"(i64 0, i64 0, i64 0) ] } void *vptr; @@ -60,7 +60,7 @@ void test5() { // TYPE-NEXT: br i1 [[CMP]], label %[[NONNULL:.*]], label %[[CONT:.*]] // TYPE: [[NONNULL]]: - // TYPE: [[RESIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 {{.*}}, i32 0, i64 18983, i32 0, i64 0) + // TYPE: [[RESIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 {{.*}}) [ "ptrauth"(i64 0, i64 18983, i64 0), "ptrauth"(i64 0, i64 0, i64 0) ] // TYPE: [[CAST:%.*]] = inttoptr i64 [[RESIGN]] to ptr // TYPE: [[CONT]]: diff --git a/clang/test/CodeGen/ptrauth-function-lvalue-cast.c b/clang/test/CodeGen/ptrauth-function-lvalue-cast.c index 8d8af18fcafbe..25ef81fd54966 100644 --- a/clang/test/CodeGen/ptrauth-function-lvalue-cast.c +++ b/clang/test/CodeGen/ptrauth-function-lvalue-cast.c @@ -9,7 +9,7 @@ void (*fptr)(void); // CHECK: define {{(dso_local )?}}void @test1 void test1() { // CHECK: [[LOAD:%.*]] = load ptr, ptr @cptr - // CHECK: call void [[LOAD]]() [ "ptrauth"(i32 0, i64 0) ] + // CHECK: call void [[LOAD]]() [ "ptrauth"(i64 0, i64 0, i64 0) ] // CHECK: ret void (*(fptr_t)cptr)(); diff --git a/clang/test/CodeGen/ptrauth-function-type-discriminator-cast.c b/clang/test/CodeGen/ptrauth-function-type-discriminator-cast.c index 1a1dce6f4a66e..1c034182bb664 100644 --- a/clang/test/CodeGen/ptrauth-function-type-discriminator-cast.c +++ b/clang/test/CodeGen/ptrauth-function-type-discriminator-cast.c @@ -34,7 +34,7 @@ ptr_member pm; void (*test_member)() = (void (*)())pm.fptr_; // CHECKCXX-LABEL: define{{.*}} internal void @__cxx_global_var_init -// TYPECXX: call i64 @llvm.ptrauth.resign(i64 {{.*}}, i32 0, i64 2712, i32 0, i64 18983) +// TYPECXX: call i64 @llvm.ptrauth.resign(i64 {{.*}}) [ "ptrauth"(i64 0, i64 2712, i64 0), "ptrauth"(i64 0, i64 18983, i64 0) ] #endif @@ -42,7 +42,7 @@ void (*test_member)() = (void (*)())pm.fptr_; void test_cast_to_opaque() { opaque = (void *)f; - // TYPE: [[RESIGN_VAL:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @f, i32 0, i64 18983) to i64), i32 0, i64 18983, i32 0, i64 0) + // TYPE: [[RESIGN_VAL:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @f, [i64 0, i64 18983, i64 0]) to i64)) [ "ptrauth"(i64 0, i64 18983, i64 0), "ptrauth"(i64 0, i64 0, i64 0) ] // TYPE: [[RESIGN_PTR:%.*]] = inttoptr i64 [[RESIGN_VAL]] to ptr // ZERO-NOT: @llvm.ptrauth.resign } @@ -57,7 +57,7 @@ void test_cast_from_opaque() { // TYPE: [[RESIGN_LAB]]: // TYPE: [[INT:%.*]] = ptrtoint ptr [[LOAD]] to i64 - // TYPE: [[RESIGN_INT:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[INT]], i32 0, i64 0, i32 0, i64 18983) + // TYPE: [[RESIGN_INT:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[INT]]) [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 0, i64 18983, i64 0) ] // ZERO-NOT: @llvm.ptrauth.resign } @@ -73,7 +73,7 @@ void test_cast_to_intptr() { // TYPE: [[RESIGN_LAB]]: // TYPE: [[INT:%.*]] = ptrtoint ptr [[LOAD]] to i64 - // TYPE: [[RESIGN_INT:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[INT]], i32 0, i64 18983, i32 0, i64 0) + // TYPE: [[RESIGN_INT:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[INT]]) [ "ptrauth"(i64 0, i64 18983, i64 0), "ptrauth"(i64 0, i64 0, i64 0) ] // TYPE: [[RESIGN:%.*]] = inttoptr i64 [[RESIGN_INT]] to ptr // TYPE: br label %[[RESIGN_CONT]] @@ -86,7 +86,7 @@ void test_cast_to_intptr() { // CHECK-LABEL: define{{.*}} void @test_function_to_function_cast void test_function_to_function_cast() { void (*fptr2)(int) = (void (*)(int))fptr; - // TYPE: call i64 @llvm.ptrauth.resign(i64 {{.*}}, i32 0, i64 18983, i32 0, i64 2712) + // TYPE: call i64 @llvm.ptrauth.resign(i64 {{.*}}) [ "ptrauth"(i64 0, i64 18983, i64 0), "ptrauth"(i64 0, i64 2712, i64 0) ] // ZERO-NOT: @llvm.ptrauth.resign } @@ -95,11 +95,11 @@ void test_call_lvalue_cast() { (*(void (*)(int))f)(42); // TYPE: entry: - // TYPE-NEXT: [[RESIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @f, i32 0, i64 18983) to i64), i32 0, i64 18983, i32 0, i64 2712) + // TYPE-NEXT: [[RESIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @f, [i64 0, i64 18983, i64 0]) to i64)) [ "ptrauth"(i64 0, i64 18983, i64 0), "ptrauth"(i64 0, i64 2712, i64 0) ] // TYPE-NEXT: [[RESIGN_INT:%.*]] = inttoptr i64 [[RESIGN]] to ptr - // TYPE-NEXT: call void [[RESIGN_INT]](i32 noundef 42) [ "ptrauth"(i32 0, i64 2712) ] + // TYPE-NEXT: call void [[RESIGN_INT]](i32 noundef 42) [ "ptrauth"(i64 0, i64 2712, i64 0) ] // ZERO-NOT: @llvm.ptrauth.resign - // ZERO: call void ptrauth (ptr @f, i32 0)(i32 noundef 42) [ "ptrauth"(i32 0, i64 0) ] + // ZERO: call void ptrauth (ptr @f, [i64 0, i64 0, i64 0])(i32 noundef 42) [ "ptrauth"(i64 0, i64 0, i64 0) ] } diff --git a/clang/test/CodeGen/ptrauth-function-type-discriminator.c b/clang/test/CodeGen/ptrauth-function-type-discriminator.c index 0952c1abf6c07..773decff900f7 100644 --- a/clang/test/CodeGen/ptrauth-function-type-discriminator.c +++ b/clang/test/CodeGen/ptrauth-function-type-discriminator.c @@ -27,53 +27,53 @@ unsigned long uintptr; // CHECK: @test_constant_null = global ptr null void (*test_constant_null)(int) = 0; -// CHECK: @test_constant_cast = global ptr ptrauth (ptr @f, i32 0, i64 2712) +// CHECK: @test_constant_cast = global ptr ptrauth (ptr @f, [i64 0, i64 2712, i64 0]) void (*test_constant_cast)(int) = (void (*)(int))f; #ifndef __cplusplus -// CHECKC: @enum_func_ptr = global ptr ptrauth (ptr @enum_func, i32 0, i64 2712) +// CHECKC: @enum_func_ptr = global ptr ptrauth (ptr @enum_func, [i64 0, i64 2712, i64 0]) enum Enum0; void enum_func(enum Enum0); void (*enum_func_ptr)(enum Enum0) = enum_func; #endif -// CHECK: @test_opaque = global ptr ptrauth (ptr @f, i32 0) +// CHECK: @test_opaque = global ptr ptrauth (ptr @f, [i64 0, i64 0, i64 0]) void *test_opaque = #ifdef __cplusplus (void *) #endif (void (*)(int))(double (*)(double))f; -// CHECK: @test_intptr_t = global i64 ptrtoint (ptr ptrauth (ptr @f, i32 0) to i64) +// CHECK: @test_intptr_t = global i64 ptrtoint (ptr ptrauth (ptr @f, [i64 0, i64 0, i64 0]) to i64) unsigned long test_intptr_t = (unsigned long)f; -// CHECK: @test_through_long = global ptr ptrauth (ptr @f, i32 0, i64 2712) +// CHECK: @test_through_long = global ptr ptrauth (ptr @f, [i64 0, i64 2712, i64 0]) void (*test_through_long)(int) = (void (*)(int))(long)f; -// CHECK: @test_to_long = global i64 ptrtoint (ptr ptrauth (ptr @f, i32 0) to i64) +// CHECK: @test_to_long = global i64 ptrtoint (ptr ptrauth (ptr @f, [i64 0, i64 0, i64 0]) to i64) long test_to_long = (long)(double (*)())f; extern void external_function(void); -// CHECK: @fptr1 = global ptr ptrauth (ptr @external_function, i32 0, i64 18983) +// CHECK: @fptr1 = global ptr ptrauth (ptr @external_function, [i64 0, i64 18983, i64 0]) void (*fptr1)(void) = external_function; -// CHECK: @fptr2 = global ptr ptrauth (ptr @external_function, i32 0, i64 18983) +// CHECK: @fptr2 = global ptr ptrauth (ptr @external_function, [i64 0, i64 18983, i64 0]) void (*fptr2)(void) = &external_function; -// CHECK: @fptr3 = global ptr ptrauth (ptr @external_function, i32 2, i64 26) +// CHECK: @fptr3 = global ptr ptrauth (ptr @external_function, [i64 2, i64 26, i64 0]) void (*fptr3)(void) = __builtin_ptrauth_sign_constant(&external_function, 2, 26); -// CHECK: @fptr4 = global ptr ptrauth (ptr @external_function, i32 2, i64 26, ptr @fptr4) +// CHECK: @fptr4 = global ptr ptrauth (ptr @external_function, [i64 2, i64 26, i64 ptrtoint (ptr @fptr4 to i64)]) void (*fptr4)(void) = __builtin_ptrauth_sign_constant(&external_function, 2, __builtin_ptrauth_blend_discriminator(&fptr4, 26)); // CHECK-LABEL: define{{.*}} void @test_call() void test_call() { // CHECK: [[T0:%.*]] = load ptr, ptr @fnptr, - // CHECK-NEXT: call void [[T0]]() [ "ptrauth"(i32 0, i64 18983) ] + // CHECK-NEXT: call void [[T0]]() [ "ptrauth"(i64 0, i64 18983, i64 0) ] fnptr(); } // CHECK-LABEL: define{{.*}} ptr @test_function_pointer() -// CHECK: ret ptr ptrauth (ptr @external_function, i32 0, i64 18983) +// CHECK: ret ptr ptrauth (ptr @external_function, [i64 0, i64 18983, i64 0]) void (*test_function_pointer())(void) { return external_function; } @@ -83,14 +83,14 @@ extern struct InitiallyIncomplete returns_initially_incomplete(void); // CHECK-LABEL: define{{.*}} void @use_while_incomplete() void use_while_incomplete() { // CHECK: [[VAR:%.*]] = alloca ptr, - // CHECK-NEXT: store ptr ptrauth (ptr @returns_initially_incomplete, i32 0, i64 25106), ptr [[VAR]] + // CHECK-NEXT: store ptr ptrauth (ptr @returns_initially_incomplete, [i64 0, i64 25106, i64 0]), ptr [[VAR]] struct InitiallyIncomplete (*fnptr)(void) = &returns_initially_incomplete; } struct InitiallyIncomplete { int x; }; // CHECK-LABEL: define{{.*}} void @use_while_complete() void use_while_complete() { // CHECK: [[VAR:%.*]] = alloca ptr, - // CHECK-NEXT: store ptr ptrauth (ptr @returns_initially_incomplete, i32 0, i64 25106), ptr [[VAR]] + // CHECK-NEXT: store ptr ptrauth (ptr @returns_initially_incomplete, [i64 0, i64 25106, i64 0]), ptr [[VAR]] // CHECK-NEXT: ret void struct InitiallyIncomplete (*fnptr)(void) = &returns_initially_incomplete; } @@ -107,9 +107,9 @@ void test_knr() { p(0); // CHECKC: [[P:%.*]] = alloca ptr - // CHECKC: store ptr ptrauth (ptr @knr, i32 0, i64 18983), ptr [[P]] + // CHECKC: store ptr ptrauth (ptr @knr, [i64 0, i64 18983, i64 0]), ptr [[P]] // CHECKC: [[LOAD:%.*]] = load ptr, ptr [[P]] - // CHECKC: call void [[LOAD]](i32 noundef 0) [ "ptrauth"(i32 0, i64 18983) ] + // CHECKC: call void [[LOAD]](i32 noundef 0) [ "ptrauth"(i64 0, i64 18983, i64 0) ] } // CHECKC-LABEL: define{{.*}} void @test_redeclaration @@ -121,10 +121,10 @@ void test_redeclaration() { ptr(); ptr2(0); - // CHECKC: store ptr ptrauth (ptr @redecl, i32 0, i64 18983), ptr %ptr - // CHECKC: store ptr ptrauth (ptr @redecl, i32 0, i64 2712), ptr %ptr2 - // CHECKC: call void {{.*}}() [ "ptrauth"(i32 0, i64 18983) ] - // CHECKC: call void {{.*}}(i32 noundef 0) [ "ptrauth"(i32 0, i64 2712) ] + // CHECKC: store ptr ptrauth (ptr @redecl, [i64 0, i64 18983, i64 0]), ptr %ptr + // CHECKC: store ptr ptrauth (ptr @redecl, [i64 0, i64 2712, i64 0]), ptr %ptr2 + // CHECKC: call void {{.*}}() [ "ptrauth"(i64 0, i64 18983, i64 0) ] + // CHECKC: call void {{.*}}(i32 noundef 0) [ "ptrauth"(i64 0, i64 2712, i64 0) ] } void knr2(param) @@ -136,16 +136,16 @@ void test_redecl_knr() { void (*p)() = knr2; p(); - // CHECKC: store ptr ptrauth (ptr @knr2, i32 0, i64 18983) - // CHECKC: call void {{.*}}() [ "ptrauth"(i32 0, i64 18983) ] + // CHECKC: store ptr ptrauth (ptr @knr2, [i64 0, i64 18983, i64 0]) + // CHECKC: call void {{.*}}() [ "ptrauth"(i64 0, i64 18983, i64 0) ] void knr2(int); void (*p2)(int) = knr2; p2(0); - // CHECKC: store ptr ptrauth (ptr @knr2, i32 0, i64 2712) - // CHECKC: call void {{.*}}(i32 noundef 0) [ "ptrauth"(i32 0, i64 2712) ] + // CHECKC: store ptr ptrauth (ptr @knr2, [i64 0, i64 2712, i64 0]) + // CHECKC: call void {{.*}}(i32 noundef 0) [ "ptrauth"(i64 0, i64 2712, i64 0) ] } #endif diff --git a/clang/test/CodeGen/ptrauth-function.c b/clang/test/CodeGen/ptrauth-function.c index eea3f7ed73747..31112f204b8d2 100644 --- a/clang/test/CodeGen/ptrauth-function.c +++ b/clang/test/CodeGen/ptrauth-function.c @@ -14,7 +14,7 @@ void test_indirect_call(void (*fp(void))) { // CHECK: %[[FP_ADDR:.*]] = alloca ptr, align 8 // CHECK: store ptr %[[FP]], ptr %[[FP_ADDR]], align 8 // CHECK: %[[V0:.*]] = load ptr, ptr %[[FP_ADDR]], align 8 - // CHECK: %[[CALL:.*]] = call ptr %[[V0]]() [ "ptrauth"(i32 0, i64 0) ] + // CHECK: %[[CALL:.*]] = call ptr %[[V0]]() [ "ptrauth"(i64 0, i64 0, i64 0) ] fp(); } diff --git a/clang/test/CodeGen/ptrauth-in-c-struct.c b/clang/test/CodeGen/ptrauth-in-c-struct.c index c74be17b4c837..ed928bb8214b7 100644 --- a/clang/test/CodeGen/ptrauth-in-c-struct.c +++ b/clang/test/CodeGen/ptrauth-in-c-struct.c @@ -55,11 +55,9 @@ int g0; // CHECK: %[[V9:.*]] = getelementptr inbounds i8, ptr %[[V1]], i64 8 // CHECK: %[[V11:.*]] = load ptr, ptr %[[V9]], align 8 // CHECK: %[[V12:.*]] = ptrtoint ptr %[[V9]] to i64 -// CHECK: %[[V13:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V12]], i64 50) // CHECK: %[[V14:.*]] = ptrtoint ptr %[[V6]] to i64 -// CHECK: %[[V15:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V14]], i64 50) // CHECK: %[[V17:.*]] = ptrtoint ptr %[[V11]] to i64 -// CHECK: %[[V18:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V17]], i32 1, i64 %[[V13]], i32 1, i64 %[[V15]]) +// CHECK: %[[V18:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V17]]) [ "ptrauth"(i64 1, i64 50, i64 %[[V12]]), "ptrauth"(i64 1, i64 50, i64 %[[V14]]) ] void test_copy_constructor_SA(SA *s) { SA t = *s; @@ -79,11 +77,9 @@ void test_copy_constructor_SA(SA *s) { // CHECK: %[[V9:.*]] = getelementptr inbounds i8, ptr %[[V1]], i64 8 // CHECK: %[[V11:.*]] = load ptr, ptr %[[V9]], align 8 // CHECK: %[[V12:.*]] = ptrtoint ptr %[[V9]] to i64 -// CHECK: %[[V13:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V12]], i64 30) // CHECK: %[[V14:.*]] = ptrtoint ptr %[[V6]] to i64 -// CHECK: %[[V15:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V14]], i64 30) // CHECK: %[[V17:.*]] = ptrtoint ptr %[[V11]] to i64 -// CHECK: %[[V18:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V17]], i32 2, i64 %[[V13]], i32 2, i64 %[[V15]]) +// CHECK: %[[V18:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V17]]) [ "ptrauth"(i64 2, i64 30, i64 %[[V12]]), "ptrauth"(i64 2, i64 30, i64 %[[V14]]) ] void test_copy_constructor_SA2(SA2 *s) { SA2 t = *s; @@ -168,14 +164,12 @@ void test_parameter_SI(SI a) { // CHECK-LABEL: define void @test_array( // CHECK: %[[F1:.*]] = getelementptr inbounds nuw %[[STRUCT_SA]], ptr %{{.*}}, i32 0, i32 1 // CHECK: %[[V0:.*]] = ptrtoint ptr %[[F1]] to i64 -// CHECK: %[[V1:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V0]], i64 50) -// CHECK: %[[V2:.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @g0 to i64), i32 1, i64 %[[V1]]) +// CHECK: %[[V2:.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @g0 to i64)) [ "ptrauth"(i64 1, i64 50, i64 %[[V0]]) ] // CHECK: %[[V3:.*]] = inttoptr i64 %[[V2]] to ptr // CHECK: store ptr %[[V3]], ptr %[[F1]], align 8 // CHECK: %[[F12:.*]] = getelementptr inbounds nuw %[[STRUCT_SA]], ptr %{{.*}}, i32 0, i32 1 // CHECK: %[[V4:.*]] = ptrtoint ptr %[[F12]] to i64 -// CHECK: %[[V5:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V4]], i64 50) -// CHECK: %[[V6:.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @g0 to i64), i32 1, i64 %[[V5]]) +// CHECK: %[[V6:.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @g0 to i64)) [ "ptrauth"(i64 1, i64 50, i64 %[[V4]]) ] // CHECK: %[[V7:.*]] = inttoptr i64 %[[V6]] to ptr // CHECK: store ptr %[[V7]], ptr %[[F12]], align 8 diff --git a/clang/test/CodeGen/ptrauth-init-fini.c b/clang/test/CodeGen/ptrauth-init-fini.c index 1e8953961d64e..834e17fd4f9d4 100644 --- a/clang/test/CodeGen/ptrauth-init-fini.c +++ b/clang/test/CodeGen/ptrauth-init-fini.c @@ -15,11 +15,11 @@ // RUN: %clang_cc1 -triple aarch64-elf -target-feature +pauth -fptrauth-init-fini \ // RUN: -emit-llvm %s -o - | FileCheck --check-prefix=UNSIGNED %s -// SIGNED: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @foo, i32 0, i64 55764), ptr null }] -// SIGNED: @llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @bar, i32 0, i64 55764), ptr null }] +// SIGNED: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @foo, [i64 0, i64 55764, i64 0]), ptr null }] +// SIGNED: @llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @bar, [i64 0, i64 55764, i64 0]), ptr null }] -// ADDRDISC: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @foo, i32 0, i64 55764, ptr inttoptr (i64 1 to ptr)), ptr null }] -// ADDRDISC: @llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @bar, i32 0, i64 55764, ptr inttoptr (i64 1 to ptr)), ptr null }] +// ADDRDISC: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @foo, [i64 0, i64 55764, i64 ptrtoint (ptr inttoptr (i64 1 to ptr) to i64)]), ptr null }] +// ADDRDISC: @llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @bar, [i64 0, i64 55764, i64 ptrtoint (ptr inttoptr (i64 1 to ptr) to i64)]), ptr null }] // UNSIGNED: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @foo, ptr null }] // UNSIGNED: @llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @bar, ptr null }] diff --git a/clang/test/CodeGen/ptrauth-intrinsic-sign-constant.c b/clang/test/CodeGen/ptrauth-intrinsic-sign-constant.c index bab39897b9427..5448692813ec3 100644 --- a/clang/test/CodeGen/ptrauth-intrinsic-sign-constant.c +++ b/clang/test/CodeGen/ptrauth-intrinsic-sign-constant.c @@ -3,16 +3,16 @@ extern int external; -// CHECK: @ptr1 = global ptr ptrauth (ptr @external, i32 0) +// CHECK: @ptr1 = global ptr ptrauth (ptr @external, [i64 0, i64 0, i64 0]) void *ptr1 = __builtin_ptrauth_sign_constant(&external, 0, 0); -// CHECK: @ptr2 = global ptr ptrauth (ptr @external, i32 0, i64 1234) +// CHECK: @ptr2 = global ptr ptrauth (ptr @external, [i64 0, i64 1234, i64 0]) void *ptr2 = __builtin_ptrauth_sign_constant(&external, 0, 1234); -// CHECK: @ptr3 = global ptr ptrauth (ptr @external, i32 2, i64 0, ptr @ptr3) +// CHECK: @ptr3 = global ptr ptrauth (ptr @external, [i64 2, i64 0, i64 ptrtoint (ptr @ptr3 to i64)]) void *ptr3 = __builtin_ptrauth_sign_constant(&external, 2, &ptr3); -// CHECK: @ptr4 = global ptr ptrauth (ptr @external, i32 2, i64 26, ptr @ptr4) +// CHECK: @ptr4 = global ptr ptrauth (ptr @external, [i64 2, i64 26, i64 ptrtoint (ptr @ptr4 to i64)]) void *ptr4 = __builtin_ptrauth_sign_constant(&external, 2, __builtin_ptrauth_blend_discriminator(&ptr4, 26)); // CHECK: @ptr5 = global ptr null @@ -21,10 +21,10 @@ void *ptr5; void test_sign_constant_code() { // CHECK-LABEL: define {{.*}}void @test_sign_constant_code() // CHECK-NEXT: entry: -// CHECK-NEXT: store ptr ptrauth (ptr @external, i32 0), ptr @ptr1, align 8 -// CHECK-NEXT: store ptr ptrauth (ptr @external, i32 2, i64 1234), ptr @ptr2, align 8 -// CHECK-NEXT: store ptr ptrauth (ptr @external, i32 2, i64 0, ptr @ptr3), ptr @ptr3, align 8 -// CHECK-NEXT: store ptr ptrauth (ptr @external, i32 2, i64 1234, ptr @ptr4), ptr @ptr4, align 8 +// CHECK-NEXT: store ptr ptrauth (ptr @external, [i64 0, i64 0, i64 0]), ptr @ptr1, align 8 +// CHECK-NEXT: store ptr ptrauth (ptr @external, [i64 2, i64 1234, i64 0]), ptr @ptr2, align 8 +// CHECK-NEXT: store ptr ptrauth (ptr @external, [i64 2, i64 0, i64 ptrtoint (ptr @ptr3 to i64)]), ptr @ptr3, align 8 +// CHECK-NEXT: store ptr ptrauth (ptr @external, [i64 2, i64 1234, i64 ptrtoint (ptr @ptr4 to i64)]), ptr @ptr4, align 8 // CHECK-NEXT: ret void ptr1 = __builtin_ptrauth_sign_constant(&external, 0, 0); ptr2 = __builtin_ptrauth_sign_constant(&external, 2, 1234); diff --git a/clang/test/CodeGen/ptrauth-intrinsics.c b/clang/test/CodeGen/ptrauth-intrinsics.c index 50bf1898e4b37..c4246ac16fc63 100644 --- a/clang/test/CodeGen/ptrauth-intrinsics.c +++ b/clang/test/CodeGen/ptrauth-intrinsics.c @@ -12,10 +12,10 @@ long signature; // CHECK-LABEL: define {{.*}}void @test_auth() void test_auth() { // CHECK: [[PTR:%.*]] = load ptr, ptr @fnptr, - // CHECK-NEXT: [[DISC0:%.*]] = load ptr, ptr @ptr_discriminator, // CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[PTR]] to i64 + // CHECK-NEXT: [[DISC0:%.*]] = load ptr, ptr @ptr_discriminator, // CHECK-NEXT: [[DISC:%.*]] = ptrtoint ptr [[DISC0]] to i64 - // CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]], i32 0, i64 [[DISC]]) + // CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]]) [ "ptrauth"(i64 0, i64 0, i64 [[DISC]]) ] // CHECK-NEXT: [[RESULT:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: store ptr [[RESULT]], ptr @fnptr, fnptr = __builtin_ptrauth_auth(fnptr, 0, ptr_discriminator); @@ -25,7 +25,7 @@ void test_auth() { void test_strip() { // CHECK: [[PTR:%.*]] = load ptr, ptr @fnptr, // CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[PTR]] to i64 - // CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.strip(i64 [[T0]], i32 0) + // CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.strip(i64 [[T0]]) [ "ptrauth"(i64 0) ] // CHECK-NEXT: [[RESULT:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: store ptr [[RESULT]], ptr @fnptr, fnptr = __builtin_ptrauth_strip(fnptr, 0); @@ -34,10 +34,10 @@ void test_strip() { // CHECK-LABEL: define {{.*}}void @test_sign_unauthenticated() void test_sign_unauthenticated() { // CHECK: [[PTR:%.*]] = load ptr, ptr @fnptr, - // CHECK-NEXT: [[DISC0:%.*]] = load ptr, ptr @ptr_discriminator, // CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[PTR]] to i64 + // CHECK-NEXT: [[DISC0:%.*]] = load ptr, ptr @ptr_discriminator, // CHECK-NEXT: [[DISC:%.*]] = ptrtoint ptr [[DISC0]] to i64 - // CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[T0]], i32 0, i64 [[DISC]]) + // CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[T0]]) [ "ptrauth"(i64 0, i64 0, i64 [[DISC]]) ] // CHECK-NEXT: [[RESULT:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: store ptr [[RESULT]], ptr @fnptr, fnptr = __builtin_ptrauth_sign_unauthenticated(fnptr, 0, ptr_discriminator); @@ -46,30 +46,60 @@ void test_sign_unauthenticated() { // CHECK-LABEL: define {{.*}}void @test_auth_and_resign() void test_auth_and_resign() { // CHECK: [[PTR:%.*]] = load ptr, ptr @fnptr, - // CHECK-NEXT: [[DISC0:%.*]] = load ptr, ptr @ptr_discriminator, // CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[PTR]] to i64 + // CHECK-NEXT: [[DISC0:%.*]] = load ptr, ptr @ptr_discriminator, // CHECK-NEXT: [[DISC:%.*]] = ptrtoint ptr [[DISC0]] to i64 - // CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 0, i64 [[DISC]], i32 3, i64 15) + // CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 0, i64 0, i64 [[DISC]]), "ptrauth"(i64 3, i64 15, i64 0) ] // CHECK-NEXT: [[RESULT:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: store ptr [[RESULT]], ptr @fnptr, fnptr = __builtin_ptrauth_auth_and_resign(fnptr, 0, ptr_discriminator, 3, 15); } -// CHECK-LABEL: define {{.*}}void @test_blend_discriminator() -void test_blend_discriminator() { - // CHECK: [[PTR:%.*]] = load ptr, ptr @fnptr, - // CHECK-NEXT: [[DISC:%.*]] = load i64, ptr @int_discriminator, - // CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[PTR]] to i64 - // CHECK-NEXT: [[RESULT:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 [[DISC]]) - // CHECK-NEXT: store i64 [[RESULT]], ptr @int_discriminator, - int_discriminator = __builtin_ptrauth_blend_discriminator(fnptr, int_discriminator); +// CHECK-LABEL: define {{.*}}void @test_auth_blend_discriminator() +void test_auth_blend_discriminator() { + // CHECK: [[FNPTR:%.*]] = load ptr, ptr @fnptr, + // CHECK-NEXT: [[CAST_FNPTR:%.*]] = ptrtoint ptr [[FNPTR]] to i64 + // CHECK: [[DISC:%.*]] = load i64, ptr @int_discriminator, + // CHECK-NEXT: [[PTR:%.*]] = load ptr, ptr @ptr_discriminator, + // CHECK-NEXT: [[CAST_PTR:%.*]] = ptrtoint ptr [[PTR]] to i64 + // CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[CAST_FNPTR]]) [ "ptrauth"(i64 0, i64 [[DISC]], i64 [[CAST_PTR]]) ] + // CHECK-NEXT: [[RESULT:%.*]] = inttoptr i64 [[T1]] to ptr + // CHECK-NEXT: store ptr [[RESULT]], ptr @fnptr, + fnptr = __builtin_ptrauth_auth(fnptr, 0, __builtin_ptrauth_blend_discriminator(ptr_discriminator, int_discriminator)); +} + +// CHECK-LABEL: define {{.*}}void @test_sign_blend_discriminator() +void test_sign_blend_discriminator() { + // CHECK: [[FNPTR:%.*]] = load ptr, ptr @fnptr, + // CHECK-NEXT: [[CAST_FNPTR:%.*]] = ptrtoint ptr [[FNPTR]] to i64 + // CHECK: [[DISC:%.*]] = load i64, ptr @int_discriminator, + // CHECK-NEXT: [[PTR:%.*]] = load ptr, ptr @ptr_discriminator, + // CHECK-NEXT: [[CAST_PTR:%.*]] = ptrtoint ptr [[PTR]] to i64 + // CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[CAST_FNPTR]]) [ "ptrauth"(i64 0, i64 [[DISC]], i64 [[CAST_PTR]]) ] + // CHECK-NEXT: [[RESULT:%.*]] = inttoptr i64 [[T1]] to ptr + // CHECK-NEXT: store ptr [[RESULT]], ptr @fnptr, + fnptr = __builtin_ptrauth_sign_unauthenticated(fnptr, 0, __builtin_ptrauth_blend_discriminator(ptr_discriminator, int_discriminator)); +} + +// CHECK-LABEL: define {{.*}}void @test_resign_blend_discriminator() +void test_resign_blend_discriminator() { + // CHECK: [[FNPTR:%.*]] = load ptr, ptr @fnptr, + // CHECK-NEXT: [[CAST_FNPTR:%.*]] = ptrtoint ptr [[FNPTR]] to i64 + // CHECK: [[DISC:%.*]] = load i64, ptr @int_discriminator, + // CHECK-NEXT: [[PTR:%.*]] = load ptr, ptr @ptr_discriminator, + // CHECK-NEXT: [[CAST_PTR:%.*]] = ptrtoint ptr [[PTR]] to i64 + // CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[CAST_FNPTR]]) [ "ptrauth"(i64 0, i64 [[DISC]], i64 [[CAST_PTR]]), "ptrauth"(i64 1, i64 1234, i64 ptrtoint (ptr @int_discriminator to i64)) ] + // CHECK-NEXT: [[RESULT:%.*]] = inttoptr i64 [[T1]] to ptr + // CHECK-NEXT: store ptr [[RESULT]], ptr @fnptr, + fnptr = __builtin_ptrauth_auth_and_resign(fnptr, 0, __builtin_ptrauth_blend_discriminator(ptr_discriminator, int_discriminator), + 1, __builtin_ptrauth_blend_discriminator(&int_discriminator, 1234)); } // CHECK-LABEL: define {{.*}}void @test_sign_generic_data() void test_sign_generic_data() { // CHECK: [[PTR:%.*]] = load ptr, ptr @fnptr, - // CHECK-NEXT: [[DISC0:%.*]] = load ptr, ptr @ptr_discriminator, // CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[PTR]] to i64 + // CHECK-NEXT: [[DISC0:%.*]] = load ptr, ptr @ptr_discriminator, // CHECK-NEXT: [[DISC:%.*]] = ptrtoint ptr [[DISC0]] to i64 // CHECK-NEXT: [[RESULT:%.*]] = call i64 @llvm.ptrauth.sign.generic(i64 [[T0]], i64 [[DISC]]) // CHECK-NEXT: store i64 [[RESULT]], ptr @signature, diff --git a/clang/test/CodeGen/ptrauth-qualifier-blocks.c b/clang/test/CodeGen/ptrauth-qualifier-blocks.c index f460da205cac7..119f283347d1e 100644 --- a/clang/test/CodeGen/ptrauth-qualifier-blocks.c +++ b/clang/test/CodeGen/ptrauth-qualifier-blocks.c @@ -20,7 +20,7 @@ void test_block_nonaddress_capture() { use_block(^{ return ptr->value; }); } // CHECK-LABEL: define internal i32 @__test_block_nonaddress_capture_block_invoke -// CHECK: call i64 @llvm.ptrauth.auth(i64 {{%.*}}, i32 1, i64 15) +// CHECK: call i64 @llvm.ptrauth.auth(i64 {{%.*}}) [ "ptrauth"(i64 1, i64 15, i64 0) ] // CHECK-LABEL: define void @test_block_address_capture( void test_block_address_capture() { @@ -30,14 +30,12 @@ void test_block_address_capture() { // CHECK: store i32 1107296256, ptr // CHECK: [[CAPTURE:%.*]] = getelementptr inbounds {{.*}} [[BLOCK]], i32 0, i32 5 // CHECK: [[LOAD:%.*]] = load ptr, ptr [[VAR]], - // CHECK: [[T0:%.*]] = ptrtoint ptr [[VAR]] to i64 - // CHECK: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 30) - // CHECK: [[T0:%.*]] = ptrtoint ptr [[CAPTURE]] to i64 - // CHECK: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 30) + // CHECK: [[T01:%.*]] = ptrtoint ptr [[VAR]] to i64 + // CHECK: [[T02:%.*]] = ptrtoint ptr [[CAPTURE]] to i64 // CHECK: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK: br i1 [[T0]] // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 - // CHECK: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]]) + // CHECK: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 30, i64 [[T01]]), "ptrauth"(i64 1, i64 30, i64 [[T02]]) ] // CHECK: [[T2:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK: [[T0:%.*]] = phi // CHECK: store ptr [[T0]], ptr [[CAPTURE]] @@ -45,20 +43,18 @@ void test_block_address_capture() { use_block(^{ return ptr->value; }); } // CHECK-LABEL: define internal i32 @__test_block_address_capture_block_invoke -// CHECK: call i64 @llvm.ptrauth.auth(i64 {{%.*}}, i32 1, i64 {{%.*}}) +// CHECK: call i64 @llvm.ptrauth.auth(i64 {{%.*}}) [ "ptrauth"(i64 1, i64 30, i64 {{.*}}) ] // CHECK: linkonce_odr hidden void @__copy_helper_block_8_32p1d30( // CHECK: [[OLDSLOT:%.*]] = getelementptr inbounds {{.*}} {{.*}}, i32 0, i32 5 // CHECK: [[NEWSLOT:%.*]] = getelementptr inbounds {{.*}} {{.*}}, i32 0, i32 5 // CHECK: [[LOAD:%.*]] = load ptr, ptr [[OLDSLOT]], -// CHECK: [[T0:%.*]] = ptrtoint ptr [[OLDSLOT]] to i64 -// CHECK: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 30) -// CHECK: [[T0:%.*]] = ptrtoint ptr [[NEWSLOT]] to i64 -// CHECK: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 30) +// CHECK: [[T01:%.*]] = ptrtoint ptr [[OLDSLOT]] to i64 +// CHECK: [[T02:%.*]] = ptrtoint ptr [[NEWSLOT]] to i64 // CHECK: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK: br i1 [[T0]] // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]]) +// CHECK: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 30, i64 [[T01]]), "ptrauth"(i64 1, i64 30, i64 [[T02]]) ] // CHECK: [[T2:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK: [[T0:%.*]] = phi // CHECK: store ptr [[T0]], ptr [[NEWSLOT]] @@ -83,12 +79,12 @@ void test_block_address_byref_capture() { // CHECK: store i32 48, // CHECK: [[COPY_HELPER_FIELD:%.*]] = getelementptr inbounds nuw [[BYREF_T]], ptr [[BYREF]], i32 0, i32 4 // CHECK: [[T0:%.*]] = ptrtoint ptr [[COPY_HELPER_FIELD]] to i64 - // CHECK: [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @__Block_byref_object_copy_ to i64), i32 0, i64 [[T0]]) + // CHECK: [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @__Block_byref_object_copy_ to i64)) [ "ptrauth"(i64 0, i64 0, i64 [[T0]]) ] // CHECK: [[T2:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK: store ptr [[T2]], ptr [[COPY_HELPER_FIELD]], align // CHECK: [[DISPOSE_HELPER_FIELD:%.*]] = getelementptr inbounds nuw [[BYREF_T]], ptr [[BYREF]], i32 0, i32 5 // CHECK: [[T0:%.*]] = ptrtoint ptr [[DISPOSE_HELPER_FIELD]] to i64 - // CHECK: [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @__Block_byref_object_dispose_ to i64), i32 0, i64 [[T0]]) + // CHECK: [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @__Block_byref_object_dispose_ to i64)) [ "ptrauth"(i64 0, i64 0, i64 [[T0]]) ] // CHECK: [[T2:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK: store ptr [[T2]], ptr [[DISPOSE_HELPER_FIELD]], align // flags - copy/dispose required @@ -100,14 +96,12 @@ void test_block_address_byref_capture() { // CHECK: [[NEWSLOT:%.*]] = getelementptr inbounds {{.*}} {{.*}}, i32 0, i32 6 // CHECK: [[OLDSLOT:%.*]] = getelementptr inbounds {{.*}} {{.*}}, i32 0, i32 6 // CHECK: [[LOAD:%.*]] = load ptr, ptr [[OLDSLOT]], -// CHECK: [[T0:%.*]] = ptrtoint ptr [[OLDSLOT]] to i64 -// CHECK: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 60) -// CHECK: [[T0:%.*]] = ptrtoint ptr [[NEWSLOT]] to i64 -// CHECK: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 60) +// CHECK: [[T01:%.*]] = ptrtoint ptr [[OLDSLOT]] to i64 +// CHECK: [[T02:%.*]] = ptrtoint ptr [[NEWSLOT]] to i64 // CHECK: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK: br i1 [[T0]] // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]]) +// CHECK: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 60, i64 [[T01]]), "ptrauth"(i64 1, i64 60, i64 [[T02]]) ] // CHECK: [[T2:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK: [[T0:%.*]] = phi // CHECK: store ptr [[T0]], ptr [[NEWSLOT]] diff --git a/clang/test/CodeGen/ptrauth-qualifier-const-init.c b/clang/test/CodeGen/ptrauth-qualifier-const-init.c index 174f328628f19..b985a13e084af 100644 --- a/clang/test/CodeGen/ptrauth-qualifier-const-init.c +++ b/clang/test/CodeGen/ptrauth-qualifier-const-init.c @@ -4,10 +4,10 @@ // Constant initializers for data pointers. extern int external_int; -// CHECK: @g1 = global ptr ptrauth (ptr @external_int, i32 1, i64 56) +// CHECK: @g1 = global ptr ptrauth (ptr @external_int, [i64 1, i64 56, i64 0]) int * __ptrauth(1,0,56) g1 = &external_int; -// CHECK: @g2 = global ptr ptrauth (ptr @external_int, i32 1, i64 1272, ptr @g2) +// CHECK: @g2 = global ptr ptrauth (ptr @external_int, [i64 1, i64 1272, i64 ptrtoint (ptr @g2 to i64)]) int * __ptrauth(1,1,1272) g2 = &external_int; // CHECK: @g3 = global ptr null @@ -18,9 +18,9 @@ int * __ptrauth(1,1,871) g3 = 0; int * __ptrauth(1,1,1902) g4 = (int*) 1230; // CHECK: @ga = global [3 x ptr] [ -// CHECK-SAME: ptr ptrauth (ptr @external_int, i32 1, i64 712, ptr @ga), -// CHECK-SAME: ptr ptrauth (ptr @external_int, i32 1, i64 712, ptr getelementptr inbounds ([3 x ptr], ptr @ga, i32 0, i32 1)), -// CHECK-SAME: ptr ptrauth (ptr @external_int, i32 1, i64 712, ptr getelementptr inbounds ([3 x ptr], ptr @ga, i32 0, i32 2))] +// CHECK-SAME: ptr ptrauth (ptr @external_int, [i64 1, i64 712, i64 ptrtoint (ptr @ga to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @external_int, [i64 1, i64 712, i64 ptrtoint (ptr getelementptr inbounds ([3 x ptr], ptr @ga, i32 0, i32 1) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @external_int, [i64 1, i64 712, i64 ptrtoint (ptr getelementptr inbounds ([3 x ptr], ptr @ga, i32 0, i32 2) to i64)])] int * __ptrauth(1,1,712) ga[3] = { &external_int, &external_int, &external_int }; struct A { @@ -30,9 +30,9 @@ struct A { }; // CHECK: @gs1 = global %struct.A { -// CHECK-SAME: ptr ptrauth (ptr @external_int, i32 1, i64 431), -// CHECK-SAME: ptr ptrauth (ptr @external_int, i32 1, i64 9182), -// CHECK-SAME: ptr ptrauth (ptr @external_int, i32 1, i64 783) } +// CHECK-SAME: ptr ptrauth (ptr @external_int, [i64 1, i64 431, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr @external_int, [i64 1, i64 9182, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr @external_int, [i64 1, i64 783, i64 0]) } struct A gs1 = { &external_int, &external_int, &external_int }; struct B { @@ -42,25 +42,25 @@ struct B { }; // CHECK: @gs2 = global %struct.B { -// CHECK-SAME: ptr ptrauth (ptr @external_int, i32 1, i64 1276, ptr @gs2), -// CHECK-SAME: ptr ptrauth (ptr @external_int, i32 1, i64 23674, ptr getelementptr inbounds (%struct.B, ptr @gs2, i32 0, i32 1)), -// CHECK-SAME: ptr ptrauth (ptr @external_int, i32 1, i64 163, ptr getelementptr inbounds (%struct.B, ptr @gs2, i32 0, i32 2)) } +// CHECK-SAME: ptr ptrauth (ptr @external_int, [i64 1, i64 1276, i64 ptrtoint (ptr @gs2 to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @external_int, [i64 1, i64 23674, i64 ptrtoint (ptr getelementptr inbounds (%struct.B, ptr @gs2, i32 0, i32 1) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @external_int, [i64 1, i64 163, i64 ptrtoint (ptr getelementptr inbounds (%struct.B, ptr @gs2, i32 0, i32 2) to i64)]) } struct B gs2 = { &external_int, &external_int, &external_int }; // Constant initializers for function pointers. extern void external_function(void); typedef void (*fpt)(void); -// CHECK: @f1 = global ptr ptrauth (ptr @external_function, i32 1, i64 56) +// CHECK: @f1 = global ptr ptrauth (ptr @external_function, [i64 1, i64 56, i64 0]) fpt __ptrauth(1,0,56) f1 = &external_function; -// CHECK: @f2 = global ptr ptrauth (ptr @external_function, i32 1, i64 1272, ptr @f2) +// CHECK: @f2 = global ptr ptrauth (ptr @external_function, [i64 1, i64 1272, i64 ptrtoint (ptr @f2 to i64)]) fpt __ptrauth(1,1,1272) f2 = &external_function; // CHECK: @fa = global [3 x ptr] [ -// CHECK-SAME: ptr ptrauth (ptr @external_function, i32 1, i64 712, ptr @fa), -// CHECK-SAME: ptr ptrauth (ptr @external_function, i32 1, i64 712, ptr getelementptr inbounds ([3 x ptr], ptr @fa, i32 0, i32 1)), -// CHECK-SAME: ptr ptrauth (ptr @external_function, i32 1, i64 712, ptr getelementptr inbounds ([3 x ptr], ptr @fa, i32 0, i32 2))] +// CHECK-SAME: ptr ptrauth (ptr @external_function, [i64 1, i64 712, i64 ptrtoint (ptr @fa to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @external_function, [i64 1, i64 712, i64 ptrtoint (ptr getelementptr inbounds ([3 x ptr], ptr @fa, i32 0, i32 1) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @external_function, [i64 1, i64 712, i64 ptrtoint (ptr getelementptr inbounds ([3 x ptr], ptr @fa, i32 0, i32 2) to i64)])] fpt __ptrauth(1,1,712) fa[3] = { &external_function, &external_function, &external_function }; struct C { @@ -69,9 +69,9 @@ struct C { fpt __ptrauth(1,0,783) f2; }; // CHECK: @fs1 = global %struct.C { -// CHECK-SAME: ptr ptrauth (ptr @external_function, i32 1, i64 431), -// CHECK-SAME: ptr ptrauth (ptr @external_function, i32 1, i64 9182), -// CHECK-SAME: ptr ptrauth (ptr @external_function, i32 1, i64 783) } +// CHECK-SAME: ptr ptrauth (ptr @external_function, [i64 1, i64 431, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr @external_function, [i64 1, i64 9182, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr @external_function, [i64 1, i64 783, i64 0]) } struct C fs1 = { &external_function, &external_function, &external_function }; struct D { @@ -80,7 +80,7 @@ struct D { fpt __ptrauth(1,1,163) f2; }; // CHECK: @fs2 = global %struct.D { -// CHECK-SAME: ptr ptrauth (ptr @external_function, i32 1, i64 1276, ptr @fs2), -// CHECK-SAME: ptr ptrauth (ptr @external_function, i32 1, i64 23674, ptr getelementptr inbounds (%struct.D, ptr @fs2, i32 0, i32 1)), -// CHECK-SAME: ptr ptrauth (ptr @external_function, i32 1, i64 163, ptr getelementptr inbounds (%struct.D, ptr @fs2, i32 0, i32 2)) } +// CHECK-SAME: ptr ptrauth (ptr @external_function, [i64 1, i64 1276, i64 ptrtoint (ptr @fs2 to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @external_function, [i64 1, i64 23674, i64 ptrtoint (ptr getelementptr inbounds (%struct.D, ptr @fs2, i32 0, i32 1) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @external_function, [i64 1, i64 163, i64 ptrtoint (ptr getelementptr inbounds (%struct.D, ptr @fs2, i32 0, i32 2) to i64)]) } struct D fs2 = { &external_function, &external_function, &external_function }; diff --git a/clang/test/CodeGen/ptrauth-qualifier-function.c b/clang/test/CodeGen/ptrauth-qualifier-function.c index cd25b77a01548..fe515da646b76 100644 --- a/clang/test/CodeGen/ptrauth-qualifier-function.c +++ b/clang/test/CodeGen/ptrauth-qualifier-function.c @@ -26,7 +26,7 @@ void test_assign_to_qualified() { // TYPE: [[RESIGN1]]: // TYPE-NEXT: [[FPTR2:%.*]] = ptrtoint ptr [[FPTR]] to i64 - // TYPE-NEXT: [[FPTR4:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[FPTR2]], i32 0, i64 18983, i32 0, i64 2712) + // TYPE-NEXT: [[FPTR4:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[FPTR2]]) [ "ptrauth"(i64 0, i64 18983, i64 0), "ptrauth"(i64 0, i64 2712, i64 0) ] // TYPE-NEXT: [[FPTR5:%.*]] = inttoptr i64 [[FPTR4]] to ptr // TYPE-NEXT: br label %[[JOIN1]] @@ -37,9 +37,9 @@ void test_assign_to_qualified() { // CHECK: [[RESIGN2]]: // TYPE-NEXT: [[FPTR7:%.*]] = ptrtoint ptr [[FPTR6]] to i64 - // TYPE-NEXT: [[FPTR8:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[FPTR7]], i32 0, i64 2712, i32 0, i64 42) + // TYPE-NEXT: [[FPTR8:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[FPTR7]]) [ "ptrauth"(i64 0, i64 2712, i64 0), "ptrauth"(i64 0, i64 42, i64 0) ] // ZERO-NEXT: [[FPTR7:%.*]] = ptrtoint ptr [[FPTR]] to i64 - // ZERO-NEXT: [[FPTR8:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[FPTR7]], i32 0, i64 0, i32 0, i64 42) + // ZERO-NEXT: [[FPTR8:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[FPTR7]]) [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 0, i64 42, i64 0) ] // CHECK-NEXT: [[FPTR9:%.*]] = inttoptr i64 [[FPTR8]] to ptr // CHECK-NEXT: br label %[[JOIN2]] @@ -61,7 +61,7 @@ void test_assign_from_qualified() { // TYPE: [[RESIGN1]]: // TYPE-NEXT: [[FPTR1:%.*]] = ptrtoint ptr [[FPTR]] to i64 - // TYPE-NEXT: [[FPTR2:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[FPTR1]], i32 0, i64 42, i32 0, i64 2712) + // TYPE-NEXT: [[FPTR2:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[FPTR1]]) [ "ptrauth"(i64 0, i64 42, i64 0), "ptrauth"(i64 0, i64 2712, i64 0) ] // TYPE-NEXT: [[FPTR3:%.*]] = inttoptr i64 [[FPTR2]] to ptr // TYPE-NEXT: br label %[[JOIN1]] @@ -72,9 +72,9 @@ void test_assign_from_qualified() { // CHECK: [[RESIGN2]]: // TYPE-NEXT: [[FPTR6:%.*]] = ptrtoint ptr [[FPTR4]] to i64 - // TYPE-NEXT: [[FPTR7:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[FPTR6]], i32 0, i64 2712, i32 0, i64 18983) + // TYPE-NEXT: [[FPTR7:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[FPTR6]]) [ "ptrauth"(i64 0, i64 2712, i64 0), "ptrauth"(i64 0, i64 18983, i64 0) ] // ZERO-NEXT: [[FPTR6:%.*]] = ptrtoint ptr [[FPTR]] to i64 - // ZERO-NEXT: [[FPTR7:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[FPTR6]], i32 0, i64 42, i32 0, i64 0) + // ZERO-NEXT: [[FPTR7:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[FPTR6]]) [ "ptrauth"(i64 0, i64 42, i64 0), "ptrauth"(i64 0, i64 0, i64 0) ] // CHECK-NEXT: [[FPTR8:%.*]] = inttoptr i64 [[FPTR7]] to ptr // CHECK-NEXT: br label %[[JOIN2]] @@ -88,8 +88,8 @@ void test_assign_from_qualified() { void test_const_ptr_function_call(void) { f_const_ptr(1); - // TYPE: call void ptrauth (ptr @f, i32 0, i64 2712)(i32 noundef 1) [ "ptrauth"(i32 0, i64 2712) ] - // ZERO: call void ptrauth (ptr @f, i32 0)(i32 noundef 1) [ "ptrauth"(i32 0, i64 0) ] + // TYPE: call void ptrauth (ptr @f, [i64 0, i64 2712, i64 0])(i32 noundef 1) [ "ptrauth"(i64 0, i64 2712, i64 0) ] + // ZERO: call void ptrauth (ptr @f, [i64 0, i64 0, i64 0])(i32 noundef 1) [ "ptrauth"(i64 0, i64 0, i64 0) ] } #ifdef __cplusplus @@ -105,7 +105,7 @@ void (* const __ptrauth(0, 1, 43) &f_ref)(int) = f_const_ptr2; // CHECK-CXX: [[RESIGN_NONNULL]]: // CHECK-CXX: %[[V1:.*]] = ptrtoint ptr %[[CALL]] to i64 -// CHECK-CXX: %[[V2:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V1]], i32 0, i64 2712, i32 0, i64 42) +// CHECK-CXX: %[[V2:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V1]]) [ "ptrauth"(i64 0, i64 2712, i64 0), "ptrauth"(i64 0, i64 42, i64 0) ] // CHECK-CXX: %[[V3:.*]] = inttoptr i64 %[[V2]] to ptr // CHECK-CXX: br label %[[RESIGN_CONT]] @@ -116,13 +116,12 @@ void (* const __ptrauth(0, 1, 43) &f_ref)(int) = f_const_ptr2; // CHECK-CXX-LABEL: define {{.*}}internal void @__cxx_global_var_init.1() // CHECK-CXX: [[ENTRY:.*]]: // CHECK-CXX: %[[V0:.*]] = load ptr, ptr @f_const_ptr2, align 8 -// CHECK-CXX: %[[V1:.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @_ZGR5f_ref_ to i64), i64 43) // CHECK-CXX: %[[V2:.*]] = icmp ne ptr %[[V0]], null // CHECK-CXX: br i1 %[[V2]], label %[[RESIGN_NONNULL:.*]], label %[[RESIGN_CONT:.*]] // CHECK-CXX: [[RESIGN_NONNULL]]: // CHECK-CXX: %[[V3:.*]] = ptrtoint ptr %[[V0]] to i64 -// CHECK-CXX: %[[V4:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V3]], i32 0, i64 42, i32 0, i64 %[[V1]]) +// CHECK-CXX: %[[V4:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V3]]) [ "ptrauth"(i64 0, i64 42, i64 0), "ptrauth"(i64 0, i64 43, i64 ptrtoint (ptr @_ZGR5f_ref_ to i64)) ] // CHECK-CXX: %[[V5:.*]] = inttoptr i64 %[[V4]] to ptr // CHECK-CXX: br label %[[RESIGN_CONT]] @@ -138,8 +137,7 @@ void test_const_ptr_ref_function_call(void) { // CHECK-CXX: %[[V0:.*]] = load ptr, ptr @f_ref, align 8 // CHECK-CXX: %[[V1:.*]] = load ptr, ptr %[[V0]], align 8 // CHECK-CXX: %[[V2:.*]] = ptrtoint ptr %[[V0]] to i64 - // CHECK-CXX: %[[V3:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V2]], i64 43) - // CHECK-CXX: call void %[[V1]](i32 noundef 1) [ "ptrauth"(i32 0, i64 %[[V3]]) ] + // CHECK-CXX: call void %[[V1]](i32 noundef 1) [ "ptrauth"(i64 0, i64 43, i64 %[[V2]]) ] } } #endif diff --git a/clang/test/CodeGen/ptrauth-qualifier-loadstore.c b/clang/test/CodeGen/ptrauth-qualifier-loadstore.c index db259ed950fec..382730935b137 100644 --- a/clang/test/CodeGen/ptrauth-qualifier-loadstore.c +++ b/clang/test/CodeGen/ptrauth-qualifier-loadstore.c @@ -26,11 +26,11 @@ extern void use_upf(func_t *ptr); // CHECK-LABEL: define {{.*}}void @test_store_data_i_constant() void test_store_data_i_constant() { // CHECK: [[V:%.*]] = alloca ptr, -// CHECK-NEXT: [[SIGN:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @external_int to i64), i32 1, i64 50) +// CHECK-NEXT: [[SIGN:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @external_int to i64)) [ "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[T0:%.*]] = inttoptr i64 [[SIGN]] to ptr // CHECK-NEXT: store ptr [[T0]], ptr [[V]], int * IQ iqpi = &external_int; -// CHECK-NEXT: [[T0:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @external_int to i64), i32 1, i64 50) +// CHECK-NEXT: [[T0:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @external_int to i64)) [ "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T0]] to ptr // CHECK-NEXT: store ptr [[SIGNED]], ptr [[V]], // CHECK-NEXT: ret void @@ -44,7 +44,7 @@ void test_store_data_iu() { // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[T0]], i32 1, i64 50) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -54,7 +54,7 @@ void test_store_data_iu() { // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[T0]], i32 1, i64 50) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -66,33 +66,30 @@ void test_store_data_iu() { void test_store_data_ia() { // CHECK: [[V:%.*]] = alloca ptr, // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpi, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50) // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 50) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpi to i64)), "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] // CHECK-NEXT: store ptr [[T0]], ptr [[V]], int * IQ iqpi = global_aqpi; // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpi, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50) // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 50) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpi to i64)), "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] // CHECK-NEXT: store ptr [[T0]], ptr [[V]], iqpi = global_aqpi; // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpi, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50) // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 50) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpi to i64)), "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[RESULT:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -100,7 +97,7 @@ void test_store_data_ia() { // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[RESULT]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[RESULT]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]], i32 1, i64 50) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[AUTHED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[RESULT:%.*]] = phi ptr [ null, {{.*}} ], [ [[AUTHED]], {{.*}} ] @@ -126,7 +123,7 @@ void test_store_data_ii_different() { // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 1, i64 100) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0), "ptrauth"(i64 1, i64 100, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -136,7 +133,7 @@ void test_store_data_ii_different() { // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 1, i64 100) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0), "ptrauth"(i64 1, i64 100, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -151,7 +148,7 @@ void test_store_data_ii_zero() { // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 1, i64 0) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0), "ptrauth"(i64 1, i64 0, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -161,7 +158,7 @@ void test_store_data_ii_zero() { // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 0, i32 1, i64 50) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 0, i64 0), "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -176,7 +173,7 @@ void test_load_data_i() { // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]], i32 1, i64 50) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[AUTHED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[AUTHED]], {{.*}} ] @@ -186,7 +183,7 @@ void test_load_data_i() { // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]], i32 1, i64 50) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[AUTHED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[AUTHED]], {{.*}} ] @@ -196,7 +193,7 @@ void test_load_data_i() { // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]], i32 1, i64 50) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[AUTHED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[AUTHED]], {{.*}} ] @@ -210,14 +207,12 @@ void test_load_data_i() { void test_store_data_a_constant() { // CHECK: [[V:%.*]] = alloca ptr, // CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50) -// CHECK-NEXT: [[SIGN:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @external_int to i64), i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[SIGN:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @external_int to i64)) [ "ptrauth"(i64 1, i64 50, i64 [[T0]]) ] // CHECK-NEXT: [[T0:%.*]] = inttoptr i64 [[SIGN]] to ptr // CHECK-NEXT: store ptr [[T0]], ptr [[V]], int * AQ aqpi = &external_int; // CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50) -// CHECK-NEXT: [[SIGN:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @external_int to i64), i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[SIGN:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @external_int to i64)) [ "ptrauth"(i64 1, i64 50, i64 [[T0]]) ] // CHECK-NEXT: [[T0:%.*]] = inttoptr i64 [[SIGN]] to ptr // CHECK-NEXT: store ptr [[T0]], ptr [[V]], aqpi = &external_int; @@ -227,24 +222,22 @@ void test_store_data_a_constant() { void test_store_data_au() { // CHECK: [[V:%.*]] = alloca ptr, // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_upi, -// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50) +// CHECK-NEXT: [[T01:%.*]] = ptrtoint ptr [[V]] to i64 // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[T0]], i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 [[T01]]) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] // CHECK-NEXT: store ptr [[T0]], ptr [[V]], int * AQ aqpi = global_upi; // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_upi, -// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50) +// CHECK-NEXT: [[T01:%.*]] = ptrtoint ptr [[V]] to i64 // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[T0]], i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 [[T01]]) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -256,24 +249,22 @@ void test_store_data_au() { void test_store_data_ai() { // CHECK: [[V:%.*]] = alloca ptr, // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_iqpi, -// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50) +// CHECK-NEXT: [[T01:%.*]] = ptrtoint ptr [[V]] to i64 // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0), "ptrauth"(i64 1, i64 50, i64 [[T01]]) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] // CHECK-NEXT: store ptr [[T0]], ptr [[V]], int * AQ aqpi = global_iqpi; // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_iqpi, -// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50) +// CHECK-NEXT: [[T01:%.*]] = ptrtoint ptr [[V]] to i64 // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0), "ptrauth"(i64 1, i64 50, i64 [[T01]]) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -285,26 +276,22 @@ void test_store_data_ai() { void test_store_data_aa_same() { // CHECK: [[V:%.*]] = alloca ptr, // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpi, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50) -// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50) +// CHECK-NEXT: [[T01:%.*]] = ptrtoint ptr [[V]] to i64 // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpi to i64)), "ptrauth"(i64 1, i64 50, i64 [[T01]]) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] // CHECK-NEXT: store ptr [[T0]], ptr [[V]], int * AQ aqpi = global_aqpi; // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpi, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50) -// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50) +// CHECK-NEXT: [[T01:%.*]] = ptrtoint ptr [[V]] to i64 // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpi to i64)), "ptrauth"(i64 1, i64 50, i64 [[T01]]) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -316,26 +303,22 @@ void test_store_data_aa_same() { void test_store_data_aa_different() { // CHECK: [[V:%.*]] = alloca ptr, // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpi, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50) -// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 100) +// CHECK-NEXT: [[T01:%.*]] = ptrtoint ptr [[V]] to i64 // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpi to i64)), "ptrauth"(i64 1, i64 100, i64 [[T01]]) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] // CHECK-NEXT: store ptr [[T0]], ptr [[V]], int * DIFF_AQ aqpi = global_aqpi; // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpi, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50) -// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 100) +// CHECK-NEXT: [[T01:%.*]] = ptrtoint ptr [[V]] to i64 // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpi to i64)), "ptrauth"(i64 1, i64 100, i64 [[T01]]) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -347,12 +330,11 @@ void test_store_data_aa_different() { void test_store_data_aa_zero() { // CHECK: [[V:%.*]] = alloca ptr, // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpi, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50) // CHECK-NEXT: [[NEWDISC:%.*]] = ptrtoint ptr [[V]] to i64 // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpi to i64)), "ptrauth"(i64 1, i64 0, i64 [[NEWDISC]]) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -360,11 +342,10 @@ void test_store_data_aa_zero() { int * ZERO_AQ aqpi = global_aqpi; // CHECK: [[LOAD:%.*]] = load ptr, ptr [[V]], // CHECK-NEXT: [[OLDDISC:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50) // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 0, i64 [[OLDDISC]]), "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpi to i64)) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -376,33 +357,30 @@ void test_store_data_aa_zero() { void test_load_data_a() { // CHECK: [[V:%.*]] = alloca ptr, // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpi, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50) // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]], i32 1, i64 [[OLDDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpi to i64)) ] // CHECK-NEXT: [[AUTHED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[AUTHED]], {{.*}} ] // CHECK-NEXT: store ptr [[T0]], ptr [[V]], int *upi = global_aqpi; // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpi, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50) // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]], i32 1, i64 [[OLDDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpi to i64)) ] // CHECK-NEXT: [[AUTHED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[AUTHED]], {{.*}} ] // CHECK-NEXT: store ptr [[T0]], ptr [[V]], upi = global_aqpi; // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpi, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpi to i64), i64 50) // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]], i32 1, i64 [[OLDDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpi to i64)) ] // CHECK-NEXT: [[AUTHED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[AUTHED]], {{.*}} ] @@ -415,11 +393,11 @@ void test_load_data_a() { // CHECK-LABEL: define {{.*}}void @test_store_function_i_constant() void test_store_function_i_constant() { // CHECK: [[V:%.*]] = alloca ptr, -// CHECK-NEXT: [[SIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @external_func, i32 0, i64 18983) to i64), i32 0, i64 18983, i32 1, i64 50) +// CHECK-NEXT: [[SIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @external_func, [i64 0, i64 18983, i64 0]) to i64)) [ "ptrauth"(i64 0, i64 18983, i64 0), "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[T0:%.*]] = inttoptr i64 [[SIGN]] to ptr // CHECK-NEXT: store ptr [[T0]], ptr [[V]], func_t * IQ iqpf = &external_func; -// CHECK-NEXT: [[SIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @external_func, i32 0, i64 18983) to i64), i32 0, i64 18983, i32 1, i64 50) +// CHECK-NEXT: [[SIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @external_func, [i64 0, i64 18983, i64 0]) to i64)) [ "ptrauth"(i64 0, i64 18983, i64 0), "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[T0:%.*]] = inttoptr i64 [[SIGN]] to ptr // CHECK-NEXT: store ptr [[T0]], ptr [[V]], iqpf = &external_func; @@ -432,7 +410,7 @@ void test_store_function_iu() { // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 0, i64 18983, i32 1, i64 50) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 0, i64 18983, i64 0), "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -442,7 +420,7 @@ void test_store_function_iu() { // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 0, i64 18983, i32 1, i64 50) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 0, i64 18983, i64 0), "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -454,33 +432,30 @@ void test_store_function_iu() { void test_store_function_ia() { // CHECK: [[V:%.*]] = alloca ptr, // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpf, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50) // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 50) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpf to i64)), "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] // CHECK-NEXT: store ptr [[T0]], ptr [[V]], func_t * IQ iqpf = global_aqpf; // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpf, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50) // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 50) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpf to i64)), "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] // CHECK-NEXT: store ptr [[T0]], ptr [[V]], iqpf = global_aqpf; // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpf, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50) // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 50) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpf to i64)), "ptrauth"(i64 1, i64 50, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[RESULT:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -488,7 +463,7 @@ void test_store_function_ia() { // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[RESULT]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[RESULT]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 0, i64 18983) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0), "ptrauth"(i64 0, i64 18983, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -514,7 +489,7 @@ void test_store_function_ii_different() { // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 1, i64 100) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0), "ptrauth"(i64 1, i64 100, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -524,7 +499,7 @@ void test_store_function_ii_different() { // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 1, i64 100) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0), "ptrauth"(i64 1, i64 100, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -539,7 +514,7 @@ void test_load_function_i() { // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 0, i64 18983) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0), "ptrauth"(i64 0, i64 18983, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -549,7 +524,7 @@ void test_load_function_i() { // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 0, i64 18983) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0), "ptrauth"(i64 0, i64 18983, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -559,7 +534,7 @@ void test_load_function_i() { // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 0, i64 18983) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0), "ptrauth"(i64 0, i64 18983, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -573,14 +548,12 @@ void test_load_function_i() { void test_store_function_a_constant() { // CHECK: [[V:%.*]] = alloca ptr, // CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50) -// CHECK-NEXT: [[SIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @external_func, i32 0, i64 18983) to i64), i32 0, i64 18983, i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[SIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @external_func, [i64 0, i64 18983, i64 0]) to i64)) [ "ptrauth"(i64 0, i64 18983, i64 0), "ptrauth"(i64 1, i64 50, i64 [[T0]]) ] // CHECK-NEXT: [[T0:%.*]] = inttoptr i64 [[SIGN]] to ptr // CHECK-NEXT: store ptr [[T0]], ptr [[V]], func_t * AQ aqpf = &external_func; // CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50) -// CHECK-NEXT: [[SIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @external_func, i32 0, i64 18983) to i64), i32 0, i64 18983, i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[SIGN:%.*]] = call i64 @llvm.ptrauth.resign(i64 ptrtoint (ptr ptrauth (ptr @external_func, [i64 0, i64 18983, i64 0]) to i64)) [ "ptrauth"(i64 0, i64 18983, i64 0), "ptrauth"(i64 1, i64 50, i64 [[T0]]) ] // CHECK-NEXT: [[T0:%.*]] = inttoptr i64 [[SIGN]] to ptr // CHECK-NEXT: store ptr [[T0]], ptr [[V]], aqpf = &external_func; @@ -590,24 +563,22 @@ void test_store_function_a_constant() { void test_store_function_au() { // CHECK: [[V:%.*]] = alloca ptr, // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_upf, -// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50) +// CHECK-NEXT: [[T01:%.*]] = ptrtoint ptr [[V]] to i64 // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 0, i64 18983, i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 0, i64 18983, i64 0), "ptrauth"(i64 1, i64 50, i64 [[T01]]) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] // CHECK-NEXT: store ptr [[T0]], ptr [[V]], func_t * AQ aqpf = global_upf; // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_upf, -// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50) +// CHECK-NEXT: [[T01:%.*]] = ptrtoint ptr [[V]] to i64 // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 0, i64 18983, i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 0, i64 18983, i64 0), "ptrauth"(i64 1, i64 50, i64 [[T01]]) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -619,24 +590,22 @@ void test_store_function_au() { void test_store_function_ai() { // CHECK: [[V:%.*]] = alloca ptr, // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_iqpf, -// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50) +// CHECK-NEXT: [[T01:%.*]] = ptrtoint ptr [[V]] to i64 // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0), "ptrauth"(i64 1, i64 50, i64 [[T01]]) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] // CHECK-NEXT: store ptr [[T0]], ptr [[V]], func_t * AQ aqpf = global_iqpf; // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_iqpf, -// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50) +// CHECK-NEXT: [[T01:%.*]] = ptrtoint ptr [[V]] to i64 // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 50, i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 0), "ptrauth"(i64 1, i64 50, i64 [[T01]]) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -648,26 +617,22 @@ void test_store_function_ai() { void test_store_function_aa_same() { // CHECK: [[V:%.*]] = alloca ptr, // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpf, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50) -// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50) +// CHECK-NEXT: [[T01:%.*]] = ptrtoint ptr [[V]] to i64 // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpf to i64)), "ptrauth"(i64 1, i64 50, i64 [[T01]]) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] // CHECK-NEXT: store ptr [[T0]], ptr [[V]], func_t * AQ aqpf = global_aqpf; // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpf, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50) -// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 50) +// CHECK-NEXT: [[T01:%.*]] = ptrtoint ptr [[V]] to i64 // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpf to i64)), "ptrauth"(i64 1, i64 50, i64 [[T01]]) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -679,26 +644,22 @@ void test_store_function_aa_same() { void test_store_function_aa_different() { // CHECK: [[V:%.*]] = alloca ptr, // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpf, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50) -// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 100) +// CHECK-NEXT: [[T01:%.*]] = ptrtoint ptr [[V]] to i64 // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpf to i64)), "ptrauth"(i64 1, i64 100, i64 [[T01]]) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] // CHECK-NEXT: store ptr [[T0]], ptr [[V]], func_t * DIFF_AQ aqpf = global_aqpf; // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpf, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50) -// CHECK-NEXT: [[T0:%.*]] = ptrtoint ptr [[V]] to i64 -// CHECK-NEXT: [[NEWDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[T0]], i64 100) +// CHECK-NEXT: [[T01:%.*]] = ptrtoint ptr [[V]] to i64 // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 1, i64 [[NEWDISC]]) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpf to i64)), "ptrauth"(i64 1, i64 100, i64 [[T01]]) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] @@ -710,33 +671,30 @@ void test_store_function_aa_different() { void test_load_function_a() { // CHECK: [[V:%.*]] = alloca ptr, // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpf, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50) // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 0, i64 18983) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpf to i64)), "ptrauth"(i64 0, i64 18983, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] // CHECK-NEXT: store ptr [[T0]], ptr [[V]], func_t *upf = global_aqpf; // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpf, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50) // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 0, i64 18983) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpf to i64)), "ptrauth"(i64 0, i64 18983, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] // CHECK-NEXT: store ptr [[T0]], ptr [[V]], upf = global_aqpf; // CHECK-NEXT: [[LOAD:%.*]] = load ptr, ptr @global_aqpf, -// CHECK-NEXT: [[OLDDISC:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @global_aqpf to i64), i64 50) // CHECK-NEXT: [[T0:%.*]] = icmp ne ptr [[LOAD]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]], i32 1, i64 [[OLDDISC]], i32 0, i64 18983) +// CHECK-NEXT: [[T1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[T0]]) [ "ptrauth"(i64 1, i64 50, i64 ptrtoint (ptr @global_aqpf to i64)), "ptrauth"(i64 0, i64 18983, i64 0) ] // CHECK-NEXT: [[SIGNED:%.*]] = inttoptr i64 [[T1]] to ptr // CHECK-NEXT: br label // CHECK: [[T0:%.*]] = phi ptr [ null, {{.*}} ], [ [[SIGNED]], {{.*}} ] diff --git a/clang/test/CodeGen/ptrauth-restricted-intptr-qualifier.c b/clang/test/CodeGen/ptrauth-restricted-intptr-qualifier.c index dcce5764e2217..de7119e1bd808 100644 --- a/clang/test/CodeGen/ptrauth-restricted-intptr-qualifier.c +++ b/clang/test/CodeGen/ptrauth-restricted-intptr-qualifier.c @@ -9,11 +9,11 @@ __INTPTR_TYPE__ __ptrauth(1, 1, 1272) g2 = 0; extern __UINTPTR_TYPE__ test_int; __UINTPTR_TYPE__ __ptrauth(3, 1, 23) g3 = (__UINTPTR_TYPE__)&test_int; // CHECK: @test_int = external global i64 -// CHECK: @g3 = global i64 ptrtoint (ptr ptrauth (ptr @test_int, i32 3, i64 23, ptr @g3) to i64) +// CHECK: @g3 = global i64 ptrtoint (ptr ptrauth (ptr @test_int, [i64 3, i64 23, i64 ptrtoint (ptr @g3 to i64)]) to i64) __INTPTR_TYPE__ __ptrauth(1, 1, 712) ga[3] = {0,0,(__UINTPTR_TYPE__)&test_int}; -// CHECK: @ga = global [3 x i64] [i64 0, i64 0, i64 ptrtoint (ptr ptrauth (ptr @test_int, i32 1, i64 712, ptr getelementptr inbounds ([3 x i64], ptr @ga, i32 0, i32 2)) to i64)] +// CHECK: @ga = global [3 x i64] [i64 0, i64 0, i64 ptrtoint (ptr ptrauth (ptr @test_int, [i64 1, i64 712, i64 ptrtoint (ptr getelementptr inbounds ([3 x i64], ptr @ga, i32 0, i32 2) to i64)]) to i64)] struct A { __INTPTR_TYPE__ __ptrauth(1, 0, 431) f0; @@ -22,7 +22,7 @@ struct A { }; struct A gs1 = {0, 0, (__UINTPTR_TYPE__)&test_int}; -// CHECK: @gs1 = global %struct.A { i64 0, i64 0, i64 ptrtoint (ptr ptrauth (ptr @test_int, i32 1, i64 783) to i64) } +// CHECK: @gs1 = global %struct.A { i64 0, i64 0, i64 ptrtoint (ptr ptrauth (ptr @test_int, [i64 1, i64 783, i64 0]) to i64) } struct B { __INTPTR_TYPE__ __ptrauth(1, 1, 1276) f0; @@ -31,19 +31,17 @@ struct B { }; struct B gs2 = {0, 0, (__UINTPTR_TYPE__)&test_int}; -// CHECK: @gs2 = global %struct.B { i64 0, i64 0, i64 ptrtoint (ptr ptrauth (ptr @test_int, i32 1, i64 163, ptr getelementptr inbounds (%struct.B, ptr @gs2, i32 0, i32 2)) to i64) } +// CHECK: @gs2 = global %struct.B { i64 0, i64 0, i64 ptrtoint (ptr ptrauth (ptr @test_int, [i64 1, i64 163, i64 ptrtoint (ptr getelementptr inbounds (%struct.B, ptr @gs2, i32 0, i32 2) to i64)]) to i64) } // CHECK-LABEL: i64 @test_read_globals __INTPTR_TYPE__ test_read_globals() { __INTPTR_TYPE__ result = g1 + g2 + g3; // CHECK: [[A:%.*]] = load i64, ptr @g1 - // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[A]], i32 1, i64 56) + // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[A]]) [ "ptrauth"(i64 1, i64 56, i64 0) ] // CHECK: [[B:%.*]] = load i64, ptr @g2 - // CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @g2 to i64), i64 1272) - // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[B]], i32 1, i64 [[BLENDED]]) + // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[B]]) [ "ptrauth"(i64 1, i64 1272, i64 ptrtoint (ptr @g2 to i64)) ] // CHECK: [[VALUE:%.*]] = load i64, ptr @g3 - // CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @g3 to i64), i64 23) - // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VALUE]], i32 3, i64 [[BLENDED]]) + // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VALUE]]) [ "ptrauth"(i64 3, i64 23, i64 ptrtoint (ptr @g3 to i64)) ] for (int i = 0; i < 3; i++) { result += ga[i]; @@ -57,28 +55,25 @@ __INTPTR_TYPE__ test_read_globals() { // CHECK: [[ARRAYIDX:%.*]] = getelementptr inbounds [3 x i64], ptr @ga, i64 0, i64 [[IDXPROM]] // CHECK: [[VALUE:%.*]] = load i64, ptr [[ARRAYIDX]] // CHECK: [[CASTIDX:%.*]] = ptrtoint ptr [[ARRAYIDX]] to i64 - // CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CASTIDX]], i64 712) // CHECK: resign.nonnull6: - // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VALUE]], i32 1, i64 [[BLENDED]]) + // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VALUE]]) [ "ptrauth"(i64 1, i64 712, i64 [[CASTIDX]]) ] // CHECK: resign.cont7 result += gs1.f0 + gs1.f1 + gs1.f2; // CHECK: resign.cont10: // CHECK: [[ADDR:%.*]] = load i64, ptr getelementptr inbounds nuw (%struct.A, ptr @gs1, i32 0, i32 1 // CHECK: resign.nonnull11: - // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[ADDR]], i32 1, i64 9182) + // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[ADDR]]) [ "ptrauth"(i64 1, i64 9182, i64 0) ] // CHECK: resign.cont12: // CHECK: [[ADDR:%.*]] = load i64, ptr getelementptr inbounds nuw (%struct.A, ptr @gs1, i32 0, i32 2) - // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[ADDR]], i32 1, i64 783) + // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[ADDR]]) [ "ptrauth"(i64 1, i64 783, i64 0) ] result += gs2.f0 + gs2.f1 + gs2.f2; // CHECK: [[ADDR:%.*]] = load i64, ptr @gs2 - // CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @gs2 to i64), i64 1276) - // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[ADDR]], i32 1, i64 [[BLENDED]]) + // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[ADDR]]) [ "ptrauth"(i64 1, i64 1276, i64 ptrtoint (ptr @gs2 to i64)) ] // CHECK: [[ADDR:%.*]] = load i64, ptr getelementptr inbounds nuw (%struct.B, ptr @gs2, i32 0, i32 1) - // CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr getelementptr inbounds nuw (%struct.B, ptr @gs2, i32 0, i32 1) to i64), i64 23674) - // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[ADDR]], i32 1, i64 [[BLENDED]]) + // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[ADDR]]) [ "ptrauth"(i64 1, i64 23674, i64 ptrtoint (ptr getelementptr inbounds nuw (%struct.B, ptr @gs2, i32 0, i32 1) to i64)) ] // CHECK: [[ADDR:%.*]] = load i64, ptr getelementptr inbounds nuw (%struct.B, ptr @gs2, i32 0, i32 2) - // CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr getelementptr inbounds nuw (%struct.B, ptr @gs2, i32 0, i32 2) to i64), i64 163) + // CHECK: "ptrauth"(i64 1, i64 163, i64 ptrtoint (ptr getelementptr inbounds nuw (%struct.B, ptr @gs2, i32 0, i32 2) to i64)) return result; } @@ -103,11 +98,11 @@ void test_write_globals(int i, __INTPTR_TYPE__ j) { void test_set_A(struct A *a, __INTPTR_TYPE__ x, int y) { a->f0 = x; // CHECK: [[XADDR:%.*]] = load i64, ptr %x.addr - // CHECK: [[SIGNED_X:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[XADDR]], i32 1, i64 431) + // CHECK: [[SIGNED_X:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[XADDR]]) [ "ptrauth"(i64 1, i64 431, i64 0) ] a->f1 = y; // CHECK: [[Y:%.*]] = load i32, ptr %y.addr // CHECK: [[CONV:%.*]] = sext i32 [[Y]] to i64 - // CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[CONV]], i32 1, i64 9182) + // CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[CONV]]) [ "ptrauth"(i64 1, i64 9182, i64 0) ] a->f2 = 0; // CHECK: [[A:%.*]] = load ptr, ptr %a.addr // CHECK: [[F2:%.*]] = getelementptr inbounds nuw %struct.A, ptr [[A]], i32 0, i32 2 @@ -119,16 +114,14 @@ void test_set_B(struct B *b, __INTPTR_TYPE__ x, int y) { b->f0 = x; // CHECK: [[X:%.*]] = load i64, ptr %x.addr // CHECK: [[F0_ADDR:%.*]] = ptrtoint ptr %f0 to i64 - // CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[F0_ADDR]], i64 1276) - // CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[X]], i32 1, i64 [[BLENDED]]) + // CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[X]]) [ "ptrauth"(i64 1, i64 1276, i64 [[F0_ADDR]]) ] b->f1 = y; // CHECK: [[B:%.*]] = load ptr, ptr %b.addr // CHECK: [[F1_ADDR:%.*]] = getelementptr inbounds nuw %struct.B, ptr [[B]], i32 0, i32 1 // CHECK: [[Y:%.*]] = load i32, ptr %y.addr, align 4 // CHECK: [[CONV:%.*]] = sext i32 [[Y]] to i64 // CHECK: [[CAST_ADDR:%.*]] = ptrtoint ptr [[F1_ADDR]] to i64 - // CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_ADDR]], i64 23674) - // CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[CONV]], i32 1, i64 [[BLENDED]]) + // CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[CONV]]) [ "ptrauth"(i64 1, i64 23674, i64 [[CAST_ADDR]]) ] b->f2 = 0; // CHECK: [[B:%.*]] = load ptr, ptr %b.addr // CHECK: [[F2_ADDR:%.*]] = getelementptr inbounds nuw %struct.B, ptr [[B]], i32 0, i32 2 @@ -141,15 +134,15 @@ __INTPTR_TYPE__ test_get_A(struct A *a) { // CHECK: [[A:%.*]] = load ptr, ptr %a.addr // CHECK: [[F0_ADDR:%.*]] = getelementptr inbounds nuw %struct.A, ptr [[A]], i32 0, i32 0 // CHECK: [[F0:%.*]] = load i64, ptr [[F0_ADDR]] - // CHECK: [[AUTH:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[F0]], i32 1, i64 431) + // CHECK: [[AUTH:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[F0]]) [ "ptrauth"(i64 1, i64 431, i64 0) ] // CHECK: [[A:%.*]] = load ptr, ptr %a.addr // CHECK: [[F1_ADDR:%.*]] = getelementptr inbounds nuw %struct.A, ptr [[A]], i32 0, i32 1 // CHECK: [[F1:%.*]] = load i64, ptr [[F1_ADDR]] - // CHECK: [[AUTH:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[F1]], i32 1, i64 9182) + // CHECK: [[AUTH:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[F1]]) [ "ptrauth"(i64 1, i64 9182, i64 0) ] // CHECK: [[A:%.*]] = load ptr, ptr %a.addr // CHECK: [[F2_ADDR:%.*]] = getelementptr inbounds nuw %struct.A, ptr [[A]], i32 0, i32 2 // CHECK: [[F2:%.*]] = load i64, ptr [[F2_ADDR]] - // CHECK: [[AUTH:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[F2]], i32 1, i64 783) + // CHECK: [[AUTH:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[F2]]) [ "ptrauth"(i64 1, i64 783, i64 0) ] } // CHECK-LABEL: define i64 @test_get_B @@ -159,20 +152,17 @@ __INTPTR_TYPE__ test_get_B(struct B *b) { // CHECK: [[F0:%.*]] = getelementptr inbounds nuw %struct.B, ptr [[B]], i32 0, i32 0 // CHECK: [[VALUE:%.*]] = load i64, ptr [[F0]] // CHECK: [[CASTF0:%.*]] = ptrtoint ptr %f0 to i64 - // CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CASTF0]], i64 1276) - // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VALUE]], i32 1, i64 [[BLENDED]]) + // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VALUE]]) [ "ptrauth"(i64 1, i64 1276, i64 [[CASTF0]]) ] // CHECK: [[B:%.*]] = load ptr, ptr %b.addr // CHECK: [[ADDR:%.*]] = getelementptr inbounds nuw %struct.B, ptr [[B]], i32 0, i32 1 // CHECK: [[VALUE:%.*]] = load i64, ptr [[ADDR]] // CHECK: [[CAST_ADDR:%.*]] = ptrtoint ptr [[ADDR]] to i64 - // CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_ADDR]], i64 23674) - // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VALUE]], i32 1, i64 [[BLENDED]]) + // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VALUE]]) [ "ptrauth"(i64 1, i64 23674, i64 [[CAST_ADDR]]) ] // CHECK: [[B:%.*]] = load ptr, ptr %b.addr // CHECK: [[ADDR:%.*]] = getelementptr inbounds nuw %struct.B, ptr [[B]], i32 0, i32 2 // CHECK: [[VALUE:%.*]] = load i64, ptr [[ADDR]] // CHECK: [[CAST_ADDR:%.*]] = ptrtoint ptr [[ADDR]] to i64 - // CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_ADDR]], i64 163) - // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VALUE]], i32 1, i64 [[BLENDED]]) + // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VALUE]]) [ "ptrauth"(i64 1, i64 163, i64 [[CAST_ADDR]]) ] } // CHECK-LABEL: define void @test_resign @@ -184,8 +174,7 @@ void test_resign(struct A* a, const struct B *b) { // CHECK: [[F01:%.*]] = getelementptr inbounds nuw %struct.B, ptr [[B]], i32 0, i32 0 // CHECK: [[F01VALUE:%.*]] = load i64, ptr [[F01]] // CHECK: [[CASTF01:%.*]] = ptrtoint ptr %f01 to i64 - // CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CASTF01]], i64 1276) - // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[F01VALUE]], i32 1, i64 [[BLENDED]], i32 1, i64 431) + // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[F01VALUE]]) [ "ptrauth"(i64 1, i64 1276, i64 [[CASTF01]]), "ptrauth"(i64 1, i64 431, i64 0) ] } // CHECK-LABEL: define i64 @other_test @@ -195,25 +184,20 @@ __INTPTR_TYPE__ other_test(__INTPTR_TYPE__ i) { // CHECK: store i64 0, ptr %j __INTPTR_TYPE__ __ptrauth(1, 1, 43) k = 1234; // CHECK: [[ADDR:%.*]] = ptrtoint ptr %k to i64 - // CHECK: [[JBLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[ADDR]], i64 43) - // CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 1234, i32 1, i64 [[JBLENDED]]) + // CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 1234) [ "ptrauth"(i64 1, i64 43, i64 [[ADDR]]) ] __INTPTR_TYPE__ __ptrauth(1, 1, 44) l = i; // CHECK: [[I:%.*]] = load i64, ptr %i.addr // CHECK: [[ADDR:%.*]] = ptrtoint ptr %l to i64 - // CHECK: [[LBLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[ADDR]], i64 44) - // CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[I]], i32 1, i64 [[LBLENDED]]) + // CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[I]]) [ "ptrauth"(i64 1, i64 44, i64 [[ADDR]]) ] asm volatile ("" ::: "memory"); return j + k + l; // CHECK: [[VALUE:%.*]] = load i64, ptr %j // CHECK: [[CAST_ADDR:%.*]] = ptrtoint ptr %j to i64 - // CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_ADDR]], i64 42) - // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VALUE]], i32 1, i64 [[BLENDED]]) + // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VALUE]]) [ "ptrauth"(i64 1, i64 42, i64 [[CAST_ADDR]]) ] // CHECK: [[VALUE:%.*]] = load i64, ptr %k // CHECK: [[CASTK:%.*]] = ptrtoint ptr %k to i64 - // CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CASTK]], i64 43) - // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VALUE]], i32 1, i64 [[BLENDED]]) + // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VALUE]]) [ "ptrauth"(i64 1, i64 43, i64 [[CASTK]]) ] // CHECK: [[VALUE:%.*]] = load i64, ptr %l // CHECK: [[CASTL:%.*]] = ptrtoint ptr %l to i64 - // CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CASTL]], i64 44) - // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VALUE]], i32 1, i64 [[BLENDED]]) + // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VALUE]]) [ "ptrauth"(i64 1, i64 44, i64 [[CASTL]]) ] } diff --git a/clang/test/CodeGen/ptrauth-weak_import.c b/clang/test/CodeGen/ptrauth-weak_import.c index 1f53747a2640e..c5b4bbd69a9fb 100644 --- a/clang/test/CodeGen/ptrauth-weak_import.c +++ b/clang/test/CodeGen/ptrauth-weak_import.c @@ -4,7 +4,7 @@ extern void foo() __attribute__((weak_import)); // CHECK: define {{(dso_local )?}}void @bar() -// CHECK: [[TMP1:%.*]] = icmp ne ptr ptrauth (ptr @foo, i32 0), null +// CHECK: [[TMP1:%.*]] = icmp ne ptr ptrauth (ptr @foo, [i64 0, i64 0, i64 0]), null // CHECK: br i1 [[TMP1]], label void bar() { if (foo) diff --git a/clang/test/CodeGen/ubsan-function.cpp b/clang/test/CodeGen/ubsan-function.cpp index 76d4237383f83..60fd7edca0613 100644 --- a/clang/test/CodeGen/ubsan-function.cpp +++ b/clang/test/CodeGen/ubsan-function.cpp @@ -17,7 +17,7 @@ void fun() {} // ARM: and i32 {{.*}}, -2, !nosanitize !5 // ARM: inttoptr i32 {{.*}} to ptr, !nosanitize !5 // AUTH: %[[STRIPPED:.*]] = ptrtoint ptr {{.*}} to i64, !nosanitize -// AUTH: call i64 @llvm.ptrauth.auth(i64 %[[STRIPPED]], i32 0, i64 0), !nosanitize +// AUTH: call i64 @llvm.ptrauth.auth(i64 %[[STRIPPED]]) [ "ptrauth"(i64 0, i64 0, i64 0) ], !nosanitize // CHECK: getelementptr <{ i32, i32 }>, ptr {{.*}}, i32 -1, i32 0, !nosanitize // CHECK: load i32, ptr {{.*}}, align {{.*}}, !nosanitize // CHECK: icmp eq i32 {{.*}}, -1056584962, !nosanitize diff --git a/clang/test/CodeGenCXX/builtin-get-vtable-pointer.cpp b/clang/test/CodeGenCXX/builtin-get-vtable-pointer.cpp index 0bde63496f4cb..db0fd8e20e595 100644 --- a/clang/test/CodeGenCXX/builtin-get-vtable-pointer.cpp +++ b/clang/test/CodeGenCXX/builtin-get-vtable-pointer.cpp @@ -53,7 +53,7 @@ template struct same_type { // CHECK-TYPEAUTH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[O_ADDR]], align 8, !tbaa [[TBAA6]] // CHECK-TYPEAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9:![0-9]+]] // CHECK-TYPEAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]], i32 2, i64 48388) +// CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]]) [ "ptrauth"(i64 2, i64 48388, i64 0) ] // CHECK-TYPEAUTH-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr // CHECK-TYPEAUTH-NEXT: [[TMP4:%.*]] = load volatile i8, ptr [[TMP3]], align 8 // CHECK-TYPEAUTH-NEXT: ret ptr [[TMP3]] @@ -67,7 +67,7 @@ template struct same_type { // CHECK-ADDRESSAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9:![0-9]+]] // CHECK-ADDRESSAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 // CHECK-ADDRESSAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]], i32 2, i64 [[TMP1]]) +// CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]]) [ "ptrauth"(i64 2, i64 0, i64 [[TMP1]]) ] // CHECK-ADDRESSAUTH-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr // CHECK-ADDRESSAUTH-NEXT: [[TMP5:%.*]] = load volatile i8, ptr [[TMP4]], align 8 // CHECK-ADDRESSAUTH-NEXT: ret ptr [[TMP4]] @@ -80,9 +80,8 @@ template struct same_type { // CHECK-BOTHAUTH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[O_ADDR]], align 8, !tbaa [[TBAA6]] // CHECK-BOTHAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9:![0-9]+]] // CHECK-BOTHAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[TMP1]], i64 48388) // CHECK-BOTHAUTH-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]], i32 2, i64 [[TMP2]]) +// CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]]) [ "ptrauth"(i64 2, i64 48388, i64 [[TMP1]]) ] // CHECK-BOTHAUTH-NEXT: [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr // CHECK-BOTHAUTH-NEXT: [[TMP6:%.*]] = load volatile i8, ptr [[TMP5]], align 8 // CHECK-BOTHAUTH-NEXT: ret ptr [[TMP5]] @@ -109,7 +108,7 @@ const void *a(A *o) { // CHECK-TYPEAUTH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[O_ADDR]], align 8, !tbaa [[TBAA11]] // CHECK-TYPEAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-TYPEAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]], i32 2, i64 48388) +// CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]]) [ "ptrauth"(i64 2, i64 48388, i64 0) ] // CHECK-TYPEAUTH-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr // CHECK-TYPEAUTH-NEXT: [[TMP4:%.*]] = load volatile i8, ptr [[TMP3]], align 8 // CHECK-TYPEAUTH-NEXT: ret ptr [[TMP3]] @@ -123,7 +122,7 @@ const void *a(A *o) { // CHECK-ADDRESSAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-ADDRESSAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 // CHECK-ADDRESSAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]], i32 2, i64 [[TMP1]]) +// CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]]) [ "ptrauth"(i64 2, i64 0, i64 [[TMP1]]) ] // CHECK-ADDRESSAUTH-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr // CHECK-ADDRESSAUTH-NEXT: [[TMP5:%.*]] = load volatile i8, ptr [[TMP4]], align 8 // CHECK-ADDRESSAUTH-NEXT: ret ptr [[TMP4]] @@ -136,9 +135,8 @@ const void *a(A *o) { // CHECK-BOTHAUTH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[O_ADDR]], align 8, !tbaa [[TBAA11]] // CHECK-BOTHAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-BOTHAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[TMP1]], i64 48388) // CHECK-BOTHAUTH-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]], i32 2, i64 [[TMP2]]) +// CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]]) [ "ptrauth"(i64 2, i64 48388, i64 [[TMP1]]) ] // CHECK-BOTHAUTH-NEXT: [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr // CHECK-BOTHAUTH-NEXT: [[TMP6:%.*]] = load volatile i8, ptr [[TMP5]], align 8 // CHECK-BOTHAUTH-NEXT: ret ptr [[TMP5]] @@ -165,7 +163,7 @@ const void *b(B *o) { // CHECK-TYPEAUTH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[O_ADDR]], align 8, !tbaa [[TBAA11]] // CHECK-TYPEAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-TYPEAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]], i32 2, i64 48388) +// CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]]) [ "ptrauth"(i64 2, i64 48388, i64 0) ] // CHECK-TYPEAUTH-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr // CHECK-TYPEAUTH-NEXT: [[TMP4:%.*]] = load volatile i8, ptr [[TMP3]], align 8 // CHECK-TYPEAUTH-NEXT: ret ptr [[TMP3]] @@ -179,7 +177,7 @@ const void *b(B *o) { // CHECK-ADDRESSAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-ADDRESSAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 // CHECK-ADDRESSAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]], i32 2, i64 [[TMP1]]) +// CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]]) [ "ptrauth"(i64 2, i64 0, i64 [[TMP1]]) ] // CHECK-ADDRESSAUTH-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr // CHECK-ADDRESSAUTH-NEXT: [[TMP5:%.*]] = load volatile i8, ptr [[TMP4]], align 8 // CHECK-ADDRESSAUTH-NEXT: ret ptr [[TMP4]] @@ -192,9 +190,8 @@ const void *b(B *o) { // CHECK-BOTHAUTH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[O_ADDR]], align 8, !tbaa [[TBAA11]] // CHECK-BOTHAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-BOTHAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[TMP1]], i64 48388) // CHECK-BOTHAUTH-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]], i32 2, i64 [[TMP2]]) +// CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]]) [ "ptrauth"(i64 2, i64 48388, i64 [[TMP1]]) ] // CHECK-BOTHAUTH-NEXT: [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr // CHECK-BOTHAUTH-NEXT: [[TMP6:%.*]] = load volatile i8, ptr [[TMP5]], align 8 // CHECK-BOTHAUTH-NEXT: ret ptr [[TMP5]] @@ -221,7 +218,7 @@ const void *b_as_A(B *o) { // CHECK-TYPEAUTH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[O_ADDR]], align 8, !tbaa [[TBAA13]] // CHECK-TYPEAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-TYPEAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]], i32 2, i64 48388) +// CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]]) [ "ptrauth"(i64 2, i64 48388, i64 0) ] // CHECK-TYPEAUTH-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr // CHECK-TYPEAUTH-NEXT: [[TMP4:%.*]] = load volatile i8, ptr [[TMP3]], align 8 // CHECK-TYPEAUTH-NEXT: ret ptr [[TMP3]] @@ -235,7 +232,7 @@ const void *b_as_A(B *o) { // CHECK-ADDRESSAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-ADDRESSAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 // CHECK-ADDRESSAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]], i32 2, i64 [[TMP1]]) +// CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]]) [ "ptrauth"(i64 2, i64 0, i64 [[TMP1]]) ] // CHECK-ADDRESSAUTH-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr // CHECK-ADDRESSAUTH-NEXT: [[TMP5:%.*]] = load volatile i8, ptr [[TMP4]], align 8 // CHECK-ADDRESSAUTH-NEXT: ret ptr [[TMP4]] @@ -248,9 +245,8 @@ const void *b_as_A(B *o) { // CHECK-BOTHAUTH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[O_ADDR]], align 8, !tbaa [[TBAA13]] // CHECK-BOTHAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-BOTHAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[TMP1]], i64 48388) // CHECK-BOTHAUTH-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]], i32 2, i64 [[TMP2]]) +// CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]]) [ "ptrauth"(i64 2, i64 48388, i64 [[TMP1]]) ] // CHECK-BOTHAUTH-NEXT: [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr // CHECK-BOTHAUTH-NEXT: [[TMP6:%.*]] = load volatile i8, ptr [[TMP5]], align 8 // CHECK-BOTHAUTH-NEXT: ret ptr [[TMP5]] @@ -277,7 +273,7 @@ const void *c(C *o) { // CHECK-TYPEAUTH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[O_ADDR]], align 8, !tbaa [[TBAA13]] // CHECK-TYPEAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-TYPEAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]], i32 2, i64 48388) +// CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]]) [ "ptrauth"(i64 2, i64 48388, i64 0) ] // CHECK-TYPEAUTH-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr // CHECK-TYPEAUTH-NEXT: [[TMP4:%.*]] = load volatile i8, ptr [[TMP3]], align 8 // CHECK-TYPEAUTH-NEXT: ret ptr [[TMP3]] @@ -291,7 +287,7 @@ const void *c(C *o) { // CHECK-ADDRESSAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-ADDRESSAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 // CHECK-ADDRESSAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]], i32 2, i64 [[TMP1]]) +// CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]]) [ "ptrauth"(i64 2, i64 0, i64 [[TMP1]]) ] // CHECK-ADDRESSAUTH-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr // CHECK-ADDRESSAUTH-NEXT: [[TMP5:%.*]] = load volatile i8, ptr [[TMP4]], align 8 // CHECK-ADDRESSAUTH-NEXT: ret ptr [[TMP4]] @@ -304,9 +300,8 @@ const void *c(C *o) { // CHECK-BOTHAUTH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[O_ADDR]], align 8, !tbaa [[TBAA13]] // CHECK-BOTHAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-BOTHAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[TMP1]], i64 48388) // CHECK-BOTHAUTH-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]], i32 2, i64 [[TMP2]]) +// CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]]) [ "ptrauth"(i64 2, i64 48388, i64 [[TMP1]]) ] // CHECK-BOTHAUTH-NEXT: [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr // CHECK-BOTHAUTH-NEXT: [[TMP6:%.*]] = load volatile i8, ptr [[TMP5]], align 8 // CHECK-BOTHAUTH-NEXT: ret ptr [[TMP5]] @@ -347,7 +342,7 @@ const void *c_as_Z(C *o) { // CHECK-TYPEAUTH-NEXT: [[CAST_RESULT:%.*]] = phi ptr [ [[ADD_PTR]], %[[CAST_NOTNULL]] ], [ null, %[[ENTRY]] ] // CHECK-TYPEAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[CAST_RESULT]], align 8, !tbaa [[TBAA9]] // CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-TYPEAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]], i32 2, i64 48388) +// CHECK-TYPEAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]]) [ "ptrauth"(i64 2, i64 48388, i64 0) ] // CHECK-TYPEAUTH-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr // CHECK-TYPEAUTH-NEXT: [[TMP5:%.*]] = load volatile i8, ptr [[TMP4]], align 8 // CHECK-TYPEAUTH-NEXT: ret ptr [[TMP4]] @@ -368,7 +363,7 @@ const void *c_as_Z(C *o) { // CHECK-ADDRESSAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[CAST_RESULT]], align 8, !tbaa [[TBAA9]] // CHECK-ADDRESSAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[CAST_RESULT]] to i64 // CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-ADDRESSAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]], i32 2, i64 [[TMP2]]) +// CHECK-ADDRESSAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]]) [ "ptrauth"(i64 2, i64 0, i64 [[TMP2]]) ] // CHECK-ADDRESSAUTH-NEXT: [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr // CHECK-ADDRESSAUTH-NEXT: [[TMP6:%.*]] = load volatile i8, ptr [[TMP5]], align 8 // CHECK-ADDRESSAUTH-NEXT: ret ptr [[TMP5]] @@ -388,9 +383,8 @@ const void *c_as_Z(C *o) { // CHECK-BOTHAUTH-NEXT: [[CAST_RESULT:%.*]] = phi ptr [ [[ADD_PTR]], %[[CAST_NOTNULL]] ], [ null, %[[ENTRY]] ] // CHECK-BOTHAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[CAST_RESULT]], align 8, !tbaa [[TBAA9]] // CHECK-BOTHAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[CAST_RESULT]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[TMP2]], i64 48388) // CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP5:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP4]], i32 2, i64 [[TMP3]]) +// CHECK-BOTHAUTH-NEXT: [[TMP5:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP4]]) [ "ptrauth"(i64 2, i64 48388, i64 [[TMP2]]) ] // CHECK-BOTHAUTH-NEXT: [[TMP6:%.*]] = inttoptr i64 [[TMP5]] to ptr // CHECK-BOTHAUTH-NEXT: [[TMP7:%.*]] = load volatile i8, ptr [[TMP6]], align 8 // CHECK-BOTHAUTH-NEXT: ret ptr [[TMP6]] @@ -417,7 +411,7 @@ const void *c_as_B(C *o) { // CHECK-TYPEAUTH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[O_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK-TYPEAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-TYPEAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]], i32 2, i64 48388) +// CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]]) [ "ptrauth"(i64 2, i64 48388, i64 0) ] // CHECK-TYPEAUTH-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr // CHECK-TYPEAUTH-NEXT: [[TMP4:%.*]] = load volatile i8, ptr [[TMP3]], align 8 // CHECK-TYPEAUTH-NEXT: ret ptr [[TMP3]] @@ -431,7 +425,7 @@ const void *c_as_B(C *o) { // CHECK-ADDRESSAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-ADDRESSAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 // CHECK-ADDRESSAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]], i32 2, i64 [[TMP1]]) +// CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]]) [ "ptrauth"(i64 2, i64 0, i64 [[TMP1]]) ] // CHECK-ADDRESSAUTH-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr // CHECK-ADDRESSAUTH-NEXT: [[TMP5:%.*]] = load volatile i8, ptr [[TMP4]], align 8 // CHECK-ADDRESSAUTH-NEXT: ret ptr [[TMP4]] @@ -444,9 +438,8 @@ const void *c_as_B(C *o) { // CHECK-BOTHAUTH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[O_ADDR]], align 8, !tbaa [[TBAA15]] // CHECK-BOTHAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-BOTHAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[TMP1]], i64 48388) // CHECK-BOTHAUTH-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]], i32 2, i64 [[TMP2]]) +// CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]]) [ "ptrauth"(i64 2, i64 48388, i64 [[TMP1]]) ] // CHECK-BOTHAUTH-NEXT: [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr // CHECK-BOTHAUTH-NEXT: [[TMP6:%.*]] = load volatile i8, ptr [[TMP5]], align 8 // CHECK-BOTHAUTH-NEXT: ret ptr [[TMP5]] @@ -486,7 +479,7 @@ const void *d(D *o) { // CHECK-TYPEAUTH: [[CAST_NOTNULL]]: // CHECK-TYPEAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-TYPEAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]], i32 2, i64 48388) +// CHECK-TYPEAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]]) [ "ptrauth"(i64 2, i64 48388, i64 0) ] // CHECK-TYPEAUTH-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr // CHECK-TYPEAUTH-NEXT: [[VBASE_OFFSET_PTR:%.*]] = getelementptr i8, ptr [[TMP4]], i64 -32 // CHECK-TYPEAUTH-NEXT: [[VBASE_OFFSET:%.*]] = load i64, ptr [[VBASE_OFFSET_PTR]], align 8 @@ -496,7 +489,7 @@ const void *d(D *o) { // CHECK-TYPEAUTH-NEXT: [[CAST_RESULT:%.*]] = phi ptr [ [[ADD_PTR]], %[[CAST_NOTNULL]] ], [ null, %[[ENTRY]] ] // CHECK-TYPEAUTH-NEXT: [[VTABLE1:%.*]] = load ptr, ptr [[CAST_RESULT]], align 8, !tbaa [[TBAA9]] // CHECK-TYPEAUTH-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[VTABLE1]] to i64 -// CHECK-TYPEAUTH-NEXT: [[TMP6:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP5]], i32 2, i64 48388) +// CHECK-TYPEAUTH-NEXT: [[TMP6:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP5]]) [ "ptrauth"(i64 2, i64 48388, i64 0) ] // CHECK-TYPEAUTH-NEXT: [[TMP7:%.*]] = inttoptr i64 [[TMP6]] to ptr // CHECK-TYPEAUTH-NEXT: [[TMP8:%.*]] = load volatile i8, ptr [[TMP7]], align 8 // CHECK-TYPEAUTH-NEXT: ret ptr [[TMP7]] @@ -513,7 +506,7 @@ const void *d(D *o) { // CHECK-ADDRESSAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-ADDRESSAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP0]] to i64 // CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-ADDRESSAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]], i32 2, i64 [[TMP2]]) +// CHECK-ADDRESSAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]]) [ "ptrauth"(i64 2, i64 0, i64 [[TMP2]]) ] // CHECK-ADDRESSAUTH-NEXT: [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr // CHECK-ADDRESSAUTH-NEXT: [[VBASE_OFFSET_PTR:%.*]] = getelementptr i8, ptr [[TMP5]], i64 -32 // CHECK-ADDRESSAUTH-NEXT: [[VBASE_OFFSET:%.*]] = load i64, ptr [[VBASE_OFFSET_PTR]], align 8 @@ -524,7 +517,7 @@ const void *d(D *o) { // CHECK-ADDRESSAUTH-NEXT: [[VTABLE1:%.*]] = load ptr, ptr [[CAST_RESULT]], align 8, !tbaa [[TBAA9]] // CHECK-ADDRESSAUTH-NEXT: [[TMP6:%.*]] = ptrtoint ptr [[CAST_RESULT]] to i64 // CHECK-ADDRESSAUTH-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[VTABLE1]] to i64 -// CHECK-ADDRESSAUTH-NEXT: [[TMP8:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP7]], i32 2, i64 [[TMP6]]) +// CHECK-ADDRESSAUTH-NEXT: [[TMP8:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP7]]) [ "ptrauth"(i64 2, i64 0, i64 [[TMP6]]) ] // CHECK-ADDRESSAUTH-NEXT: [[TMP9:%.*]] = inttoptr i64 [[TMP8]] to ptr // CHECK-ADDRESSAUTH-NEXT: [[TMP10:%.*]] = load volatile i8, ptr [[TMP9]], align 8 // CHECK-ADDRESSAUTH-NEXT: ret ptr [[TMP9]] @@ -540,9 +533,8 @@ const void *d(D *o) { // CHECK-BOTHAUTH: [[CAST_NOTNULL]]: // CHECK-BOTHAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-BOTHAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[TMP0]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[TMP2]], i64 48388) // CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP5:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP4]], i32 2, i64 [[TMP3]]) +// CHECK-BOTHAUTH-NEXT: [[TMP5:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP4]]) [ "ptrauth"(i64 2, i64 48388, i64 [[TMP2]]) ] // CHECK-BOTHAUTH-NEXT: [[TMP6:%.*]] = inttoptr i64 [[TMP5]] to ptr // CHECK-BOTHAUTH-NEXT: [[VBASE_OFFSET_PTR:%.*]] = getelementptr i8, ptr [[TMP6]], i64 -32 // CHECK-BOTHAUTH-NEXT: [[VBASE_OFFSET:%.*]] = load i64, ptr [[VBASE_OFFSET_PTR]], align 8 @@ -552,9 +544,8 @@ const void *d(D *o) { // CHECK-BOTHAUTH-NEXT: [[CAST_RESULT:%.*]] = phi ptr [ [[ADD_PTR]], %[[CAST_NOTNULL]] ], [ null, %[[ENTRY]] ] // CHECK-BOTHAUTH-NEXT: [[VTABLE1:%.*]] = load ptr, ptr [[CAST_RESULT]], align 8, !tbaa [[TBAA9]] // CHECK-BOTHAUTH-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[CAST_RESULT]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP8:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[TMP7]], i64 48388) // CHECK-BOTHAUTH-NEXT: [[TMP9:%.*]] = ptrtoint ptr [[VTABLE1]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP10:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP9]], i32 2, i64 [[TMP8]]) +// CHECK-BOTHAUTH-NEXT: [[TMP10:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP9]]) [ "ptrauth"(i64 2, i64 48388, i64 [[TMP7]]) ] // CHECK-BOTHAUTH-NEXT: [[TMP11:%.*]] = inttoptr i64 [[TMP10]] to ptr // CHECK-BOTHAUTH-NEXT: [[TMP12:%.*]] = load volatile i8, ptr [[TMP11]], align 8 // CHECK-BOTHAUTH-NEXT: ret ptr [[TMP11]] @@ -581,7 +572,7 @@ const void *d_as_A(D *o) { // CHECK-TYPEAUTH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[O_ADDR]], align 8, !tbaa [[TBAA17]] // CHECK-TYPEAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-TYPEAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]], i32 2, i64 48388) +// CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]]) [ "ptrauth"(i64 2, i64 48388, i64 0) ] // CHECK-TYPEAUTH-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr // CHECK-TYPEAUTH-NEXT: [[TMP4:%.*]] = load volatile i8, ptr [[TMP3]], align 8 // CHECK-TYPEAUTH-NEXT: ret ptr [[TMP3]] @@ -595,7 +586,7 @@ const void *d_as_A(D *o) { // CHECK-ADDRESSAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-ADDRESSAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 // CHECK-ADDRESSAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]], i32 2, i64 [[TMP1]]) +// CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]]) [ "ptrauth"(i64 2, i64 0, i64 [[TMP1]]) ] // CHECK-ADDRESSAUTH-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr // CHECK-ADDRESSAUTH-NEXT: [[TMP5:%.*]] = load volatile i8, ptr [[TMP4]], align 8 // CHECK-ADDRESSAUTH-NEXT: ret ptr [[TMP4]] @@ -608,9 +599,8 @@ const void *d_as_A(D *o) { // CHECK-BOTHAUTH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[O_ADDR]], align 8, !tbaa [[TBAA17]] // CHECK-BOTHAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-BOTHAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[TMP1]], i64 48388) // CHECK-BOTHAUTH-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]], i32 2, i64 [[TMP2]]) +// CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]]) [ "ptrauth"(i64 2, i64 48388, i64 [[TMP1]]) ] // CHECK-BOTHAUTH-NEXT: [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr // CHECK-BOTHAUTH-NEXT: [[TMP6:%.*]] = load volatile i8, ptr [[TMP5]], align 8 // CHECK-BOTHAUTH-NEXT: ret ptr [[TMP5]] @@ -651,7 +641,7 @@ const void *e(E *o) { // CHECK-TYPEAUTH-NEXT: [[CAST_RESULT:%.*]] = phi ptr [ [[ADD_PTR]], %[[CAST_NOTNULL]] ], [ null, %[[ENTRY]] ] // CHECK-TYPEAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[CAST_RESULT]], align 8, !tbaa [[TBAA9]] // CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-TYPEAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]], i32 2, i64 48388) +// CHECK-TYPEAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]]) [ "ptrauth"(i64 2, i64 48388, i64 0) ] // CHECK-TYPEAUTH-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr // CHECK-TYPEAUTH-NEXT: [[TMP5:%.*]] = load volatile i8, ptr [[TMP4]], align 8 // CHECK-TYPEAUTH-NEXT: ret ptr [[TMP4]] @@ -672,7 +662,7 @@ const void *e(E *o) { // CHECK-ADDRESSAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[CAST_RESULT]], align 8, !tbaa [[TBAA9]] // CHECK-ADDRESSAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[CAST_RESULT]] to i64 // CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-ADDRESSAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]], i32 2, i64 [[TMP2]]) +// CHECK-ADDRESSAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]]) [ "ptrauth"(i64 2, i64 0, i64 [[TMP2]]) ] // CHECK-ADDRESSAUTH-NEXT: [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr // CHECK-ADDRESSAUTH-NEXT: [[TMP6:%.*]] = load volatile i8, ptr [[TMP5]], align 8 // CHECK-ADDRESSAUTH-NEXT: ret ptr [[TMP5]] @@ -692,9 +682,8 @@ const void *e(E *o) { // CHECK-BOTHAUTH-NEXT: [[CAST_RESULT:%.*]] = phi ptr [ [[ADD_PTR]], %[[CAST_NOTNULL]] ], [ null, %[[ENTRY]] ] // CHECK-BOTHAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[CAST_RESULT]], align 8, !tbaa [[TBAA9]] // CHECK-BOTHAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[CAST_RESULT]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[TMP2]], i64 48388) // CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP5:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP4]], i32 2, i64 [[TMP3]]) +// CHECK-BOTHAUTH-NEXT: [[TMP5:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP4]]) [ "ptrauth"(i64 2, i64 48388, i64 [[TMP2]]) ] // CHECK-BOTHAUTH-NEXT: [[TMP6:%.*]] = inttoptr i64 [[TMP5]] to ptr // CHECK-BOTHAUTH-NEXT: [[TMP7:%.*]] = load volatile i8, ptr [[TMP6]], align 8 // CHECK-BOTHAUTH-NEXT: ret ptr [[TMP6]] @@ -721,7 +710,7 @@ const void *e_as_B(E *o) { // CHECK-TYPEAUTH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[O_ADDR]], align 8, !tbaa [[TBAA17]] // CHECK-TYPEAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-TYPEAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]], i32 2, i64 48388) +// CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]]) [ "ptrauth"(i64 2, i64 48388, i64 0) ] // CHECK-TYPEAUTH-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr // CHECK-TYPEAUTH-NEXT: [[TMP4:%.*]] = load volatile i8, ptr [[TMP3]], align 8 // CHECK-TYPEAUTH-NEXT: ret ptr [[TMP3]] @@ -735,7 +724,7 @@ const void *e_as_B(E *o) { // CHECK-ADDRESSAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-ADDRESSAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 // CHECK-ADDRESSAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]], i32 2, i64 [[TMP1]]) +// CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]]) [ "ptrauth"(i64 2, i64 0, i64 [[TMP1]]) ] // CHECK-ADDRESSAUTH-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr // CHECK-ADDRESSAUTH-NEXT: [[TMP5:%.*]] = load volatile i8, ptr [[TMP4]], align 8 // CHECK-ADDRESSAUTH-NEXT: ret ptr [[TMP4]] @@ -748,9 +737,8 @@ const void *e_as_B(E *o) { // CHECK-BOTHAUTH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[O_ADDR]], align 8, !tbaa [[TBAA17]] // CHECK-BOTHAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-BOTHAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[TMP1]], i64 48388) // CHECK-BOTHAUTH-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]], i32 2, i64 [[TMP2]]) +// CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]]) [ "ptrauth"(i64 2, i64 48388, i64 [[TMP1]]) ] // CHECK-BOTHAUTH-NEXT: [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr // CHECK-BOTHAUTH-NEXT: [[TMP6:%.*]] = load volatile i8, ptr [[TMP5]], align 8 // CHECK-BOTHAUTH-NEXT: ret ptr [[TMP5]] @@ -777,7 +765,7 @@ const void *e_as_D(E *o) { // CHECK-TYPEAUTH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[AARRAY_ADDR]], align 8, !tbaa [[TBAA6]] // CHECK-TYPEAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-TYPEAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]], i32 2, i64 48388) +// CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]]) [ "ptrauth"(i64 2, i64 48388, i64 0) ] // CHECK-TYPEAUTH-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr // CHECK-TYPEAUTH-NEXT: [[TMP4:%.*]] = load volatile i8, ptr [[TMP3]], align 8 // CHECK-TYPEAUTH-NEXT: ret ptr [[TMP3]] @@ -791,7 +779,7 @@ const void *e_as_D(E *o) { // CHECK-ADDRESSAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-ADDRESSAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 // CHECK-ADDRESSAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]], i32 2, i64 [[TMP1]]) +// CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]]) [ "ptrauth"(i64 2, i64 0, i64 [[TMP1]]) ] // CHECK-ADDRESSAUTH-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr // CHECK-ADDRESSAUTH-NEXT: [[TMP5:%.*]] = load volatile i8, ptr [[TMP4]], align 8 // CHECK-ADDRESSAUTH-NEXT: ret ptr [[TMP4]] @@ -804,9 +792,8 @@ const void *e_as_D(E *o) { // CHECK-BOTHAUTH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[AARRAY_ADDR]], align 8, !tbaa [[TBAA6]] // CHECK-BOTHAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA9]] // CHECK-BOTHAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[TMP0]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[TMP1]], i64 48388) // CHECK-BOTHAUTH-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]], i32 2, i64 [[TMP2]]) +// CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]]) [ "ptrauth"(i64 2, i64 48388, i64 [[TMP1]]) ] // CHECK-BOTHAUTH-NEXT: [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr // CHECK-BOTHAUTH-NEXT: [[TMP6:%.*]] = load volatile i8, ptr [[TMP5]], align 8 // CHECK-BOTHAUTH-NEXT: ret ptr [[TMP5]] @@ -836,7 +823,7 @@ extern "C" const void *aArrayParameter(A aArray[]) { // CHECK-TYPEAUTH-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [1 x %"struct.test1::A"], ptr [[ARRAY]], i64 0, i64 0 // CHECK-TYPEAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[ARRAYDECAY]], align 8, !tbaa [[TBAA9]] // CHECK-TYPEAUTH-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-TYPEAUTH-NEXT: [[TMP1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP0]], i32 2, i64 48388) +// CHECK-TYPEAUTH-NEXT: [[TMP1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP0]]) [ "ptrauth"(i64 2, i64 48388, i64 0) ] // CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = inttoptr i64 [[TMP1]] to ptr // CHECK-TYPEAUTH-NEXT: [[TMP3:%.*]] = load volatile i8, ptr [[TMP2]], align 8 // CHECK-TYPEAUTH-NEXT: call void @llvm.lifetime.end.p0(ptr [[ARRAY]]) #[[ATTR7]] @@ -852,7 +839,7 @@ extern "C" const void *aArrayParameter(A aArray[]) { // CHECK-ADDRESSAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[ARRAYDECAY]], align 8, !tbaa [[TBAA9]] // CHECK-ADDRESSAUTH-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[ARRAYDECAY]] to i64 // CHECK-ADDRESSAUTH-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-ADDRESSAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]], i32 2, i64 [[TMP0]]) +// CHECK-ADDRESSAUTH-NEXT: [[TMP2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP1]]) [ "ptrauth"(i64 2, i64 0, i64 [[TMP0]]) ] // CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to ptr // CHECK-ADDRESSAUTH-NEXT: [[TMP4:%.*]] = load volatile i8, ptr [[TMP3]], align 8 // CHECK-ADDRESSAUTH-NEXT: call void @llvm.lifetime.end.p0(ptr [[ARRAY]]) #[[ATTR7]] @@ -867,9 +854,8 @@ extern "C" const void *aArrayParameter(A aArray[]) { // CHECK-BOTHAUTH-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [1 x %"struct.test1::A"], ptr [[ARRAY]], i64 0, i64 0 // CHECK-BOTHAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[ARRAYDECAY]], align 8, !tbaa [[TBAA9]] // CHECK-BOTHAUTH-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[ARRAYDECAY]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP1:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[TMP0]], i64 48388) // CHECK-BOTHAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]], i32 2, i64 [[TMP1]]) +// CHECK-BOTHAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]]) [ "ptrauth"(i64 2, i64 48388, i64 [[TMP0]]) ] // CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr // CHECK-BOTHAUTH-NEXT: [[TMP5:%.*]] = load volatile i8, ptr [[TMP4]], align 8 // CHECK-BOTHAUTH-NEXT: call void @llvm.lifetime.end.p0(ptr [[ARRAY]]) #[[ATTR7]] @@ -1018,7 +1004,7 @@ extern "C" const void *aArrayLocal() { // CHECK-TYPEAUTH: [[CAST_NOTNULL9]]: // CHECK-TYPEAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[DINSTANCE]], align 8, !tbaa [[TBAA9]] // CHECK-TYPEAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-TYPEAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]], i32 2, i64 48388) +// CHECK-TYPEAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP2]]) [ "ptrauth"(i64 2, i64 48388, i64 0) ] // CHECK-TYPEAUTH-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr // CHECK-TYPEAUTH-NEXT: [[VBASE_OFFSET_PTR:%.*]] = getelementptr i8, ptr [[TMP4]], i64 -32 // CHECK-TYPEAUTH-NEXT: [[VBASE_OFFSET:%.*]] = load i64, ptr [[VBASE_OFFSET_PTR]], align 8 @@ -1032,7 +1018,7 @@ extern "C" const void *aArrayLocal() { // CHECK-TYPEAUTH: [[CAST_NOTNULL14]]: // CHECK-TYPEAUTH-NEXT: [[VTABLE15:%.*]] = load ptr, ptr [[EINSTANCE]], align 8, !tbaa [[TBAA9]] // CHECK-TYPEAUTH-NEXT: [[TMP6:%.*]] = ptrtoint ptr [[VTABLE15]] to i64 -// CHECK-TYPEAUTH-NEXT: [[TMP7:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP6]], i32 2, i64 48388) +// CHECK-TYPEAUTH-NEXT: [[TMP7:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP6]]) [ "ptrauth"(i64 2, i64 48388, i64 0) ] // CHECK-TYPEAUTH-NEXT: [[TMP8:%.*]] = inttoptr i64 [[TMP7]] to ptr // CHECK-TYPEAUTH-NEXT: [[VBASE_OFFSET_PTR16:%.*]] = getelementptr i8, ptr [[TMP8]], i64 -32 // CHECK-TYPEAUTH-NEXT: [[VBASE_OFFSET17:%.*]] = load i64, ptr [[VBASE_OFFSET_PTR16]], align 8 @@ -1080,7 +1066,7 @@ extern "C" const void *aArrayLocal() { // CHECK-TYPEAUTH-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [1 x %"struct.test1::E"], ptr [[EARRAY]], i64 0, i64 0 // CHECK-TYPEAUTH-NEXT: [[VTABLE49:%.*]] = load ptr, ptr [[ARRAYDECAY]], align 8, !tbaa [[TBAA9]] // CHECK-TYPEAUTH-NEXT: [[TMP12:%.*]] = ptrtoint ptr [[VTABLE49]] to i64 -// CHECK-TYPEAUTH-NEXT: [[TMP13:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP12]], i32 2, i64 48388) +// CHECK-TYPEAUTH-NEXT: [[TMP13:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP12]]) [ "ptrauth"(i64 2, i64 48388, i64 0) ] // CHECK-TYPEAUTH-NEXT: [[TMP14:%.*]] = inttoptr i64 [[TMP13]] to ptr // CHECK-TYPEAUTH-NEXT: [[TMP15:%.*]] = load volatile i8, ptr [[TMP14]], align 8 // CHECK-TYPEAUTH-NEXT: call void @llvm.lifetime.end.p0(ptr [[EARRAY]]) #[[ATTR7]] @@ -1129,7 +1115,7 @@ extern "C" const void *aArrayLocal() { // CHECK-ADDRESSAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[DINSTANCE]], align 8, !tbaa [[TBAA9]] // CHECK-ADDRESSAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[DINSTANCE]] to i64 // CHECK-ADDRESSAUTH-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-ADDRESSAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]], i32 2, i64 [[TMP2]]) +// CHECK-ADDRESSAUTH-NEXT: [[TMP4:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP3]]) [ "ptrauth"(i64 2, i64 0, i64 [[TMP2]]) ] // CHECK-ADDRESSAUTH-NEXT: [[TMP5:%.*]] = inttoptr i64 [[TMP4]] to ptr // CHECK-ADDRESSAUTH-NEXT: [[VBASE_OFFSET_PTR:%.*]] = getelementptr i8, ptr [[TMP5]], i64 -32 // CHECK-ADDRESSAUTH-NEXT: [[VBASE_OFFSET:%.*]] = load i64, ptr [[VBASE_OFFSET_PTR]], align 8 @@ -1144,7 +1130,7 @@ extern "C" const void *aArrayLocal() { // CHECK-ADDRESSAUTH-NEXT: [[VTABLE15:%.*]] = load ptr, ptr [[EINSTANCE]], align 8, !tbaa [[TBAA9]] // CHECK-ADDRESSAUTH-NEXT: [[TMP7:%.*]] = ptrtoint ptr [[EINSTANCE]] to i64 // CHECK-ADDRESSAUTH-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[VTABLE15]] to i64 -// CHECK-ADDRESSAUTH-NEXT: [[TMP9:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP8]], i32 2, i64 [[TMP7]]) +// CHECK-ADDRESSAUTH-NEXT: [[TMP9:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP8]]) [ "ptrauth"(i64 2, i64 0, i64 [[TMP7]]) ] // CHECK-ADDRESSAUTH-NEXT: [[TMP10:%.*]] = inttoptr i64 [[TMP9]] to ptr // CHECK-ADDRESSAUTH-NEXT: [[VBASE_OFFSET_PTR16:%.*]] = getelementptr i8, ptr [[TMP10]], i64 -32 // CHECK-ADDRESSAUTH-NEXT: [[VBASE_OFFSET17:%.*]] = load i64, ptr [[VBASE_OFFSET_PTR16]], align 8 @@ -1193,7 +1179,7 @@ extern "C" const void *aArrayLocal() { // CHECK-ADDRESSAUTH-NEXT: [[VTABLE49:%.*]] = load ptr, ptr [[ARRAYDECAY]], align 8, !tbaa [[TBAA9]] // CHECK-ADDRESSAUTH-NEXT: [[TMP14:%.*]] = ptrtoint ptr [[ARRAYDECAY]] to i64 // CHECK-ADDRESSAUTH-NEXT: [[TMP15:%.*]] = ptrtoint ptr [[VTABLE49]] to i64 -// CHECK-ADDRESSAUTH-NEXT: [[TMP16:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP15]], i32 2, i64 [[TMP14]]) +// CHECK-ADDRESSAUTH-NEXT: [[TMP16:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP15]]) [ "ptrauth"(i64 2, i64 0, i64 [[TMP14]]) ] // CHECK-ADDRESSAUTH-NEXT: [[TMP17:%.*]] = inttoptr i64 [[TMP16]] to ptr // CHECK-ADDRESSAUTH-NEXT: [[TMP18:%.*]] = load volatile i8, ptr [[TMP17]], align 8 // CHECK-ADDRESSAUTH-NEXT: call void @llvm.lifetime.end.p0(ptr [[EARRAY]]) #[[ATTR7]] @@ -1241,9 +1227,8 @@ extern "C" const void *aArrayLocal() { // CHECK-BOTHAUTH: [[CAST_NOTNULL9]]: // CHECK-BOTHAUTH-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[DINSTANCE]], align 8, !tbaa [[TBAA9]] // CHECK-BOTHAUTH-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[DINSTANCE]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP3:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[TMP2]], i64 48388) // CHECK-BOTHAUTH-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP5:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP4]], i32 2, i64 [[TMP3]]) +// CHECK-BOTHAUTH-NEXT: [[TMP5:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP4]]) [ "ptrauth"(i64 2, i64 48388, i64 [[TMP2]]) ] // CHECK-BOTHAUTH-NEXT: [[TMP6:%.*]] = inttoptr i64 [[TMP5]] to ptr // CHECK-BOTHAUTH-NEXT: [[VBASE_OFFSET_PTR:%.*]] = getelementptr i8, ptr [[TMP6]], i64 -32 // CHECK-BOTHAUTH-NEXT: [[VBASE_OFFSET:%.*]] = load i64, ptr [[VBASE_OFFSET_PTR]], align 8 @@ -1257,9 +1242,8 @@ extern "C" const void *aArrayLocal() { // CHECK-BOTHAUTH: [[CAST_NOTNULL14]]: // CHECK-BOTHAUTH-NEXT: [[VTABLE15:%.*]] = load ptr, ptr [[EINSTANCE]], align 8, !tbaa [[TBAA9]] // CHECK-BOTHAUTH-NEXT: [[TMP8:%.*]] = ptrtoint ptr [[EINSTANCE]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP9:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[TMP8]], i64 48388) // CHECK-BOTHAUTH-NEXT: [[TMP10:%.*]] = ptrtoint ptr [[VTABLE15]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP11:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP10]], i32 2, i64 [[TMP9]]) +// CHECK-BOTHAUTH-NEXT: [[TMP11:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP10]]) [ "ptrauth"(i64 2, i64 48388, i64 [[TMP8]]) ] // CHECK-BOTHAUTH-NEXT: [[TMP12:%.*]] = inttoptr i64 [[TMP11]] to ptr // CHECK-BOTHAUTH-NEXT: [[VBASE_OFFSET_PTR16:%.*]] = getelementptr i8, ptr [[TMP12]], i64 -32 // CHECK-BOTHAUTH-NEXT: [[VBASE_OFFSET17:%.*]] = load i64, ptr [[VBASE_OFFSET_PTR16]], align 8 @@ -1307,9 +1291,8 @@ extern "C" const void *aArrayLocal() { // CHECK-BOTHAUTH-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [1 x %"struct.test1::E"], ptr [[EARRAY]], i64 0, i64 0 // CHECK-BOTHAUTH-NEXT: [[VTABLE49:%.*]] = load ptr, ptr [[ARRAYDECAY]], align 8, !tbaa [[TBAA9]] // CHECK-BOTHAUTH-NEXT: [[TMP16:%.*]] = ptrtoint ptr [[ARRAYDECAY]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP17:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[TMP16]], i64 48388) // CHECK-BOTHAUTH-NEXT: [[TMP18:%.*]] = ptrtoint ptr [[VTABLE49]] to i64 -// CHECK-BOTHAUTH-NEXT: [[TMP19:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP18]], i32 2, i64 [[TMP17]]) +// CHECK-BOTHAUTH-NEXT: [[TMP19:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP18]]) [ "ptrauth"(i64 2, i64 48388, i64 [[TMP16]]) ] // CHECK-BOTHAUTH-NEXT: [[TMP20:%.*]] = inttoptr i64 [[TMP19]] to ptr // CHECK-BOTHAUTH-NEXT: [[TMP21:%.*]] = load volatile i8, ptr [[TMP20]], align 8 // CHECK-BOTHAUTH-NEXT: call void @llvm.lifetime.end.p0(ptr [[EARRAY]]) #[[ATTR7]] diff --git a/clang/test/CodeGenCXX/mangle-itanium-ptrauth.cpp b/clang/test/CodeGenCXX/mangle-itanium-ptrauth.cpp index 155b766803a0a..14c7c118d3b60 100644 --- a/clang/test/CodeGenCXX/mangle-itanium-ptrauth.cpp +++ b/clang/test/CodeGenCXX/mangle-itanium-ptrauth.cpp @@ -5,7 +5,7 @@ // clang previously emitted an incorrect discriminator for the member function // pointer because of a bug in the mangler. -// CHECK: @_ZN17test_substitution5funcsE = global [1 x { i64, i64 }] [{ i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN17test_substitution1S1fEPvS1_, i32 0, i64 48995) to i64), i64 0 }], align 8 +// CHECK: @_ZN17test_substitution5funcsE = global [1 x { i64, i64 }] [{ i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN17test_substitution1S1fEPvS1_, [i64 0, i64 48995, i64 0]) to i64), i64 0 }], align 8 namespace test_substitution { struct S { int f(void *, void *); }; diff --git a/clang/test/CodeGenCXX/ptrauth-apple-kext-indirect-call-2.cpp b/clang/test/CodeGenCXX/ptrauth-apple-kext-indirect-call-2.cpp index c2f20d56b0a6b..c1a9093ffdf57 100644 --- a/clang/test/CodeGenCXX/ptrauth-apple-kext-indirect-call-2.cpp +++ b/clang/test/CodeGenCXX/ptrauth-apple-kext-indirect-call-2.cpp @@ -1,9 +1,9 @@ // RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fapple-kext -fno-rtti -emit-llvm -o - %s | FileCheck %s -// CHECK: @_ZTV1A = unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZNK1A3abcEv, i32 0, i64 12401, ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 2)), ptr null] }, align 8 -// CHECK: @_ZTV4Base = unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZNK4Base3abcEv, i32 0, i64 64320, ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV4Base, i32 0, i32 0, i32 2)), ptr null] }, align 8 -// CHECK: @_ZTV8Derived2 = unnamed_addr constant { [5 x ptr] } { [5 x ptr] [ptr null, ptr null, ptr null, ptr ptrauth (ptr @_ZNK8Derived23efgEv, i32 0, i64 36603, ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 0, i32 3)), ptr null] }, align 8 -// CHECK: @_ZTV2D2 = unnamed_addr constant { [5 x ptr] } { [5 x ptr] [ptr null, ptr null, ptr null, ptr ptrauth (ptr @_ZNK2D23abcEv, i32 0, i64 20222, ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 3)), ptr null] }, align 8 +// CHECK: @_ZTV1A = unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZNK1A3abcEv, [i64 0, i64 12401, i64 ptrtoint (ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 2) to i64)]), ptr null] }, align 8 +// CHECK: @_ZTV4Base = unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZNK4Base3abcEv, [i64 0, i64 64320, i64 ptrtoint (ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV4Base, i32 0, i32 0, i32 2) to i64)]), ptr null] }, align 8 +// CHECK: @_ZTV8Derived2 = unnamed_addr constant { [5 x ptr] } { [5 x ptr] [ptr null, ptr null, ptr null, ptr ptrauth (ptr @_ZNK8Derived23efgEv, [i64 0, i64 36603, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 0, i32 3) to i64)]), ptr null] }, align 8 +// CHECK: @_ZTV2D2 = unnamed_addr constant { [5 x ptr] } { [5 x ptr] [ptr null, ptr null, ptr null, ptr ptrauth (ptr @_ZNK2D23abcEv, [i64 0, i64 20222, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 3) to i64)]), ptr null] }, align 8 struct A { virtual const char* abc(void) const; @@ -19,8 +19,7 @@ void B::VF() {} void FUNC(B* p) { // CHECK: [[T1:%.*]] = load ptr, ptr getelementptr inbounds (ptr, ptr @_ZTV1A, i64 2) -// CHECK-NEXT: [[BT1:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr getelementptr inbounds (ptr, ptr @_ZTV1A, i64 2) to i64), i64 12401) -// CHECK-NEXT: [[T2:%.*]] = call noundef ptr [[T1]](ptr noundef {{.*}}) [ "ptrauth"(i32 0, i64 [[BT1]]) ] +// CHECK-NEXT: [[T2:%.*]] = call noundef ptr [[T1]](ptr noundef {{.*}}) [ "ptrauth"(i64 0, i64 12401, i64 ptrtoint (ptr getelementptr inbounds (ptr, ptr @_ZTV1A, i64 2) to i64)) ] const char* c = p->A::abc(); } @@ -35,8 +34,7 @@ struct Derived : public Base { void FUNC1(Derived* p) { // CHECK: [[U1:%.*]] = load ptr, ptr getelementptr inbounds (ptr, ptr @_ZTV4Base, i64 2) -// CHECK-NEXT: [[BU1:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr getelementptr inbounds (ptr, ptr @_ZTV4Base, i64 2) to i64), i64 64320) -// CHECK-NEXT: [[U2:%.*]] = call noundef ptr [[U1]](ptr noundef {{.*}}) [ "ptrauth"(i32 0, i64 [[BU1]]) ] +// CHECK-NEXT: [[U2:%.*]] = call noundef ptr [[U1]](ptr noundef {{.*}}) [ "ptrauth"(i64 0, i64 64320, i64 ptrtoint (ptr getelementptr inbounds (ptr, ptr @_ZTV4Base, i64 2) to i64)) ] char* c = p->Base::abc(); } @@ -52,8 +50,7 @@ char* Derived2::efg(void) const { return 0; } void FUNC2(Derived2* p) { // CHECK: [[V1:%.*]] = load ptr, ptr getelementptr inbounds (ptr, ptr @_ZTV8Derived2, i64 3) -// CHECK-NEXT: [[BV1:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr getelementptr inbounds (ptr, ptr @_ZTV8Derived2, i64 3) to i64), i64 36603) -// CHECK-NEXT: [[V2:%.*]] = call noundef ptr [[V1]](ptr noundef {{.*}}) [ "ptrauth"(i32 0, i64 [[BV1]]) ] +// CHECK-NEXT: [[V2:%.*]] = call noundef ptr [[V1]](ptr noundef {{.*}}) [ "ptrauth"(i64 0, i64 36603, i64 ptrtoint (ptr getelementptr inbounds (ptr, ptr @_ZTV8Derived2, i64 3) to i64)) ] char* c = p->Derived2::efg(); } @@ -74,8 +71,7 @@ char* D2::abc(void) const { return 0; } void FUNC3(Sub* p) { // CHECK: [[W1:%.*]] = load ptr, ptr getelementptr inbounds (ptr, ptr @_ZTV2D2, i64 3) -// CHECK-NEXT: [[BW1:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr getelementptr inbounds (ptr, ptr @_ZTV2D2, i64 3) to i64), i64 20222) -// CHECK-NEXT: [[W2:%.*]] = call noundef ptr [[W1]](ptr noundef {{.*}}) [ "ptrauth"(i32 0, i64 [[BW1]]) ] +// CHECK-NEXT: [[W2:%.*]] = call noundef ptr [[W1]](ptr noundef {{.*}}) [ "ptrauth"(i64 0, i64 20222, i64 ptrtoint (ptr getelementptr inbounds (ptr, ptr @_ZTV2D2, i64 3) to i64)) ] char* c = p->D2::abc(); } @@ -94,12 +90,11 @@ void Derived4::abc() {} void FUNC4(Derived4* p) { // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) +// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 0 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 426) -// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %{{.*}}) [ "ptrauth"(i64 0, i64 426, i64 %[[T6]]) ] p->abc(); } diff --git a/clang/test/CodeGenCXX/ptrauth-apple-kext-indirect-call.cpp b/clang/test/CodeGenCXX/ptrauth-apple-kext-indirect-call.cpp index 996829a14d7d1..1f2fb516ef5df 100644 --- a/clang/test/CodeGenCXX/ptrauth-apple-kext-indirect-call.cpp +++ b/clang/test/CodeGenCXX/ptrauth-apple-kext-indirect-call.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fapple-kext -emit-llvm -o - %s | FileCheck %s -// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant { [5 x ptr] } { [5 x ptr] [ptr null, ptr @_ZTI5TemplIiE, ptr ptrauth (ptr @_ZN5TemplIiE1fEv, i32 0, i64 22189, ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV5TemplIiE, i32 0, i32 0, i32 2)), ptr ptrauth (ptr @_ZN5TemplIiE1gEv, i32 0, i64 9912, ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV5TemplIiE, i32 0, i32 0, i32 3)), ptr null] }, align 8 +// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant { [5 x ptr] } { [5 x ptr] [ptr null, ptr @_ZTI5TemplIiE, ptr ptrauth (ptr @_ZN5TemplIiE1fEv, [i64 0, i64 22189, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV5TemplIiE, i32 0, i32 0, i32 2) to i64)]), ptr ptrauth (ptr @_ZN5TemplIiE1gEv, [i64 0, i64 9912, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV5TemplIiE, i32 0, i32 0, i32 3) to i64)]), ptr null] }, align 8 struct Base { virtual void abc(void) const; diff --git a/clang/test/CodeGenCXX/ptrauth-apple-kext-indirect-virtual-dtor-call.cpp b/clang/test/CodeGenCXX/ptrauth-apple-kext-indirect-virtual-dtor-call.cpp index 7bcf1fbfdb9de..470b91f336784 100644 --- a/clang/test/CodeGenCXX/ptrauth-apple-kext-indirect-virtual-dtor-call.cpp +++ b/clang/test/CodeGenCXX/ptrauth-apple-kext-indirect-virtual-dtor-call.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -triple arm64-apple-ios -std=c++98 -fptrauth-calls -fapple-kext -fno-rtti -disable-O0-optnone -emit-llvm -o - %s | FileCheck %s -// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant { [7 x ptr] } { [7 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZN5TemplIiED1Ev, i32 0, i64 57986, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV5TemplIiE, i32 0, i32 0, i32 2)), ptr ptrauth (ptr @_ZN5TemplIiED0Ev, i32 0, i64 22856, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV5TemplIiE, i32 0, i32 0, i32 3)), ptr ptrauth (ptr @_ZN5TemplIiE1fEv, i32 0, i64 22189, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV5TemplIiE, i32 0, i32 0, i32 4)), ptr ptrauth (ptr @_ZN5TemplIiE1gEv, i32 0, i64 9912, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV5TemplIiE, i32 0, i32 0, i32 5)), ptr null] }, align 8 +// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant { [7 x ptr] } { [7 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZN5TemplIiED1Ev, [i64 0, i64 57986, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV5TemplIiE, i32 0, i32 0, i32 2) to i64)]), ptr ptrauth (ptr @_ZN5TemplIiED0Ev, [i64 0, i64 22856, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV5TemplIiE, i32 0, i32 0, i32 3) to i64)]), ptr ptrauth (ptr @_ZN5TemplIiE1fEv, [i64 0, i64 22189, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV5TemplIiE, i32 0, i32 0, i32 4) to i64)]), ptr ptrauth (ptr @_ZN5TemplIiE1gEv, [i64 0, i64 9912, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV5TemplIiE, i32 0, i32 0, i32 5) to i64)]), ptr null] }, align 8 struct B1 { virtual ~B1(); @@ -13,12 +13,10 @@ void DELETE(B1 *pb1) { } // CHECK-LABEL: define void @_ZN2B1D0Ev // CHECK: [[T1:%.*]] = load ptr, ptr getelementptr inbounds (ptr, ptr @_ZTV2B1, i64 2) -// CHECK-NEXT: [[B1:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr getelementptr inbounds (ptr, ptr @_ZTV2B1, i64 2) to i64), i64 14635) -// CHECK-NEXT: call noundef ptr [[T1]](ptr noundef nonnull align 8 dereferenceable(8) [[T2:%.*]]) [ "ptrauth"(i32 0, i64 [[B1]]) ] +// CHECK-NEXT: call noundef ptr [[T1]](ptr noundef nonnull align 8 dereferenceable(8) [[T2:%.*]]) [ "ptrauth"(i64 0, i64 14635, i64 ptrtoint (ptr getelementptr inbounds (ptr, ptr @_ZTV2B1, i64 2) to i64)) ] // CHECK-LABEL: define void @_Z6DELETEP2B1 // CHECK: [[T3:%.*]] = load ptr, ptr getelementptr inbounds (ptr, ptr @_ZTV2B1, i64 2) -// CHECK-NEXT: [[B3:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr getelementptr inbounds (ptr, ptr @_ZTV2B1, i64 2) to i64), i64 14635) -// CHECK-NEXT: call noundef ptr [[T3]](ptr noundef nonnull align 8 dereferenceable(8) [[T4:%.*]]) [ "ptrauth"(i32 0, i64 [[B3]]) +// CHECK-NEXT: call noundef ptr [[T3]](ptr noundef nonnull align 8 dereferenceable(8) [[T4:%.*]]) [ "ptrauth"(i64 0, i64 14635, i64 ptrtoint (ptr getelementptr inbounds (ptr, ptr @_ZTV2B1, i64 2) to i64)) template struct Templ { diff --git a/clang/test/CodeGenCXX/ptrauth-dynamic-cast-exact.cpp b/clang/test/CodeGenCXX/ptrauth-dynamic-cast-exact.cpp index 1710ca5563380..9b7b1eabde6ad 100644 --- a/clang/test/CodeGenCXX/ptrauth-dynamic-cast-exact.cpp +++ b/clang/test/CodeGenCXX/ptrauth-dynamic-cast-exact.cpp @@ -47,9 +47,8 @@ struct M final: G, private H { int m; }; C *exact_to_C(A *a) { // CHECK: [[UNAUTHED_VPTR:%.*]] = load ptr, ptr %a, align 8 // CHECK: [[VPTR_ADDRI:%.*]] = ptrtoint ptr %a to i64 - // CHECK: [[VPTR_ADDR_DISC:%.*]] = tail call i64 @llvm.ptrauth.blend(i64 [[VPTR_ADDRI]], i64 62866) // CHECK: [[UNAUTHED_VPTRI:%.*]] = ptrtoint ptr [[UNAUTHED_VPTR]] to i64 - // CHECK: [[AUTHED_VPTRI:%.*]] = tail call i64 @llvm.ptrauth.auth(i64 [[UNAUTHED_VPTRI]], i32 2, i64 [[VPTR_ADDR_DISC]]) + // CHECK: [[AUTHED_VPTRI:%.*]] = tail call i64 @llvm.ptrauth.auth(i64 [[UNAUTHED_VPTRI]]) [ "ptrauth"(i64 2, i64 62866, i64 [[VPTR_ADDRI]]) ] // CHECK: [[IS_EXPECTED:%.*]] = icmp eq i64 [[AUTHED_VPTRI]], ptrtoint (ptr getelementptr inbounds nuw inrange(-16, 24) (i8, ptr @_ZTV1C, i64 16) to i64) // CHECK: br i1 [[IS_EXPECTED]], label %dynamic_cast.end, label %dynamic_cast.null // CHECK: [[NULL_CHECKED_RESULT:%.*]] = phi ptr [ %a, %dynamic_cast.notnull ], [ null, %dynamic_cast.null ] @@ -62,18 +61,16 @@ D *exact_t_D(A *a) { // CHECK: dynamic_cast.notnull: // CHECK: [[SRC_UNAUTHED_VPTR:%.*]] = load ptr, ptr %a // CHECK: [[SRC_VPTR_ADDRI:%.*]] = ptrtoint ptr %a to i64 - // CHECK: [[SRC_VPTR_DISC:%.*]] = tail call i64 @llvm.ptrauth.blend(i64 [[SRC_VPTR_ADDRI]], i64 62866) // CHECK: [[SRC_UNAUTHED_VPTRI:%.*]] = ptrtoint ptr [[SRC_UNAUTHED_VPTR]] to i64 - // CHECK: [[SRC_AUTHED_VPTRI:%.*]] = tail call i64 @llvm.ptrauth.auth(i64 [[SRC_UNAUTHED_VPTRI]], i32 2, i64 [[SRC_VPTR_DISC]]) + // CHECK: [[SRC_AUTHED_VPTRI:%.*]] = tail call i64 @llvm.ptrauth.auth(i64 [[SRC_UNAUTHED_VPTRI]]) [ "ptrauth"(i64 2, i64 62866, i64 [[SRC_VPTR_ADDRI]]) ] // CHECK: [[SUCCESS:%.*]] = icmp eq i64 [[SRC_AUTHED_VPTRI]], ptrtoint (ptr getelementptr inbounds nuw inrange(-16, 16) (i8, ptr @_ZTV1D, i64 56) to i64) // CHECK: br i1 [[SUCCESS]], label %dynamic_cast.postauth.success, label %dynamic_cast.postauth.complete // CHECK: dynamic_cast.postauth.success: // CHECK: [[ADJUSTED_THIS:%.*]] = getelementptr inbounds i8, ptr %a, i64 -16 // CHECK: [[ADJUSTED_UNAUTHED_VPTR:%.*]] = load ptr, ptr [[ADJUSTED_THIS]] // CHECK: [[ADJUSTED_VPTR_ADDRI:%.*]] = ptrtoint ptr [[ADJUSTED_THIS]] to i64 - // CHECK: [[ADJUSTED_VPTR_DISC:%.*]] = tail call i64 @llvm.ptrauth.blend(i64 [[ADJUSTED_VPTR_ADDRI]], i64 28965) // CHECK: [[ADJUSTED_UNAUTHED_VPTRI:%.*]] = ptrtoint ptr [[ADJUSTED_UNAUTHED_VPTR]] to i64 - // CHECK: [[ADJUSTED_AUTHED_VPTRI:%.*]] = tail call i64 @llvm.ptrauth.auth(i64 [[ADJUSTED_UNAUTHED_VPTRI]], i32 2, i64 [[ADJUSTED_VPTR_DISC]]) + // CHECK: [[ADJUSTED_AUTHED_VPTRI:%.*]] = tail call i64 @llvm.ptrauth.auth(i64 [[ADJUSTED_UNAUTHED_VPTRI]]) [ "ptrauth"(i64 2, i64 28965, i64 [[ADJUSTED_VPTR_ADDRI]]) ] // CHECK: [[ADJUSTED_AUTHED_VPTR:%.*]] = inttoptr i64 [[ADJUSTED_AUTHED_VPTRI]] to ptr // CHECK: br label %dynamic_cast.postauth.complete // CHECK: dynamic_cast.postauth.complete: @@ -92,22 +89,20 @@ L *exact_multi(E *e) { // CHECK: dynamic_cast.notnull: // CHECK: [[VTABLE_ADDR:%.*]] = load ptr, ptr %e, align 8 // CHECK: [[THIS_ADDRI:%.*]] = ptrtoint ptr %e to i64 - // CHECK: [[VTABLE_DISC:%.*]] = tail call i64 @llvm.ptrauth.blend(i64 [[THIS_ADDRI]], i64 12810) // CHECK: [[VTABLE_ADDRI:%.*]] = ptrtoint ptr [[VTABLE_ADDR]] to i64 - // CHECK: [[AUTHED_VTABLEI:%.*]] = tail call i64 @llvm.ptrauth.auth(i64 [[VTABLE_ADDRI]], i32 2, i64 [[VTABLE_DISC]]) + // CHECK: [[AUTHED_VTABLEI:%.*]] = tail call i64 @llvm.ptrauth.auth(i64 [[VTABLE_ADDRI]]) [ "ptrauth"(i64 2, i64 12810, i64 [[THIS_ADDRI]]) ] // CHECK: [[AUTHED_VTABLE:%.*]] = inttoptr i64 [[AUTHED_VTABLEI]] to ptr // CHECK: [[PRIMARY_BASE_OFFSET:%.*]] = getelementptr inbounds i8, ptr [[AUTHED_VTABLE]], i64 -16 // CHECK: %offset.to.top = load i64, ptr [[PRIMARY_BASE_OFFSET]] // CHECK: [[ADJUSTED_THIS:%.*]] = getelementptr inbounds i8, ptr %e, i64 %offset.to.top // CHECK: [[ADJUSTED_THIS_VTABLE:%.*]] = load ptr, ptr [[ADJUSTED_THIS]] // CHECK: [[ADJUSTED_THIS_VTABLEI:%.*]] = ptrtoint ptr [[ADJUSTED_THIS_VTABLE]] to i64 - // CHECK: [[ADJUSTED_THIS_STRIPPED_VTABLEI:%.*]] = tail call i64 @llvm.ptrauth.strip(i64 [[ADJUSTED_THIS_VTABLEI]], i32 0) + // CHECK: [[ADJUSTED_THIS_STRIPPED_VTABLEI:%.*]] = tail call i64 @llvm.ptrauth.strip(i64 [[ADJUSTED_THIS_VTABLEI]]) [ "ptrauth"(i64 0) ] // CHECK: [[SUCCESS:%.*]] = icmp eq i64 [[ADJUSTED_THIS_STRIPPED_VTABLEI]], ptrtoint (ptr getelementptr inbounds nuw inrange(-24, 16) (i8, ptr @_ZTV1L, i64 24) to i64) // CHECK: br i1 [[SUCCESS]], label %dynamic_cast.postauth.success, label %dynamic_cast.postauth.complete // CHECK: dynamic_cast.postauth.success: // CHECK: [[ADJUSTED_THISI:%.*]] = ptrtoint ptr [[ADJUSTED_THIS]] to i64 - // CHECK: [[DEST_DISC:%.*]] = tail call i64 @llvm.ptrauth.blend(i64 [[ADJUSTED_THISI]], i64 41434) - // CHECK: tail call i64 @llvm.ptrauth.auth(i64 [[ADJUSTED_THIS_VTABLEI]], i32 2, i64 [[DEST_DISC]]) + // CHECK: tail call i64 @llvm.ptrauth.auth(i64 [[ADJUSTED_THIS_VTABLEI]]) [ "ptrauth"(i64 2, i64 41434, i64 [[ADJUSTED_THISI]]) ] // CHECK: br label %dynamic_cast.postauth.complete // CHECK: dynamic_cast.postauth.complete: // CHECK: [[AUTHED_ADJUSTED_THIS:%.*]] = phi ptr [ [[ADJUSTED_THIS]], %dynamic_cast.postauth.success ], [ null, %dynamic_cast.notnull ] diff --git a/clang/test/CodeGenCXX/ptrauth-explicit-vtable-pointer-control.cpp b/clang/test/CodeGenCXX/ptrauth-explicit-vtable-pointer-control.cpp index e33525c1ec0f9..2d908e4007b3b 100644 --- a/clang/test/CodeGenCXX/ptrauth-explicit-vtable-pointer-control.cpp +++ b/clang/test/CodeGenCXX/ptrauth-explicit-vtable-pointer-control.cpp @@ -79,9 +79,9 @@ struct authenticated(default_key, default_address_discrimination, custom_discrim }; // CHECK: @_ZTVN5test19ConstEvalE = external unnamed_addr constant { [3 x ptr] }, align 8 -// CHECK: @_ZN5test12ceE = global %{{.*}} { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5test19ConstEvalE, i32 0, i32 0, i32 2), i32 2, i64 0, ptr @_ZN5test12ceE) }, align 8 -// CHECK: @_ZTVN5test116ConstEvalDerivedE = linkonce_odr unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr @_ZTIN5test116ConstEvalDerivedE, ptr ptrauth (ptr @_ZN5test19ConstEval1fEv, i32 0, i64 26259, ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN5test116ConstEvalDerivedE, i32 0, i32 0, i32 2))] },{{.*}}align 8 -// CHECK: @_ZN5test13cedE = global { ptr } { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5test116ConstEvalDerivedE, i32 0, i32 0, i32 2), i32 2, i64 0, ptr @_ZN5test13cedE) }, align 8 +// CHECK: @_ZN5test12ceE = global %{{.*}} { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5test19ConstEvalE, i32 0, i32 0, i32 2), [i64 2, i64 0, i64 ptrtoint (ptr @_ZN5test12ceE to i64)]) }, align 8 +// CHECK: @_ZTVN5test116ConstEvalDerivedE = linkonce_odr unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr @_ZTIN5test116ConstEvalDerivedE, ptr ptrauth (ptr @_ZN5test19ConstEval1fEv, [i64 0, i64 26259, i64 ptrtoint (ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN5test116ConstEvalDerivedE, i32 0, i32 0, i32 2) to i64)])] },{{.*}}align 8 +// CHECK: @_ZN5test13cedE = global { ptr } { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5test116ConstEvalDerivedE, i32 0, i32 0, i32 2), [i64 2, i64 0, i64 ptrtoint (ptr @_ZN5test13cedE to i64)]) }, align 8 struct authenticated(default_key, address_discrimination, no_extra_discrimination) ConstEval { consteval ConstEval() {} @@ -153,19 +153,18 @@ int TVDisc_ExplicitTypeDiscrimination = ptrauth_string_discriminator("_ZTVN5test // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_DEFAULT]]) +// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_DEFAULT]], i64 0) ] // // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) +// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 [[VTADDRI64]]) ] // // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_DEFAULT]]) // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_DEFAULT]], i64 [[VTADDRI64]]) ] void test_default(NoExplicitAuth *a) { a->f(); } @@ -184,21 +183,19 @@ void test_disabled(ExplicitlyDisableAuth *a) { // // NODISC: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 [[VTADDRI64]]) ] // // TYPE: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// TYPE: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_ADDR]]) // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_ADDR]], i64 [[VTADDRI64]]) ] // // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) +// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 [[VTADDRI64]]) ] // // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_ADDR]]) // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_ADDR]], i64 [[VTADDRI64]]) ] void test_addr_disc(ExplicitAddressDiscrimination *a) { a->f(); } @@ -208,16 +205,16 @@ void test_addr_disc(ExplicitAddressDiscrimination *a) { // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_NO_ADDR]]) +// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_NO_ADDR]], i64 0) ] // // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) +// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_NO_ADDR]]) +// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_NO_ADDR]], i64 0) ] void test_no_addr_disc(ExplicitNoAddressDiscrimination *a) { a->f(); } @@ -227,18 +224,18 @@ void test_no_addr_disc(ExplicitNoAddressDiscrimination *a) { // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) +// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) +// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 [[VTADDRI64]]) ] // // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) +// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 [[VTADDRI64]]) ] void test_no_extra_disc(ExplicitNoExtraDiscrimination *a) { a->f(); } @@ -248,20 +245,18 @@ void test_no_extra_disc(ExplicitNoExtraDiscrimination *a) { // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_TYPE]]) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_TYPE]], i64 0) ] // // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_TYPE]]) +// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_TYPE]], i64 0) ] // // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_TYPE]]) // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_TYPE]], i64 [[VTADDRI64]]) ] // // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_TYPE]]) // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_TYPE]], i64 [[VTADDRI64]]) ] void test_type_disc(ExplicitTypeDiscrimination *a) { a->f(); } @@ -271,20 +266,18 @@ void test_type_disc(ExplicitTypeDiscrimination *a) { // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 0) ] // // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424) +// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 0) ] // // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424) // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 [[VTADDRI64]]) ] // // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424) // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 [[VTADDRI64]]) ] void test_custom_disc(ExplicitCustomDiscrimination *a) { a->f(); } @@ -299,19 +292,18 @@ void test_custom_disc(ExplicitCustomDiscrimination *a) { // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_DEFAULT]]) +// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_DEFAULT]], i64 0) ] // // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) +// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 [[VTADDRI64]]) ] // // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_DEFAULT]]) // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_DEFAULT]], i64 [[VTADDRI64]]) ] void test_subclass_default(NoExplicitAuth *a) { make_subclass(a)->f(); } @@ -330,21 +322,19 @@ void test_subclass_disabled(ExplicitlyDisableAuth *a) { // // NODISC: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 [[VTADDRI64]]) ] // // TYPE: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// TYPE: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_ADDR]]) // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_ADDR]], i64 [[VTADDRI64]]) ] // // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) +// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 [[VTADDRI64]]) ] // // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_ADDR]]) // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_ADDR]], i64 [[VTADDRI64]]) ] void test_subclass_addr_disc(ExplicitAddressDiscrimination *a) { make_subclass(a)->f(); } @@ -354,16 +344,16 @@ void test_subclass_addr_disc(ExplicitAddressDiscrimination *a) { // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_NO_ADDR]]) +// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_NO_ADDR]], i64 0) ] // // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) +// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_NO_ADDR]]) +// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_NO_ADDR]], i64 0) ] void test_subclass_no_addr_disc(ExplicitNoAddressDiscrimination *a) { make_subclass(a)->f(); } @@ -373,18 +363,18 @@ void test_subclass_no_addr_disc(ExplicitNoAddressDiscrimination *a) { // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) +// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) +// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 [[VTADDRI64]]) ] // // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) +// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 [[VTADDRI64]]) ] void test_subclass_no_extra_disc(ExplicitNoExtraDiscrimination *a) { make_subclass(a)->f(); } @@ -394,20 +384,18 @@ void test_subclass_no_extra_disc(ExplicitNoExtraDiscrimination *a) { // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_TYPE]]) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_TYPE]], i64 0) ] // // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_TYPE]]) +// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_TYPE]], i64 0) ] // // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_TYPE]]) // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_TYPE]], i64 [[VTADDRI64]]) ] // // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_TYPE]]) // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_TYPE]], i64 [[VTADDRI64]]) ] void test_subclass_type_disc(ExplicitTypeDiscrimination *a) { make_subclass(a)->f(); } @@ -417,20 +405,18 @@ void test_subclass_type_disc(ExplicitTypeDiscrimination *a) { // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 0) ] // // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424) +// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 0) ] // // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424) // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 [[VTADDRI64]]) ] // // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424) // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 [[VTADDRI64]]) ] void test_subclass_custom_disc(ExplicitCustomDiscrimination *a) { make_subclass(a)->f(); } @@ -447,19 +433,18 @@ void test_subclass_custom_disc(ExplicitCustomDiscrimination *a) { // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_DEFAULT]]) +// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_DEFAULT]], i64 0) ] // // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) +// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 [[VTADDRI64]]) ] // // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_DEFAULT]]) // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_DEFAULT]], i64 [[VTADDRI64]]) ] void test_multiple_default(NoExplicitAuth *a) { make_multiple_primary(a)->f(); } @@ -479,20 +464,18 @@ void test_multiple_disabled(ExplicitlyDisableAuth *a) { // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 0) ] // // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424) +// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 0) ] // // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424) // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 [[VTADDRI64]]) ] // // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424) // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 [[VTADDRI64]]) ] void test_multiple_custom_disc(ExplicitCustomDiscrimination *a) { make_multiple_primary(a)->f(); } @@ -508,19 +491,18 @@ void test_multiple_custom_disc(ExplicitCustomDiscrimination *a) { // CHECK: [[VTTABLE:%.*]] = load ptr, ptr [[VTTADDR]], align 8 // // NODISC: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 0) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // // TYPE: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64 -// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[DISC_DEFAULT]]) +// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_DEFAULT]], i64 0) ] // // ADDR: [[VTTADDRI64:%.*]] = ptrtoint ptr [[VTTADDR]] to i64 // ADDR: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64 -// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[VTTADDRI64]]) +// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 [[VTTADDRI64]]) ] // // BOTH: [[VTTADDRI64:%.*]] = ptrtoint ptr [[VTTADDR]] to i64 -// BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTTADDRI64]], i64 [[DISC_DEFAULT]]) // BOTH: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64 -// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[BLEND]]) +// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_DEFAULT]], i64 [[VTTADDRI64]]) ] // CHECK: [[AUTHEDPTR:%.*]] = inttoptr i64 [[AUTHED]] to ptr // CHECK: [[VBOFFPTR:%.*]] = getelementptr i8, ptr [[AUTHEDPTR]], i64 -48 @@ -529,19 +511,18 @@ void test_multiple_custom_disc(ExplicitCustomDiscrimination *a) { // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 0) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[DISC_DEFAULT]]) +// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_DEFAULT]], i64 0) ] // // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[VTADDRI64]]) +// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 0, i64 [[VTADDRI64]]) ] // // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 [[DISC_DEFAULT]]) // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 [[DISC_DEFAULT]], i64 [[VTADDRI64]]) ] void test_virtual_default(NoExplicitAuth *a) { make_virtual_primary(a)->f(); } @@ -557,20 +538,18 @@ void test_virtual_disabled(ExplicitlyDisableAuth *a) { // CHECK: [[VTTABLE:%.*]] = load ptr, ptr [[VTTADDR]], align 8 // // NODISC: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 42424) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 0) ] // // TYPE: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64 -// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 42424) +// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 0) ] // // ADDR: [[VTTADDRI64:%.*]] = ptrtoint ptr [[VTTADDR]] to i64 -// ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTTADDRI64]], i64 42424) // ADDR: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64 -// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[BLEND]]) +// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 [[VTTADDRI64]]) ] // // BOTH: [[VTTADDRI64:%.*]] = ptrtoint ptr [[VTTADDR]] to i64 -// BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTTADDRI64]], i64 42424) // BOTH: [[VTTABLEI64:%.*]] = ptrtoint ptr [[VTTABLE]] to i64 -// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]], i32 2, i64 [[BLEND]]) +// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 [[VTTADDRI64]]) ] // CHECK: [[AUTHEDPTR:%.*]] = inttoptr i64 [[AUTHED]] to ptr // CHECK: [[VBOFFPTR:%.*]] = getelementptr i8, ptr [[AUTHEDPTR]], i64 -48 @@ -579,20 +558,18 @@ void test_virtual_disabled(ExplicitlyDisableAuth *a) { // CHECK: [[VTABLE:%.*]] = load ptr, ptr [[VTADDR]], align 8 // // NODISC: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 0) ] // // TYPE: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 42424) +// TYPE: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 0) ] // // ADDR: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// ADDR: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424) // ADDR: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// ADDR: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 [[VTADDRI64]]) ] // // BOTH: [[VTADDRI64:%.*]] = ptrtoint ptr [[VTADDR]] to i64 -// BOTH: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[VTADDRI64]], i64 42424) // BOTH: [[VTABLEI64:%.*]] = ptrtoint ptr [[VTABLE]] to i64 -// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]], i32 2, i64 [[BLEND]]) +// BOTH: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VTABLEI64]]) [ "ptrauth"(i64 2, i64 42424, i64 [[VTADDRI64]]) ] void test_virtual_custom_disc(ExplicitCustomDiscrimination *a) { make_virtual_primary(a)->f(); } diff --git a/clang/test/CodeGenCXX/ptrauth-global-constant-initializers.cpp b/clang/test/CodeGenCXX/ptrauth-global-constant-initializers.cpp index 9ce9def6156ef..7c01ed09fa60c 100644 --- a/clang/test/CodeGenCXX/ptrauth-global-constant-initializers.cpp +++ b/clang/test/CodeGenCXX/ptrauth-global-constant-initializers.cpp @@ -9,27 +9,27 @@ // CHECK: %struct.Derived2 = type { %struct.Base2, %struct.Base1 } // CHECK: %struct.Derived3 = type { %struct.Base1, %struct.Base2 } -// CHECK: @_ZTV5Base1 = linkonce_odr unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, i32 0, i64 [[BASE1_A_DISC:38871]], ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV5Base1, i32 0, i32 0, i32 2))] },{{.*}} align 8 -// CHECK: @g_b1 = global %struct.Base1 { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV5Base1, i32 0, i32 0, i32 2), i32 2, i64 [[BASE1_VTABLE_DISC:6511]], ptr @g_b1) },{{.*}} align 8 -// CHECK: @_ZTV5Base2 = linkonce_odr unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, i32 0, i64 [[BASE2_B_DISC:27651]], ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV5Base2, i32 0, i32 0, i32 2))] },{{.*}} align 8 -// CHECK: @g_b2 = global %struct.Base2 { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV5Base2, i32 0, i32 0, i32 2), i32 2, i64 [[BASE2_VTABLE_DISC:63631]], ptr @g_b2) },{{.*}} align 8 -// CHECK: @_ZTV8Derived1 = linkonce_odr unnamed_addr constant { [5 x ptr], [3 x ptr] } { [5 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, i32 0, i64 [[BASE1_A_DISC]], ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived1, i32 0, i32 0, i32 2)), ptr ptrauth (ptr @_ZN8Derived11cEv, i32 0, i64 [[DERIVED1_C_DISC:54092]], ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived1, i32 0, i32 0, i32 3)), ptr ptrauth (ptr @_ZN8Derived11dEv, i32 0, i64 [[DERIVED1_D_DISC:37391]], ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived1, i32 0, i32 0, i32 4))], [3 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, i32 0, i64 [[BASE2_B_DISC]], ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived1, i32 0, i32 1, i32 2))] },{{.*}} align 8 -// CHECK: @g_d1 = global { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 24) ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived1, i32 0, i32 0, i32 2), i32 2, i64 [[BASE1_VTABLE_DISC]], ptr @g_d1), ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived1, i32 0, i32 1, i32 2), i32 2, i64 [[BASE2_VTABLE_DISC]], ptr getelementptr inbounds ({ ptr, ptr }, ptr @g_d1, i32 0, i32 1)) },{{.*}} align 8 -// CHECK: @_ZTV8Derived2 = linkonce_odr unnamed_addr constant { [5 x ptr], [3 x ptr] } { [5 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, i32 0, i64 [[BASE2_B_DISC]], ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 0, i32 2)), ptr ptrauth (ptr @_ZN8Derived21cEv, i32 0, i64 [[DERIVED2_C_DISC:15537]], ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 0, i32 3)), ptr ptrauth (ptr @_ZN8Derived21eEv, i32 0, i64 209, ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 0, i32 4))], [3 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, i32 0, i64 [[BASE1_A_DISC]], ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 1, i32 2))] },{{.*}} align 8 -// CHECK: @g_d2 = global { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 24) ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 0, i32 2), i32 2, i64 [[BASE2_VTABLE_DISC]], ptr @g_d2), ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 1, i32 2), i32 2, i64 [[BASE1_VTABLE_DISC]], ptr getelementptr inbounds ({ ptr, ptr }, ptr @g_d2, i32 0, i32 1)) },{{.*}} align 8 -// CHECK: @_ZTV8Derived3 = linkonce_odr unnamed_addr constant { [4 x ptr], [3 x ptr] } { [4 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, i32 0, i64 [[BASE1_A_DISC]], ptr getelementptr inbounds ({ [4 x ptr], [3 x ptr] }, ptr @_ZTV8Derived3, i32 0, i32 0, i32 2)), ptr ptrauth (ptr @_ZN8Derived31iEv, i32 0, i64 [[DERIVED3_I_DISC:19084]], ptr getelementptr inbounds ({ [4 x ptr], [3 x ptr] }, ptr @_ZTV8Derived3, i32 0, i32 0, i32 3))], [3 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, i32 0, i64 [[BASE2_B_DISC]], ptr getelementptr inbounds ({ [4 x ptr], [3 x ptr] }, ptr @_ZTV8Derived3, i32 0, i32 1, i32 2))] },{{.*}} align 8 -// CHECK: @g_d3 = global { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr], [3 x ptr] }, ptr @_ZTV8Derived3, i32 0, i32 0, i32 2), i32 2, i64 [[BASE1_VTABLE_DISC]], ptr @g_d3), ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [4 x ptr], [3 x ptr] }, ptr @_ZTV8Derived3, i32 0, i32 1, i32 2), i32 2, i64 [[BASE2_VTABLE_DISC]], ptr getelementptr inbounds ({ ptr, ptr }, ptr @g_d3, i32 0, i32 1)) },{{.*}} align 8 +// CHECK: @_ZTV5Base1 = linkonce_odr unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, [i64 0, i64 [[BASE1_A_DISC:38871]], i64 ptrtoint (ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV5Base1, i32 0, i32 0, i32 2) to i64)])] },{{.*}} align 8 +// CHECK: @g_b1 = global %struct.Base1 { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV5Base1, i32 0, i32 0, i32 2), [i64 2, i64 [[BASE1_VTABLE_DISC:6511]], i64 ptrtoint (ptr @g_b1 to i64)]) },{{.*}} align 8 +// CHECK: @_ZTV5Base2 = linkonce_odr unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, [i64 0, i64 [[BASE2_B_DISC:27651]], i64 ptrtoint (ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV5Base2, i32 0, i32 0, i32 2) to i64)])] },{{.*}} align 8 +// CHECK: @g_b2 = global %struct.Base2 { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV5Base2, i32 0, i32 0, i32 2), [i64 2, i64 [[BASE2_VTABLE_DISC:63631]], i64 ptrtoint (ptr @g_b2 to i64)]) },{{.*}} align 8 +// CHECK: @_ZTV8Derived1 = linkonce_odr unnamed_addr constant { [5 x ptr], [3 x ptr] } { [5 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, [i64 0, i64 [[BASE1_A_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived1, i32 0, i32 0, i32 2) to i64)]), ptr ptrauth (ptr @_ZN8Derived11cEv, [i64 0, i64 [[DERIVED1_C_DISC:54092]], i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived1, i32 0, i32 0, i32 3) to i64)]), ptr ptrauth (ptr @_ZN8Derived11dEv, [i64 0, i64 [[DERIVED1_D_DISC:37391]], i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived1, i32 0, i32 0, i32 4) to i64)])], [3 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, [i64 0, i64 [[BASE2_B_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived1, i32 0, i32 1, i32 2) to i64)])] },{{.*}} align 8 +// CHECK: @g_d1 = global { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 24) ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived1, i32 0, i32 0, i32 2), [i64 2, i64 [[BASE1_VTABLE_DISC]], i64 ptrtoint (ptr @g_d1 to i64)]), ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived1, i32 0, i32 1, i32 2), [i64 2, i64 [[BASE2_VTABLE_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ ptr, ptr }, ptr @g_d1, i32 0, i32 1) to i64)]) },{{.*}} align 8 +// CHECK: @_ZTV8Derived2 = linkonce_odr unnamed_addr constant { [5 x ptr], [3 x ptr] } { [5 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, [i64 0, i64 [[BASE2_B_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 0, i32 2) to i64)]), ptr ptrauth (ptr @_ZN8Derived21cEv, [i64 0, i64 [[DERIVED2_C_DISC:15537]], i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 0, i32 3) to i64)]), ptr ptrauth (ptr @_ZN8Derived21eEv, [i64 0, i64 209, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 0, i32 4) to i64)])], [3 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, [i64 0, i64 [[BASE1_A_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 1, i32 2) to i64)])] },{{.*}} align 8 +// CHECK: @g_d2 = global { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 24) ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 0, i32 2), [i64 2, i64 [[BASE2_VTABLE_DISC]], i64 ptrtoint (ptr @g_d2 to i64)]), ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [5 x ptr], [3 x ptr] }, ptr @_ZTV8Derived2, i32 0, i32 1, i32 2), [i64 2, i64 [[BASE1_VTABLE_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ ptr, ptr }, ptr @g_d2, i32 0, i32 1) to i64)]) },{{.*}} align 8 +// CHECK: @_ZTV8Derived3 = linkonce_odr unnamed_addr constant { [4 x ptr], [3 x ptr] } { [4 x ptr] [ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, [i64 0, i64 [[BASE1_A_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ [4 x ptr], [3 x ptr] }, ptr @_ZTV8Derived3, i32 0, i32 0, i32 2) to i64)]), ptr ptrauth (ptr @_ZN8Derived31iEv, [i64 0, i64 [[DERIVED3_I_DISC:19084]], i64 ptrtoint (ptr getelementptr inbounds ({ [4 x ptr], [3 x ptr] }, ptr @_ZTV8Derived3, i32 0, i32 0, i32 3) to i64)])], [3 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, [i64 0, i64 [[BASE2_B_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ [4 x ptr], [3 x ptr] }, ptr @_ZTV8Derived3, i32 0, i32 1, i32 2) to i64)])] },{{.*}} align 8 +// CHECK: @g_d3 = global { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr], [3 x ptr] }, ptr @_ZTV8Derived3, i32 0, i32 0, i32 2), [i64 2, i64 [[BASE1_VTABLE_DISC]], i64 ptrtoint (ptr @g_d3 to i64)]), ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [4 x ptr], [3 x ptr] }, ptr @_ZTV8Derived3, i32 0, i32 1, i32 2), [i64 2, i64 [[BASE2_VTABLE_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ ptr, ptr }, ptr @g_d3, i32 0, i32 1) to i64)]) },{{.*}} align 8 // CHECK: @g_vb1 = global %struct.VirtualBase1 zeroinitializer,{{.*}} align 8 // CHECK: @g_vb2 = global %struct.VirtualBase2 zeroinitializer,{{.*}} align 8 // CHECK: @g_d4 = global %struct.Derived4 zeroinitializer,{{.*}} align 8 -// CHECK: @_ZTV12VirtualBase1 = linkonce_odr unnamed_addr constant { [6 x ptr] } { [6 x ptr] [ptr null, ptr null, ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, i32 0, i64 [[BASE1_A_DISC]], ptr getelementptr inbounds ({ [6 x ptr] }, ptr @_ZTV12VirtualBase1, i32 0, i32 0, i32 4)), ptr ptrauth (ptr @_ZN12VirtualBase11fEv, i32 0, i64 [[VIRTUALBASE1_F_DISC:7987]], ptr getelementptr inbounds ({ [6 x ptr] }, ptr @_ZTV12VirtualBase1, i32 0, i32 0, i32 5))] },{{.*}} align 8 -// CHECK: @_ZTT12VirtualBase1 = linkonce_odr unnamed_addr constant [2 x ptr] [ptr ptrauth (ptr getelementptr inbounds inrange(-32, 16) ({ [6 x ptr] }, ptr @_ZTV12VirtualBase1, i32 0, i32 0, i32 4), i32 2), ptr ptrauth (ptr getelementptr inbounds inrange(-32, 16) ({ [6 x ptr] }, ptr @_ZTV12VirtualBase1, i32 0, i32 0, i32 4), i32 2)],{{.*}} align 8 -// CHECK: @_ZTV12VirtualBase2 = linkonce_odr unnamed_addr constant { [5 x ptr], [4 x ptr] } { [5 x ptr] [ptr inttoptr (i64 8 to ptr), ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, i32 0, i64 [[BASE2_B_DISC]], ptr getelementptr inbounds ({ [5 x ptr], [4 x ptr] }, ptr @_ZTV12VirtualBase2, i32 0, i32 0, i32 3)), ptr ptrauth (ptr @_ZN12VirtualBase21gEv, i32 0, i64 [[VIRTUALBASE2_G_DISC:51224]], ptr getelementptr inbounds ({ [5 x ptr], [4 x ptr] }, ptr @_ZTV12VirtualBase2, i32 0, i32 0, i32 4))], [4 x ptr] [ptr null, ptr inttoptr (i64 -8 to ptr), ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, i32 0, i64 [[BASE1_A_DISC]], ptr getelementptr inbounds ({ [5 x ptr], [4 x ptr] }, ptr @_ZTV12VirtualBase2, i32 0, i32 1, i32 3))] },{{.*}} align 8 -// CHECK: @_ZTT12VirtualBase2 = linkonce_odr unnamed_addr constant [2 x ptr] [ptr ptrauth (ptr getelementptr inbounds inrange(-24, 16) ({ [5 x ptr], [4 x ptr] }, ptr @_ZTV12VirtualBase2, i32 0, i32 0, i32 3), i32 2), ptr ptrauth (ptr getelementptr inbounds inrange(-24, 8) ({ [5 x ptr], [4 x ptr] }, ptr @_ZTV12VirtualBase2, i32 0, i32 1, i32 3), i32 2)],{{.*}} align 8 -// CHECK: @_ZTV8Derived4 = linkonce_odr unnamed_addr constant { [7 x ptr], [5 x ptr] } { [7 x ptr] [ptr null, ptr null, ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, i32 0, i64 [[BASE1_A_DISC]], ptr getelementptr inbounds ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 0, i32 4)), ptr ptrauth (ptr @_ZN12VirtualBase11fEv, i32 0, i64 [[VIRTUALBASE1_F_DISC]], ptr getelementptr inbounds ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 0, i32 5)), ptr ptrauth (ptr @_ZN8Derived41hEv, i32 0, i64 [[DERIVED4_H_DISC:31844]], ptr getelementptr inbounds ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 0, i32 6))], [5 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr inttoptr (i64 -8 to ptr), ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, i32 0, i64 [[BASE2_B_DISC]], ptr getelementptr inbounds ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 1, i32 3)), ptr ptrauth (ptr @_ZN12VirtualBase21gEv, i32 0, i64 [[VIRTUALBASE2_G_DISC]], ptr getelementptr inbounds ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 1, i32 4))] },{{.*}} align 8 -// CHECK: @_ZTT8Derived4 = linkonce_odr unnamed_addr constant [7 x ptr] [ptr ptrauth (ptr getelementptr inbounds inrange(-32, 24) ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 0, i32 4), i32 2), ptr ptrauth (ptr getelementptr inbounds inrange(-32, 16) ({ [6 x ptr] }, ptr @_ZTC8Derived40_12VirtualBase1, i32 0, i32 0, i32 4), i32 2), ptr ptrauth (ptr getelementptr inbounds inrange(-32, 16) ({ [6 x ptr] }, ptr @_ZTC8Derived40_12VirtualBase1, i32 0, i32 0, i32 4), i32 2), ptr ptrauth (ptr getelementptr inbounds inrange(-24, 16) ({ [5 x ptr], [4 x ptr] }, ptr @_ZTC8Derived48_12VirtualBase2, i32 0, i32 0, i32 3), i32 2), ptr ptrauth (ptr getelementptr inbounds inrange(-24, 8) ({ [5 x ptr], [4 x ptr] }, ptr @_ZTC8Derived48_12VirtualBase2, i32 0, i32 1, i32 3), i32 2), ptr ptrauth (ptr getelementptr inbounds inrange(-32, 24) ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 0, i32 4), i32 2), ptr ptrauth (ptr getelementptr inbounds inrange(-24, 16) ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 1, i32 3), i32 2)],{{.*}} align 8 -// CHECK: @_ZTC8Derived40_12VirtualBase1 = linkonce_odr unnamed_addr constant { [6 x ptr] } { [6 x ptr] [ptr null, ptr null, ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, i32 0, i64 [[BASE1_A_DISC]], ptr getelementptr inbounds ({ [6 x ptr] }, ptr @_ZTC8Derived40_12VirtualBase1, i32 0, i32 0, i32 4)), ptr ptrauth (ptr @_ZN12VirtualBase11fEv, i32 0, i64 [[VIRTUALBASE1_F_DISC]], ptr getelementptr inbounds ({ [6 x ptr] }, ptr @_ZTC8Derived40_12VirtualBase1, i32 0, i32 0, i32 5))] },{{.*}} align 8 -// CHECK: @_ZTC8Derived48_12VirtualBase2 = linkonce_odr unnamed_addr constant { [5 x ptr], [4 x ptr] } { [5 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, i32 0, i64 [[BASE2_B_DISC]], ptr getelementptr inbounds ({ [5 x ptr], [4 x ptr] }, ptr @_ZTC8Derived48_12VirtualBase2, i32 0, i32 0, i32 3)), ptr ptrauth (ptr @_ZN12VirtualBase21gEv, i32 0, i64 [[VIRTUALBASE2_G_DISC]], ptr getelementptr inbounds ({ [5 x ptr], [4 x ptr] }, ptr @_ZTC8Derived48_12VirtualBase2, i32 0, i32 0, i32 4))], [4 x ptr] [ptr null, ptr inttoptr (i64 8 to ptr), ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, i32 0, i64 [[BASE1_A_DISC]], ptr getelementptr inbounds ({ [5 x ptr], [4 x ptr] }, ptr @_ZTC8Derived48_12VirtualBase2, i32 0, i32 1, i32 3))] },{{.*}} align 8 +// CHECK: @_ZTV12VirtualBase1 = linkonce_odr unnamed_addr constant { [6 x ptr] } { [6 x ptr] [ptr null, ptr null, ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, [i64 0, i64 [[BASE1_A_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr] }, ptr @_ZTV12VirtualBase1, i32 0, i32 0, i32 4) to i64)]), ptr ptrauth (ptr @_ZN12VirtualBase11fEv, [i64 0, i64 [[VIRTUALBASE1_F_DISC:7987]], i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr] }, ptr @_ZTV12VirtualBase1, i32 0, i32 0, i32 5) to i64)])] },{{.*}} align 8 +// CHECK: @_ZTT12VirtualBase1 = linkonce_odr unnamed_addr constant [2 x ptr] [ptr ptrauth (ptr getelementptr inbounds inrange(-32, 16) ({ [6 x ptr] }, ptr @_ZTV12VirtualBase1, i32 0, i32 0, i32 4), [i64 2, i64 0, i64 0]), ptr ptrauth (ptr getelementptr inbounds inrange(-32, 16) ({ [6 x ptr] }, ptr @_ZTV12VirtualBase1, i32 0, i32 0, i32 4), [i64 2, i64 0, i64 0])],{{.*}} align 8 +// CHECK: @_ZTV12VirtualBase2 = linkonce_odr unnamed_addr constant { [5 x ptr], [4 x ptr] } { [5 x ptr] [ptr inttoptr (i64 8 to ptr), ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, [i64 0, i64 [[BASE2_B_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [4 x ptr] }, ptr @_ZTV12VirtualBase2, i32 0, i32 0, i32 3) to i64)]), ptr ptrauth (ptr @_ZN12VirtualBase21gEv, [i64 0, i64 [[VIRTUALBASE2_G_DISC:51224]], i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [4 x ptr] }, ptr @_ZTV12VirtualBase2, i32 0, i32 0, i32 4) to i64)])], [4 x ptr] [ptr null, ptr inttoptr (i64 -8 to ptr), ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, [i64 0, i64 [[BASE1_A_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [4 x ptr] }, ptr @_ZTV12VirtualBase2, i32 0, i32 1, i32 3) to i64)])] },{{.*}} align 8 +// CHECK: @_ZTT12VirtualBase2 = linkonce_odr unnamed_addr constant [2 x ptr] [ptr ptrauth (ptr getelementptr inbounds inrange(-24, 16) ({ [5 x ptr], [4 x ptr] }, ptr @_ZTV12VirtualBase2, i32 0, i32 0, i32 3), [i64 2, i64 0, i64 0]), ptr ptrauth (ptr getelementptr inbounds inrange(-24, 8) ({ [5 x ptr], [4 x ptr] }, ptr @_ZTV12VirtualBase2, i32 0, i32 1, i32 3), [i64 2, i64 0, i64 0])],{{.*}} align 8 +// CHECK: @_ZTV8Derived4 = linkonce_odr unnamed_addr constant { [7 x ptr], [5 x ptr] } { [7 x ptr] [ptr null, ptr null, ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, [i64 0, i64 [[BASE1_A_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 0, i32 4) to i64)]), ptr ptrauth (ptr @_ZN12VirtualBase11fEv, [i64 0, i64 [[VIRTUALBASE1_F_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 0, i32 5) to i64)]), ptr ptrauth (ptr @_ZN8Derived41hEv, [i64 0, i64 [[DERIVED4_H_DISC:31844]], i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 0, i32 6) to i64)])], [5 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr inttoptr (i64 -8 to ptr), ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, [i64 0, i64 [[BASE2_B_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 1, i32 3) to i64)]), ptr ptrauth (ptr @_ZN12VirtualBase21gEv, [i64 0, i64 [[VIRTUALBASE2_G_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 1, i32 4) to i64)])] },{{.*}} align 8 +// CHECK: @_ZTT8Derived4 = linkonce_odr unnamed_addr constant [7 x ptr] [ptr ptrauth (ptr getelementptr inbounds inrange(-32, 24) ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 0, i32 4), [i64 2, i64 0, i64 0]), ptr ptrauth (ptr getelementptr inbounds inrange(-32, 16) ({ [6 x ptr] }, ptr @_ZTC8Derived40_12VirtualBase1, i32 0, i32 0, i32 4), [i64 2, i64 0, i64 0]), ptr ptrauth (ptr getelementptr inbounds inrange(-32, 16) ({ [6 x ptr] }, ptr @_ZTC8Derived40_12VirtualBase1, i32 0, i32 0, i32 4), [i64 2, i64 0, i64 0]), ptr ptrauth (ptr getelementptr inbounds inrange(-24, 16) ({ [5 x ptr], [4 x ptr] }, ptr @_ZTC8Derived48_12VirtualBase2, i32 0, i32 0, i32 3), [i64 2, i64 0, i64 0]), ptr ptrauth (ptr getelementptr inbounds inrange(-24, 8) ({ [5 x ptr], [4 x ptr] }, ptr @_ZTC8Derived48_12VirtualBase2, i32 0, i32 1, i32 3), [i64 2, i64 0, i64 0]), ptr ptrauth (ptr getelementptr inbounds inrange(-32, 24) ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 0, i32 4), [i64 2, i64 0, i64 0]), ptr ptrauth (ptr getelementptr inbounds inrange(-24, 16) ({ [7 x ptr], [5 x ptr] }, ptr @_ZTV8Derived4, i32 0, i32 1, i32 3), [i64 2, i64 0, i64 0])],{{.*}} align 8 +// CHECK: @_ZTC8Derived40_12VirtualBase1 = linkonce_odr unnamed_addr constant { [6 x ptr] } { [6 x ptr] [ptr null, ptr null, ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, [i64 0, i64 [[BASE1_A_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr] }, ptr @_ZTC8Derived40_12VirtualBase1, i32 0, i32 0, i32 4) to i64)]), ptr ptrauth (ptr @_ZN12VirtualBase11fEv, [i64 0, i64 [[VIRTUALBASE1_F_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr] }, ptr @_ZTC8Derived40_12VirtualBase1, i32 0, i32 0, i32 5) to i64)])] },{{.*}} align 8 +// CHECK: @_ZTC8Derived48_12VirtualBase2 = linkonce_odr unnamed_addr constant { [5 x ptr], [4 x ptr] } { [5 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr null, ptr null, ptr ptrauth (ptr @_ZN5Base21bEv, [i64 0, i64 [[BASE2_B_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [4 x ptr] }, ptr @_ZTC8Derived48_12VirtualBase2, i32 0, i32 0, i32 3) to i64)]), ptr ptrauth (ptr @_ZN12VirtualBase21gEv, [i64 0, i64 [[VIRTUALBASE2_G_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [4 x ptr] }, ptr @_ZTC8Derived48_12VirtualBase2, i32 0, i32 0, i32 4) to i64)])], [4 x ptr] [ptr null, ptr inttoptr (i64 8 to ptr), ptr null, ptr ptrauth (ptr @_ZN5Base11aEv, [i64 0, i64 [[BASE1_A_DISC]], i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [4 x ptr] }, ptr @_ZTC8Derived48_12VirtualBase2, i32 0, i32 1, i32 3) to i64)])] },{{.*}} align 8 struct Base1 { virtual void a() {} }; struct Base2 { virtual void b() {} }; @@ -78,25 +78,25 @@ struct Derived5 : VirtualBase2, VirtualBase1 { // DARWIN-LABEL: define {{.*}} ptr @_ZN12VirtualBase1C1Ev // ELF-LABEL: define {{.*}} void @_ZN12VirtualBase1C1Ev -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.sign{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call i64 @llvm.ptrauth.sign{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] // DARWIN-LABEL: define {{.*}} ptr @_ZN12VirtualBase2C1Ev // ELF-LABEL: define {{.*}} void @_ZN12VirtualBase2C1Ev -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.sign{{.*}} [ "ptrauth"(i64 2, i64 [[BASE2_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call i64 @llvm.ptrauth.sign{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] // DARWIN-LABEL: define {{.*}} ptr @_ZN8Derived4C1Ev // ELF-LABEL: define {{.*}} void @_ZN8Derived4C1Ev -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.sign{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call i64 @llvm.ptrauth.sign{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call i64 @llvm.ptrauth.sign{{.*}} [ "ptrauth"(i64 2, i64 [[BASE2_VTABLE_DISC]], i64 {{%.*}}) ] // DARWIN-LABEL: define {{.*}} ptr @_ZN8Derived5C1Ev // ELF-LABEL: define {{.*}} void @_ZN8Derived5C1Ev -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.sign{{.*}} [ "ptrauth"(i64 2, i64 [[BASE2_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call i64 @llvm.ptrauth.sign{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call i64 @llvm.ptrauth.sign{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] VirtualBase1 g_vb1; @@ -164,82 +164,82 @@ extern "C" void cross_check_vtables(Base1 *b1, // CHECK-LABEL: define{{.*}} void @cross_check_vtables( // CHECK: "; b1->a()", -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_A_DISC]]) +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 [[BASE1_A_DISC]], i64 {{%.*}}) ] // CHECK: "; b2->b()" -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_B_DISC]]) +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE2_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 [[BASE2_B_DISC]], i64 {{%.*}}) ] // CHECK: "; d1->a()" -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_A_DISC]]) +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 [[BASE1_A_DISC]], i64 {{%.*}}) ] // CHECK: "; d1->c()" -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[DERIVED1_C_DISC]]) +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 [[DERIVED1_C_DISC]], i64 {{%.*}}) ] // CHECK: "; d2->a()" -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_A_DISC]]) +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 [[BASE1_A_DISC]], i64 {{%.*}}) ] // CHECK: "; d2->c()" -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[DERIVED2_C_DISC]]) +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE2_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 [[DERIVED2_C_DISC]], i64 {{%.*}}) ] // CHECK: "; d3->a()" -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_A_DISC]]) +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 [[BASE1_A_DISC]], i64 {{%.*}}) ] // CHECK: "; d3->b()" -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_B_DISC]]) +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE2_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 [[BASE2_B_DISC]], i64 {{%.*}}) ] // CHECK: "; d3->i()" -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[DERIVED3_I_DISC]]) +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 [[DERIVED3_I_DISC]], i64 {{%.*}}) ] // CHECK: "; vb1->a()" -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_A_DISC]]) +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 [[BASE1_A_DISC]], i64 {{%.*}}) ] // CHECK: "; vb1->f()" -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[VIRTUALBASE1_F_DISC]]) +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 [[VIRTUALBASE1_F_DISC]], i64 {{%.*}}) ] // CHECK: "; vb2->a()" -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_A_DISC]]) +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE2_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 [[BASE1_A_DISC]], i64 {{%.*}}) ] // CHECK: "; vb2->g()" -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[VIRTUALBASE2_G_DISC]]) +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE2_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 [[VIRTUALBASE2_G_DISC]], i64 {{%.*}}) ] // CHECK: "; d4->a()" -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_A_DISC]]) +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 [[BASE1_A_DISC]], i64 {{%.*}}) ] // CHECK: "; d4->b()" -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_B_DISC]]) +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE2_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 [[BASE2_B_DISC]], i64 {{%.*}}) ] // CHECK: "; d4->f()" -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[VIRTUALBASE1_F_DISC]]) +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 [[VIRTUALBASE1_F_DISC]], i64 {{%.*}}) ] // CHECK: "; d4->g()" -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[VIRTUALBASE2_G_DISC]]) +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE2_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 [[VIRTUALBASE2_G_DISC]], i64 {{%.*}}) ] // CHECK: "; d4->h()" -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[DERIVED4_H_DISC]]) +// CHECK: call i64 @llvm.ptrauth.auth{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 [[DERIVED4_H_DISC]], i64 {{%.*}}) ] // DARWIN-LABEL: define {{.*}} ptr @_ZN5Base1C2Ev // ELF-LABEL: define {{.*}} void @_ZN5Base1C2Ev -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.sign{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] // DARWIN-LABEL: define {{.*}} ptr @_ZN5Base2C2Ev // ELF-LABEL: define {{.*}} void @_ZN5Base2C2Ev -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.sign{{.*}} [ "ptrauth"(i64 2, i64 [[BASE2_VTABLE_DISC]], i64 {{%.*}}) ] // DARWIN-LABEL: define {{.*}} ptr @_ZN8Derived1C2Ev // ELF-LABEL: define {{.*}} void @_ZN8Derived1C2Ev -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.sign{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call i64 @llvm.ptrauth.sign{{.*}} [ "ptrauth"(i64 2, i64 [[BASE2_VTABLE_DISC]], i64 {{%.*}}) ] // DARWIN-LABEL: define {{.*}} ptr @_ZN8Derived2C2Ev // ELF-LABEL: define {{.*}} void @_ZN8Derived2C2Ev -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.sign{{.*}} [ "ptrauth"(i64 2, i64 [[BASE2_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call i64 @llvm.ptrauth.sign{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] // DARWIN-LABEL: define {{.*}} ptr @_ZN8Derived3C2Ev // ELF-LABEL: define {{.*}} void @_ZN8Derived3C2Ev -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE1_VTABLE_DISC]]) -// CHECK: call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 [[BASE2_VTABLE_DISC]]) +// CHECK: call i64 @llvm.ptrauth.sign{{.*}} [ "ptrauth"(i64 2, i64 [[BASE1_VTABLE_DISC]], i64 {{%.*}}) ] +// CHECK: call i64 @llvm.ptrauth.sign{{.*}} [ "ptrauth"(i64 2, i64 [[BASE2_VTABLE_DISC]], i64 {{%.*}}) ] diff --git a/clang/test/CodeGenCXX/ptrauth-member-function-pointer.cpp b/clang/test/CodeGenCXX/ptrauth-member-function-pointer.cpp index e9436f11b5106..0d17de23ea070 100644 --- a/clang/test/CodeGenCXX/ptrauth-member-function-pointer.cpp +++ b/clang/test/CodeGenCXX/ptrauth-member-function-pointer.cpp @@ -13,23 +13,23 @@ // RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics -emit-llvm -std=c++11 -O1 -disable-llvm-passes -stack-protector 3 -o - %s | FileCheck %s -check-prefix=STACK-PROT -// CHECK: @gmethod0 = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 [[TYPEDISC1:35591]]) to i64), i64 0 }, align 8 -// CHECK: @gmethod1 = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived011nonvirtual5Ev, i32 0, i64 [[TYPEDISC0:22163]]) to i64), i64 0 }, align 8 -// CHECK: @gmethod2 = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 [[TYPEDISC0]]) to i64), i64 0 }, align 8 +// CHECK: @gmethod0 = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, [i64 0, i64 [[TYPEDISC1:35591]], i64 0]) to i64), i64 0 }, align 8 +// CHECK: @gmethod1 = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived011nonvirtual5Ev, [i64 0, i64 [[TYPEDISC0:22163]], i64 0]) to i64), i64 0 }, align 8 +// CHECK: @gmethod2 = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, [i64 0, i64 [[TYPEDISC0]], i64 0]) to i64), i64 0 }, align 8 -// CHECK: @__const._Z13testArrayInitv.p0 = private unnamed_addr constant [1 x { i64, i64 }] [{ i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 35591) to i64), i64 0 }], align 8 -// CHECK: @__const._Z13testArrayInitv.p1 = private unnamed_addr constant [1 x { i64, i64 }] [{ i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 35591) to i64), i64 0 }], align 8 -// CHECK: @__const._Z13testArrayInitv.c0 = private unnamed_addr constant %struct.Class0 { { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 35591) to i64), i64 0 } }, align 8 -// CHECK: @__const._Z13testArrayInitv.c1 = private unnamed_addr constant %struct.Class0 { { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 35591) to i64), i64 0 } }, align 8 +// CHECK: @__const._Z13testArrayInitv.p0 = private unnamed_addr constant [1 x { i64, i64 }] [{ i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, [i64 0, i64 35591, i64 0]) to i64), i64 0 }], align 8 +// CHECK: @__const._Z13testArrayInitv.p1 = private unnamed_addr constant [1 x { i64, i64 }] [{ i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, [i64 0, i64 35591, i64 0]) to i64), i64 0 }], align 8 +// CHECK: @__const._Z13testArrayInitv.c0 = private unnamed_addr constant %struct.Class0 { { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, [i64 0, i64 35591, i64 0]) to i64), i64 0 } }, align 8 +// CHECK: @__const._Z13testArrayInitv.c1 = private unnamed_addr constant %struct.Class0 { { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, [i64 0, i64 35591, i64 0]) to i64), i64 0 } }, align 8 -// CHECK: @_ZN22testNoexceptConversion6mfptr1E = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S19nonvirtual_noexceptEv, i32 0, i64 [[TYPEDISC3:.*]]) to i64), i64 0 }, -// CHECK: @_ZN22testNoexceptConversion6mfptr2E = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S16virtual_noexceptEv_vfpthunk_, i32 0, i64 [[TYPEDISC3]]) to i64), i64 0 }, -// CHECK: @_ZN22testNoexceptConversion15mfptr3_noexceptE = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S19nonvirtual_noexceptEv, i32 0, i64 [[TYPEDISC3]]) to i64), i64 0 }, +// CHECK: @_ZN22testNoexceptConversion6mfptr1E = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S19nonvirtual_noexceptEv, [i64 0, i64 [[TYPEDISC3:.*]], i64 0]) to i64), i64 0 }, +// CHECK: @_ZN22testNoexceptConversion6mfptr2E = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S16virtual_noexceptEv_vfpthunk_, [i64 0, i64 [[TYPEDISC3]], i64 0]) to i64), i64 0 }, +// CHECK: @_ZN22testNoexceptConversion15mfptr3_noexceptE = global { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S19nonvirtual_noexceptEv, [i64 0, i64 [[TYPEDISC3]], i64 0]) to i64), i64 0 }, // CHECK: @_ZTV5Base0 = unnamed_addr constant { [5 x ptr] } { [5 x ptr] [ptr null, ptr @_ZTI5Base0, -// CHECK-SAME: ptr ptrauth (ptr @_ZN5Base08virtual1Ev, i32 0, i64 55600, ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV5Base0, i32 0, i32 0, i32 2)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN5Base08virtual3Ev, i32 0, i64 53007, ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV5Base0, i32 0, i32 0, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN5Base016virtual_variadicEiz, i32 0, i64 7464, ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV5Base0, i32 0, i32 0, i32 4))] }, align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZN5Base08virtual1Ev, [i64 0, i64 55600, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV5Base0, i32 0, i32 0, i32 2) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN5Base08virtual3Ev, [i64 0, i64 53007, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV5Base0, i32 0, i32 0, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN5Base016virtual_variadicEiz, [i64 0, i64 7464, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV5Base0, i32 0, i32 0, i32 4) to i64)])] }, align 8 typedef __SIZE_TYPE__ size_t; @@ -104,21 +104,21 @@ struct Class0 { // CHECK-NEXT: %[[METHOD5:.*]] = alloca { i64, i64 }, align 8 // CHECK-NEXT: %[[METHOD6:.*]] = alloca { i64, i64 }, align 8 // CHECK-NEXT: %[[METHOD7:.*]] = alloca { i64, i64 }, align 8 -// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 [[TYPEDISC0]]) to i64), i64 0 }, ptr %[[METHOD0]], align 8 -// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 [[TYPEDISC0]]) to i64), i64 0 }, ptr %[[METHOD0]], align 8 -// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual3Ev_vfpthunk_, i32 0, i64 [[TYPEDISC0]]) to i64), i64 0 }, ptr %[[METHOD0]], align 8 -// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base016virtual_variadicEiz_vfpthunk_, i32 0, i64 34368) to i64), i64 0 }, ptr %[[VARMETHOD1]], align 8 -// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 -// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 -// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual3Ev_vfpthunk_, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 -// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived011nonvirtual5Ev, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 -// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived08virtual6Ev_vfpthunk_, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 -// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived010return_aggEv_vfpthunk_, i32 0, i64 64418) to i64), i64 0 }, ptr %[[METHOD3]], align 8 -// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived04sretEv_vfpthunk_, i32 0, i64 28187) to i64), i64 0 }, ptr %[[METHOD4]], align 8 -// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived011trivial_abiE8TrivialS_vfpthunk_, i32 0, i64 8992) to i64), i64 0 }, ptr %[[METHOD5]], align 8 -// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base18virtual7Ev_vfpthunk_, i32 0, i64 [[TYPEDISC2:61596]]) to i64), i64 0 }, ptr %[[METHOD6]], align 8 -// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived18virtual7Ev_vfpthunk_, i32 0, i64 25206) to i64), i64 0 }, ptr %[[METHOD7]], align 8 -// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 25206) to i64), i64 0 }, ptr %[[METHOD7]], align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, [i64 0, i64 [[TYPEDISC0]], i64 0]) to i64), i64 0 }, ptr %[[METHOD0]], align 8 +// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, [i64 0, i64 [[TYPEDISC0]], i64 0]) to i64), i64 0 }, ptr %[[METHOD0]], align 8 +// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual3Ev_vfpthunk_, [i64 0, i64 [[TYPEDISC0]], i64 0]) to i64), i64 0 }, ptr %[[METHOD0]], align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base016virtual_variadicEiz_vfpthunk_, [i64 0, i64 34368, i64 0]) to i64), i64 0 }, ptr %[[VARMETHOD1]], align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, [i64 0, i64 [[TYPEDISC1]], i64 0]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 +// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, [i64 0, i64 [[TYPEDISC1]], i64 0]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 +// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual3Ev_vfpthunk_, [i64 0, i64 [[TYPEDISC1]], i64 0]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 +// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived011nonvirtual5Ev, [i64 0, i64 [[TYPEDISC1]], i64 0]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 +// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived08virtual6Ev_vfpthunk_, [i64 0, i64 [[TYPEDISC1]], i64 0]) to i64), i64 0 }, ptr %[[METHOD2]], align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived010return_aggEv_vfpthunk_, [i64 0, i64 64418, i64 0]) to i64), i64 0 }, ptr %[[METHOD3]], align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived04sretEv_vfpthunk_, [i64 0, i64 28187, i64 0]) to i64), i64 0 }, ptr %[[METHOD4]], align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived011trivial_abiE8TrivialS_vfpthunk_, [i64 0, i64 8992, i64 0]) to i64), i64 0 }, ptr %[[METHOD5]], align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base18virtual7Ev_vfpthunk_, [i64 0, i64 [[TYPEDISC2:61596]], i64 0]) to i64), i64 0 }, ptr %[[METHOD6]], align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN8Derived18virtual7Ev_vfpthunk_, [i64 0, i64 25206, i64 0]) to i64), i64 0 }, ptr %[[METHOD7]], align 8 +// CHECK-NEXT: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, [i64 0, i64 25206, i64 0]) to i64), i64 0 }, ptr %[[METHOD7]], align 8 // CHECK: ret void // CHECK: define linkonce_odr hidden void @_ZN5Base08virtual1Ev_vfpthunk_(ptr noundef %[[THIS:.*]]) @@ -128,13 +128,12 @@ struct Class0 { // CHECK-NEXT: %[[V0:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 // CHECK-NEXT: %[[VTABLE:.*]] = load ptr, ptr %[[THIS1]], align 8 // CHECK-NEXT: %[[V2:.*]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK-NEXT: %[[V3:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V2]], i32 2, i64 0) +// CHECK-NEXT: %[[V3:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V2]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK-NEXT: %[[V4:.*]] = inttoptr i64 %[[V3]] to ptr // CHECK-NEXT: %[[VFN:.*]] = getelementptr inbounds ptr, ptr %[[V4]], i64 0 // CHECK-NEXT: %[[V5:.*]] = load ptr, ptr %[[VFN]], align 8 // CHECK-NEXT: %[[V6:.*]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK-NEXT: %[[V7:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V6]], i64 55600) -// CHECK-NEXT: musttail call void %[[V5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %[[V0]]) [ "ptrauth"(i32 0, i64 %[[V7]]) ] +// CHECK-NEXT: musttail call void %[[V5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %[[V0]]) [ "ptrauth"(i64 0, i64 55600, i64 %[[V6]]) ] // CHECK-NEXT: ret void // CHECK: define linkonce_odr hidden void @_ZN5Base08virtual3Ev_vfpthunk_(ptr noundef %{{.*}}) @@ -142,10 +141,10 @@ struct Class0 { // CHECK: load ptr, ptr %{{.*}}, align 8 // CHECK: %[[VTABLE:.*]] = load ptr, ptr %{{.*}}, align 8 // CHECK: %[[V2:.*]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[V3:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V2]], i32 2, i64 0) +// CHECK: %[[V3:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V2]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[V4:.*]] = inttoptr i64 %[[V3]] to ptr // CHECK: getelementptr inbounds ptr, ptr %[[V4]], i64 1 -// CHECK: call i64 @llvm.ptrauth.blend(i64 %{{.*}}, i64 53007) +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 53007, i64 %{{.*}}) ] // CHECK: define linkonce_odr hidden void @_ZN5Base016virtual_variadicEiz_vfpthunk_(ptr noundef %[[THIS:.*]], i32 noundef %0, ...) // CHECK: %[[THIS_ADDR:.*]] = alloca ptr, align 8 @@ -157,13 +156,12 @@ struct Class0 { // CHECK-NEXT: %[[V2:.*]] = load i32, ptr %[[_ADDR]], align 4 // CHECK-NEXT: %[[VTABLE:.*]] = load ptr, ptr %[[THIS1]], align 8 // CHECK-NEXT: %[[V4:.*]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK-NEXT: %[[V5:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V4]], i32 2, i64 0) +// CHECK-NEXT: %[[V5:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V4]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK-NEXT: %[[V6:.*]] = inttoptr i64 %[[V5]] to ptr // CHECK-NEXT: %[[VFN:.*]] = getelementptr inbounds ptr, ptr %[[V6]], i64 2 // CHECK-NEXT: %[[V7:.*]] = load ptr, ptr %[[VFN]], align 8 // CHECK-NEXT: %[[V8:.*]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK-NEXT: %[[V9:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V8]], i64 7464) -// CHECK-NEXT: musttail call void (ptr, i32, ...) %[[V7]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %[[V1]], i32 noundef %[[V2]], ...) [ "ptrauth"(i32 0, i64 %[[V9]]) ] +// CHECK-NEXT: musttail call void (ptr, i32, ...) %[[V7]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %[[V1]], i32 noundef %[[V2]], ...) [ "ptrauth"(i64 0, i64 7464, i64 %[[V8]]) ] // CHECK-NEXT: ret void // CHECK: define linkonce_odr hidden void @_ZN8Derived08virtual6Ev_vfpthunk_(ptr noundef %[[THIS:.*]]) @@ -173,23 +171,23 @@ struct Class0 { // CHECK: %[[V0:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 // CHECK: %[[VTABLE:.*]] = load ptr, ptr %[[THIS1]], align 8 // CHECK: %[[V1:.*]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[V2:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V1]], i32 2, i64 0) +// CHECK: %[[V2:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V1]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[V3:.*]] = inttoptr i64 %[[V2]] to ptr // CHECK: %[[VFN:.*]] = getelementptr inbounds ptr, ptr %[[V3]], i64 3 // CHECK: %[[V5:.*]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: call i64 @llvm.ptrauth.blend(i64 %[[V5]], i64 55535) +// CHECK: call void %{{.*}} [ "ptrauth"(i64 0, i64 55535, i64 %[[V5]]) ] // Check that the return value of the musttail call isn't copied to a temporary. // CHECK: define linkonce_odr hidden [2 x i64] @_ZN8Derived010return_aggEv_vfpthunk_(ptr noundef %{{.*}}) -// CHECK: %[[CALL:.*]] = musttail call [2 x i64] %{{.*}}(ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %{{.*}}) [ "ptrauth"(i32 0, i64 %{{.*}}) ] +// CHECK: %[[CALL:.*]] = musttail call [2 x i64] %{{.*}}(ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %{{.*}}) [ "ptrauth"(i64 0, i64 13445, i64 %{{.*}}) ] // CHECK-NEXT: ret [2 x i64] %[[CALL]] // Check that the sret pointer passed to the caller is forwarded to the musttail // call. // CHECK: define linkonce_odr hidden void @_ZN8Derived04sretEv_vfpthunk_(ptr dead_on_unwind noalias writable sret(%struct.A1) align 4 %[[AGG_RESULT:.*]], ptr noundef %{{.*}}) -// CHECK: musttail call void %{{.*}}(ptr dead_on_unwind writable sret(%struct.A1) align 4 %[[AGG_RESULT]], ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %{{.*}}) [ "ptrauth"(i32 0, i64 %{{.*}}) ] +// CHECK: musttail call void %{{.*}}(ptr dead_on_unwind writable sret(%struct.A1) align 4 %[[AGG_RESULT]], ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %{{.*}}) [ "ptrauth"(i64 0, i64 41281, i64 %{{.*}}) ] // CHECK-NEXT: ret void // Check that the thunk function doesn't destruct the trivial_abi argument. @@ -198,9 +196,7 @@ struct Class0 { // NODEBUG-NOT: call // CHECK: call i64 @llvm.ptrauth.auth( // NODEBUG-NOT: call -// CHECK: call i64 @llvm.ptrauth.blend( -// NODEBUG-NOT: call -// CHECK: musttail call void +// CHECK: musttail call void{{.*}} [ "ptrauth"({{.*}}) ] // CHECK-NEXT: ret void // CHECK: define linkonce_odr hidden void @_ZN5Base18virtual7Ev_vfpthunk_(ptr noundef %[[THIS:.*]]) @@ -211,7 +207,7 @@ struct Class0 { // CHECK: %[[V0:.*]] = load ptr, ptr %[[THIS_ADDR]], align 8 // CHECK: %[[VTABLE:.*]] = load ptr, ptr %[[THIS1]], align 8 // CHECK: %[[V1:.*]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[V2:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V1]], i32 2, i64 0) +// CHECK: %[[V2:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V1]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[V3:.*]] = inttoptr i64 %[[V2]] to ptr // CHECK: getelementptr inbounds ptr, ptr %[[V3]], i64 0 @@ -222,7 +218,7 @@ struct Class0 { // CHECK: load ptr, ptr %[[THIS_ADDR]], align 8 // CHECK: %[[VTABLE:.*]] = load ptr, ptr %[[THIS1]], align 8 // CHECK: %[[V1:.*]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[V2:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V1]], i32 2, i64 0) +// CHECK: %[[V2:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V1]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[V3:.*]] = inttoptr i64 %[[V2]] to ptr // CHECK: getelementptr inbounds ptr, ptr %[[V3]], i64 3 @@ -281,7 +277,7 @@ void test0() { // CHECK: %[[VTABLE:.*]] = load ptr, ptr %[[V4]], align 8 // CHECK: %[[V7:.*]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[V8:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V7]], i32 2, i64 0) +// CHECK: %[[V8:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V7]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[V9:.*]] = inttoptr i64 %[[V8]] to ptr // DARWIN: %[[V10:.*]] = trunc i64 %[[MEMPTR_PTR]] to i32 // DARWIN: %[[V11:.*]] = zext i32 %[[V10]] to i64 @@ -295,7 +291,7 @@ void test0() { // CHECK: %[[V14:.*]] = phi ptr [ %[[MEMPTR_VIRTUALFN]], {{.*}} ], [ %[[MEMPTR_NONVIRTUALFN]], {{.*}} ] // CHECK: %[[V15:.*]] = phi i64 [ 0, {{.*}} ], [ [[TYPEDISC0]], {{.*}} ] -// CHECK: call void %[[V14]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %[[V4]]) [ "ptrauth"(i32 0, i64 %[[V15]]) ] +// CHECK: call void %[[V14]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %[[V4]]) [ "ptrauth"(i64 0, i64 0, i64 %[[V15]]) ] // CHECK: ret void void test1(Base0 *a0, MethodTy0 a1) { @@ -305,7 +301,7 @@ void test1(Base0 *a0, MethodTy0 a1) { // CXX17: define{{.*}} void @_Z14test1_noexceptP5Base0MS_DoFvvE( // CXX17: %[[V14:.*]] = phi ptr [ %{{.*}}, {{.*}} ], [ %{{.*}}, {{.*}} ] // CXX17: %[[V15:.*]] = phi i64 [ 0, {{.*}} ], [ [[TYPEDISC0]], {{.*}} ] -// CXX17: call void %[[V14]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %{{.*}}) {{.*}}[ "ptrauth"(i32 0, i64 %[[V15]]) ] +// CXX17: call void %[[V14]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(8) %{{.*}}) {{.*}}[ "ptrauth"(i64 0, i64 0, i64 %[[V15]]) ] #if __cplusplus >= 201703L void test1_noexcept(Base0 *a0, NoExceptMethodTy0 a1) { (a0->*a1)(); @@ -335,7 +331,7 @@ void test1_noexcept(Base0 *a0, NoExceptMethodTy0 a1) { // CHECK: br i1 %[[V5]] // CHECK: %[[V6:.*]] = ptrtoint ptr %[[V4]] to i64 -// CHECK: %[[V7:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V6]], i32 0, i64 [[TYPEDISC0]], i32 0, i64 [[TYPEDISC1]]) +// CHECK: %[[V7:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V6]]) [ "ptrauth"(i64 0, i64 [[TYPEDISC0]], i64 0), "ptrauth"(i64 0, i64 [[TYPEDISC1]], i64 0) ] // CHECK: %[[V8:.*]] = inttoptr i64 %[[V7]] to ptr // CHECK: br @@ -353,21 +349,21 @@ void testConversion0(MethodTy0 method0, MethodTy1 method1) { } // CHECK: define{{.*}} void @_Z15testConversion1M5Base0FvvE( -// CHECK: call i64 @llvm.ptrauth.resign(i64 %{{.*}}, i32 0, i64 [[TYPEDISC0]], i32 0, i64 [[TYPEDISC1]]) +// CHECK: call i64 @llvm.ptrauth.resign(i64 %{{.*}}) [ "ptrauth"(i64 0, i64 [[TYPEDISC0]], i64 0), "ptrauth"(i64 0, i64 [[TYPEDISC1]], i64 0) ] void testConversion1(MethodTy0 method0) { MethodTy1 method1 = reinterpret_cast(method0); } // CHECK: define{{.*}} void @_Z15testConversion2M8Derived0FvvE( -// CHECK: call i64 @llvm.ptrauth.resign(i64 %{{.*}}, i32 0, i64 [[TYPEDISC1]], i32 0, i64 [[TYPEDISC0]]) +// CHECK: call i64 @llvm.ptrauth.resign(i64 %{{.*}}) [ "ptrauth"(i64 0, i64 [[TYPEDISC1]], i64 0), "ptrauth"(i64 0, i64 [[TYPEDISC0]], i64 0) ] void testConversion2(MethodTy1 method1) { MethodTy0 method0 = static_cast(method1); } // CHECK: define{{.*}} void @_Z15testConversion3M8Derived0FvvE( -// CHECK: call i64 @llvm.ptrauth.resign(i64 %{{.*}}, i32 0, i64 [[TYPEDISC1]], i32 0, i64 [[TYPEDISC0]]) +// CHECK: call i64 @llvm.ptrauth.resign(i64 %{{.*}}) [ "ptrauth"(i64 0, i64 [[TYPEDISC1]], i64 0), "ptrauth"(i64 0, i64 [[TYPEDISC0]], i64 0) ] void testConversion3(MethodTy1 method1) { MethodTy0 method0 = reinterpret_cast(method1); @@ -378,7 +374,7 @@ void testConversion3(MethodTy1 method1) { // CHECK: define{{.*}} void @_Z15testConversion4v( // CHECK: %[[METHOD0:.*]] = alloca { i64, i64 }, align 8 -// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 [[TYPEDISC0]]) to i64), i64 0 }, ptr %[[METHOD0]], align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, [i64 0, i64 [[TYPEDISC0]], i64 0]) to i64), i64 0 }, ptr %[[METHOD0]], align 8 // CHECK: ret void void testConversion4() { @@ -427,8 +423,8 @@ MethodTy0 gmethod2 = reinterpret_cast(&Derived0::virtual1); // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %p1, ptr align 8 @__const._Z13testArrayInitv.p1, i64 16, i1 false) // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %c0, ptr align 8 @__const._Z13testArrayInitv.c0, i64 16, i1 false) // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %c1, ptr align 8 @__const._Z13testArrayInitv.c1, i64 16, i1 false) -// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %{{.*}} align 8 -// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, i32 0, i64 [[TYPEDISC1]]) to i64), i64 0 }, ptr %{{.*}}, align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base011nonvirtual0Ev, [i64 0, i64 [[TYPEDISC1]], i64 0]) to i64), i64 0 }, ptr %{{.*}} align 8 +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN5Base08virtual1Ev_vfpthunk_, [i64 0, i64 [[TYPEDISC1]], i64 0]) to i64), i64 0 }, ptr %{{.*}}, align 8 void initList(std::initializer_list); @@ -466,11 +462,11 @@ namespace testNoexceptConversion { // CHECK: define {{.*}}void @_ZN22testNoexceptConversion5test0Ev() // CHECK: %[[P0:.*]] = alloca { i64, i64 }, align 8 -// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S19nonvirtual_noexceptEv, i32 0, i64 [[TYPEDISC3]]) to i64), i64 0 }, ptr %[[P0]], align 8, +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S19nonvirtual_noexceptEv, [i64 0, i64 [[TYPEDISC3]], i64 0]) to i64), i64 0 }, ptr %[[P0]], align 8, // CHECK: define {{.*}}void @_ZN22testNoexceptConversion5test1Ev() // CHECK: %[[P0:.*]] = alloca { i64, i64 }, align 8 -// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S16virtual_noexceptEv_vfpthunk_, i32 0, i64 [[TYPEDISC3]]) to i64), i64 0 }, ptr %[[P0]], align 8, +// CHECK: store { i64, i64 } { i64 ptrtoint (ptr ptrauth (ptr @_ZN22testNoexceptConversion1S16virtual_noexceptEv_vfpthunk_, [i64 0, i64 [[TYPEDISC3]], i64 0]) to i64), i64 0 }, ptr %[[P0]], align 8, // CHECK: define {{.*}}void @_ZN22testNoexceptConversion5test2Ev() // CHECK: %[[P0:.*]] = alloca { i64, i64 }, align 8 diff --git a/clang/test/CodeGenCXX/ptrauth-qualifier-struct.cpp b/clang/test/CodeGenCXX/ptrauth-qualifier-struct.cpp index 0310535362e3d..f34e112da6eac 100644 --- a/clang/test/CodeGenCXX/ptrauth-qualifier-struct.cpp +++ b/clang/test/CodeGenCXX/ptrauth-qualifier-struct.cpp @@ -63,11 +63,9 @@ void testMoveConstructor(SA a) { // CHECK: %[[M02:.*]] = getelementptr inbounds nuw %[[STRUCT_SA]], ptr %[[V1]], i32 0, i32 0 // CHECK: %[[V2:.*]] = load ptr, ptr %[[M02]], align 8 // CHECK: %[[V3:.*]] = ptrtoint ptr %[[M02]] to i64 -// CHECK: %[[V4:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V3]], i64 50) // CHECK: %[[V5:.*]] = ptrtoint ptr %[[M0]] to i64 -// CHECK: %[[V6:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V5]], i64 50) // CHECK: %[[V8:.*]] = ptrtoint ptr %[[V2]] to i64 -// CHECK: %[[V9:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V8]], i32 1, i64 %[[V4]], i32 1, i64 %[[V6]]) +// CHECK: %[[V9:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V8]]) [ "ptrauth"(i64 1, i64 50, i64 %[[V3]]), "ptrauth"(i64 1, i64 50, i64 %[[V5]]) ] void testCopyAssignment(SA a) { SA t; @@ -88,11 +86,9 @@ void testCopyAssignment(SA a) { // CHECK: %[[M02:.*]] = getelementptr inbounds nuw %[[STRUCT_SA]], ptr %[[V1]], i32 0, i32 0 // CHECK: %[[V2:.*]] = load ptr, ptr %[[M02]], align 8 // CHECK: %[[V3:.*]] = ptrtoint ptr %[[M02]] to i64 -// CHECK: %[[V4:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V3]], i64 50) // CHECK: %[[V5:.*]] = ptrtoint ptr %[[M0]] to i64 -// CHECK: %[[V6:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V5]], i64 50) // CHECK: %[[V8:.*]] = ptrtoint ptr %[[V2]] to i64 -// CHECK: %[[V9:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V8]], i32 1, i64 %[[V4]], i32 1, i64 %[[V6]]) +// CHECK: %[[V9:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V8]]) [ "ptrauth"(i64 1, i64 50, i64 %[[V3]]), "ptrauth"(i64 1, i64 50, i64 %[[V5]]) ] void testMoveAssignment(SA a) { SA t; @@ -142,11 +138,9 @@ void testMoveAssignment(SI a) { // CHECK: %[[M02:.*]] = getelementptr inbounds nuw %[[STRUCT_SA]], ptr %[[V1]], i32 0, i32 0 // CHECK: %[[V2:.*]] = load ptr, ptr %[[M02]], align 8 // CHECK: %[[V3:.*]] = ptrtoint ptr %[[M02]] to i64 -// CHECK: %[[V4:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V3]], i64 50) // CHECK: %[[V5:.*]] = ptrtoint ptr %[[M0]] to i64 -// CHECK: %[[V6:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V5]], i64 50) // CHECK: %[[V8:.*]] = ptrtoint ptr %[[V2]] to i64 -// CHECK: %[[V9:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V8]], i32 1, i64 %[[V4]], i32 1, i64 %[[V6]]) +// CHECK: %[[V9:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V8]]) [ "ptrauth"(i64 1, i64 50, i64 %[[V3]]), "ptrauth"(i64 1, i64 50, i64 %[[V5]]) ] // CHECK: define linkonce_odr {{.*}}@_ZN2SAC2EOS_(ptr noundef nonnull align 8 dereferenceable(16) %[[THIS:.*]], ptr noundef nonnull align 8 dereferenceable(16) %0) // IOS: %[[RETVAL:.*]] = alloca ptr, align 8 @@ -161,8 +155,6 @@ void testMoveAssignment(SI a) { // CHECK: %[[M02:.*]] = getelementptr inbounds nuw %[[STRUCT_SA]], ptr %[[V1]], i32 0, i32 0 // CHECK: %[[V2:.*]] = load ptr, ptr %[[M02]], align 8 // CHECK: %[[V3:.*]] = ptrtoint ptr %[[M02]] to i64 -// CHECK: %[[V4:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V3]], i64 50) // CHECK: %[[V5:.*]] = ptrtoint ptr %[[M0]] to i64 -// CHECK: %[[V6:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V5]], i64 50) // CHECK: %[[V8:.*]] = ptrtoint ptr %[[V2]] to i64 -// CHECK: %[[V9:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V8]], i32 1, i64 %[[V4]], i32 1, i64 %[[V6]]) +// CHECK: %[[V9:.*]] = call i64 @llvm.ptrauth.resign(i64 %[[V8]]) [ "ptrauth"(i64 1, i64 50, i64 %[[V3]]), "ptrauth"(i64 1, i64 50, i64 %[[V5]]) ] diff --git a/clang/test/CodeGenCXX/ptrauth-rtti-layout.cpp b/clang/test/CodeGenCXX/ptrauth-rtti-layout.cpp index b50e0908f9db8..50417f8958fb0 100644 --- a/clang/test/CodeGenCXX/ptrauth-rtti-layout.cpp +++ b/clang/test/CodeGenCXX/ptrauth-rtti-layout.cpp @@ -5,11 +5,11 @@ struct A { int a; }; -// DARWIN: @_ZTI1A = linkonce_odr hidden constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr inttoptr (i64 add (i64 ptrtoint (ptr @_ZTS1A to i64), i64 -9223372036854775808) to ptr) } +// DARWIN: @_ZTI1A = linkonce_odr hidden constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), [i64 2, i64 0, i64 0]), ptr inttoptr (i64 add (i64 ptrtoint (ptr @_ZTS1A to i64), i64 -9223372036854775808) to ptr) } // DARWIN: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr] // DARWIN: @_ZTS1A = linkonce_odr hidden constant [3 x i8] c"1A\00" -// ELF: @_ZTI1A = linkonce_odr constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr @_ZTS1A } +// ELF: @_ZTI1A = linkonce_odr constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), [i64 2, i64 0, i64 0]), ptr @_ZTS1A } // ELF: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr] // ELF: @_ZTS1A = linkonce_odr constant [3 x i8] c"1A\00" diff --git a/clang/test/CodeGenCXX/ptrauth-static-destructors.cpp b/clang/test/CodeGenCXX/ptrauth-static-destructors.cpp index 634450bf62ea9..26350a4c7f2ff 100644 --- a/clang/test/CodeGenCXX/ptrauth-static-destructors.cpp +++ b/clang/test/CodeGenCXX/ptrauth-static-destructors.cpp @@ -33,13 +33,13 @@ class Foo { Foo global; // CXAATEXIT: define internal void @__cxx_global_var_init() -// CXAATEXIT: call i32 @__cxa_atexit(ptr ptrauth (ptr @_ZN3FooD1Ev, i32 0), ptr @global, ptr @__dso_handle) +// CXAATEXIT: call i32 @__cxa_atexit(ptr ptrauth (ptr @_ZN3FooD1Ev, [i64 0, i64 0, i64 0]), ptr @global, ptr @__dso_handle) // CXAATEXIT_DISC: define internal void @__cxx_global_var_init() -// CXAATEXIT_DISC: call i32 @__cxa_atexit(ptr ptrauth (ptr @_ZN3FooD1Ev, i32 0, i64 10942), ptr @global, ptr @__dso_handle) +// CXAATEXIT_DISC: call i32 @__cxa_atexit(ptr ptrauth (ptr @_ZN3FooD1Ev, [i64 0, i64 10942, i64 0]), ptr @global, ptr @__dso_handle) // ATEXIT: define internal void @__cxx_global_var_init() -// ATEXIT: %{{.*}} = call i32 @atexit(ptr ptrauth (ptr @__dtor_global, i32 0)) +// ATEXIT: %{{.*}} = call i32 @atexit(ptr ptrauth (ptr @__dtor_global, [i64 0, i64 0, i64 0])) // ATEXIT_DARWIN: define internal void @__dtor_global() {{.*}} section "__TEXT,__StaticInit,regular,pure_instructions" { // ATEXIT_ELF: define internal void @__dtor_global() {{.*}} section ".text.startup" { @@ -47,7 +47,7 @@ Foo global; // ATEXIT_ELF: call void @_ZN3FooD1Ev(ptr @global) // ATEXIT_DISC: define internal void @__cxx_global_var_init() -// ATEXIT_DISC: %{{.*}} = call i32 @atexit(ptr ptrauth (ptr @__dtor_global, i32 0, i64 10942)) +// ATEXIT_DISC: %{{.*}} = call i32 @atexit(ptr ptrauth (ptr @__dtor_global, [i64 0, i64 10942, i64 0])) // ATEXIT_DISC_DARWIN: define internal void @__dtor_global() {{.*}} section "__TEXT,__StaticInit,regular,pure_instructions" { diff --git a/clang/test/CodeGenCXX/ptrauth-throw.cpp b/clang/test/CodeGenCXX/ptrauth-throw.cpp index 0e6091a370223..f928f970b5051 100644 --- a/clang/test/CodeGenCXX/ptrauth-throw.cpp +++ b/clang/test/CodeGenCXX/ptrauth-throw.cpp @@ -11,10 +11,10 @@ class Foo { }; // CHECK-LABEL: define{{.*}} void @_Z1fv() -// CHECK: call void @__cxa_throw(ptr %{{.*}}, ptr @_ZTI3Foo, ptr ptrauth (ptr @_ZN3FooD1Ev, i32 0)) +// CHECK: call void @__cxa_throw(ptr %{{.*}}, ptr @_ZTI3Foo, ptr ptrauth (ptr @_ZN3FooD1Ev, [i64 0, i64 0, i64 0])) // CHECKDISC-LABEL: define{{.*}} void @_Z1fv() -// CHECKDISC: call void @__cxa_throw(ptr %{{.*}}, ptr @_ZTI3Foo, ptr ptrauth (ptr @_ZN3FooD1Ev, i32 0, i64 10942)) +// CHECKDISC: call void @__cxa_throw(ptr %{{.*}}, ptr @_ZTI3Foo, ptr ptrauth (ptr @_ZN3FooD1Ev, [i64 0, i64 10942, i64 0])) void f() { throw Foo(); @@ -22,10 +22,10 @@ void f() { // __cxa_throw is defined to take its destructor as "void (*)(void *)" in the ABI. // CHECK-LABEL: define{{.*}} void @__cxa_throw({{.*}}) -// CHECK: call void {{%.*}}(ptr noundef {{%.*}}) [ "ptrauth"(i32 0, i64 0) ] +// CHECK: call void {{%.*}}(ptr noundef {{%.*}}) [ "ptrauth"(i64 0, i64 0, i64 0) ] // CHECKDISC-LABEL: define{{.*}} void @__cxa_throw({{.*}}) -// CHECKDISC: call void {{%.*}}(ptr noundef {{%.*}}) [ "ptrauth"(i32 0, i64 10942) ] +// CHECKDISC: call void {{%.*}}(ptr noundef {{%.*}}) [ "ptrauth"(i64 0, i64 10942, i64 0) ] extern "C" void __cxa_throw(void *exception, void *, void (*dtor)(void *)) { dtor(exception); diff --git a/clang/test/CodeGenCXX/ptrauth-thunks.cpp b/clang/test/CodeGenCXX/ptrauth-thunks.cpp index f4491a3aab7ab..017b9a900bfbd 100644 --- a/clang/test/CodeGenCXX/ptrauth-thunks.cpp +++ b/clang/test/CodeGenCXX/ptrauth-thunks.cpp @@ -26,4 +26,4 @@ namespace Test1 { // CHECK: %[[This:.*]] = load ptr // CHECK: %[[SignedVTable:.*]] = load ptr, ptr %[[This]], align 8 // CHECK: %[[SignedVTableAsInt:.*]] = ptrtoint ptr %[[SignedVTable]] to i64 -// CHECK: %[[VTable:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[SignedVTableAsInt]], i32 2, i64 0) +// CHECK: %[[VTable:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[SignedVTableAsInt]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] diff --git a/clang/test/CodeGenCXX/ptrauth-type-info-vtable.cpp b/clang/test/CodeGenCXX/ptrauth-type-info-vtable.cpp index f4396e4027039..e5db0841cb82e 100644 --- a/clang/test/CodeGenCXX/ptrauth-type-info-vtable.cpp +++ b/clang/test/CodeGenCXX/ptrauth-type-info-vtable.cpp @@ -59,11 +59,11 @@ static_assert(__has_feature(ptrauth_type_info_vtable_pointer_discrimination) == // CHECK: @disc_std_type_info = global i32 [[STDTYPEINFO_DISC:45546]] extern "C" int disc_std_type_info = __builtin_ptrauth_string_discriminator("_ZTVSt9type_info"); -// CHECK: @_ZTV10TestStruct = unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTI10TestStruct, ptr ptrauth (ptr @_ZN10TestStructD1Ev, i32 0, i64 52216, ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV10TestStruct, i32 0, i32 0, i32 2)), ptr ptrauth (ptr @_ZN10TestStructD0Ev, i32 0, i64 39671, ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV10TestStruct, i32 0, i32 0, i32 3))] }, align 8 +// CHECK: @_ZTV10TestStruct = unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTI10TestStruct, ptr ptrauth (ptr @_ZN10TestStructD1Ev, [i64 0, i64 52216, i64 ptrtoint (ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV10TestStruct, i32 0, i32 0, i32 2) to i64)]), ptr ptrauth (ptr @_ZN10TestStructD0Ev, [i64 0, i64 39671, i64 ptrtoint (ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV10TestStruct, i32 0, i32 0, i32 3) to i64)])] }, align 8 -// NODISC: @_ZTI10TestStruct = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr @_ZTS10TestStruct }, align 8 +// NODISC: @_ZTI10TestStruct = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), [i64 2, i64 0, i64 0]), ptr @_ZTS10TestStruct }, align 8 -// DISC: @_ZTI10TestStruct = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2, i64 [[STDTYPEINFO_DISC]], ptr @_ZTI10TestStruct), ptr @_ZTS10TestStruct }, align 8 +// DISC: @_ZTI10TestStruct = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), [i64 2, i64 [[STDTYPEINFO_DISC]], i64 ptrtoint (ptr @_ZTI10TestStruct to i64)]), ptr @_ZTS10TestStruct }, align 8 // CHECK: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr] // CHECK: @_ZTS10TestStruct = constant [13 x i8] c"10TestStruct\00", align 1 @@ -84,7 +84,7 @@ extern "C" void test_vtable(std::type_info* t) { // NODISC: [[T:%.*]] = load ptr, ptr [[T_ADDR]], align 8 // NODISC: [[VPTR:%.*]] = load ptr, ptr [[T]], align 8 // NODISC: [[CAST_VPTR:%.*]] = ptrtoint ptr [[VPTR]] to i64 -// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[CAST_VPTR]], i32 2, i64 0) +// NODISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[CAST_VPTR]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // DISC: define{{.*}} void @test_vtable(ptr noundef %t) // DISC: [[T_ADDR:%.*]] = alloca ptr, align 8 @@ -92,9 +92,8 @@ extern "C" void test_vtable(std::type_info* t) { // DISC: [[T:%.*]] = load ptr, ptr [[T_ADDR]], align 8 // DISC: [[VPTR:%.*]] = load ptr, ptr [[T]], align 8 // DISC: [[ADDR:%.*]] = ptrtoint ptr [[T]] to i64 -// DISC: [[DISCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[ADDR]], i64 [[STDTYPEINFO_DISC]]) // DISC: [[VPTRI:%.*]] = ptrtoint ptr [[VPTR]] to i64 -// DISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VPTRI]], i32 2, i64 [[DISCRIMINATOR]]) +// DISC: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VPTRI]]) [ "ptrauth"(i64 2, i64 [[STDTYPEINFO_DISC]], i64 [[ADDR]]) ] extern "C" const void *ensure_typeinfo() { return new TestStruct; diff --git a/clang/test/CodeGenCXX/ptrauth-virtual-function.cpp b/clang/test/CodeGenCXX/ptrauth-virtual-function.cpp index 4aa24738d8ce3..c0b9a600869dd 100644 --- a/clang/test/CodeGenCXX/ptrauth-virtual-function.cpp +++ b/clang/test/CodeGenCXX/ptrauth-virtual-function.cpp @@ -5,90 +5,90 @@ // CHECK: %[[CLASS_B1:.*]] = type { ptr } -// CHECK: @_ZTV2B1 = unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr @_ZTI2B1, ptr ptrauth (ptr @_ZN2B12m0Ev, i32 0, i64 58196, ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV2B1, i32 0, i32 0, i32 2))] }, align 8 +// CHECK: @_ZTV2B1 = unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr @_ZTI2B1, ptr ptrauth (ptr @_ZN2B12m0Ev, [i64 0, i64 58196, i64 ptrtoint (ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTV2B1, i32 0, i32 0, i32 2) to i64)])] }, align 8 -// CHECK: @g_B1 = global %class.B1 { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV2B1, i32 0, i32 0, i32 2), i32 2) }, align 8 +// CHECK: @g_B1 = global %class.B1 { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV2B1, i32 0, i32 0, i32 2), [i64 2, i64 0, i64 0]) }, align 8 // CHECK: @_ZTV2B0 = unnamed_addr constant { [7 x ptr] } { [7 x ptr] [ptr null, ptr @_ZTI2B0, -// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m0Ev, i32 0, i64 53119, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 2)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m1Ev, i32 0, i64 15165, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, i32 0, i64 43073, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2B0D1Ev, i32 0, i64 25525, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 5)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2B0D0Ev, i32 0, i64 21295, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 6))] }, align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m0Ev, [i64 0, i64 53119, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 2) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m1Ev, [i64 0, i64 15165, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, [i64 0, i64 43073, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2B0D1Ev, [i64 0, i64 25525, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 5) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2B0D0Ev, [i64 0, i64 21295, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 6) to i64)])] }, align 8 // CHECK: @_ZTV2D0 = unnamed_addr constant { [9 x ptr] } { [9 x ptr] [ptr null, ptr @_ZTI2D0, -// CHECK-SAME: ptr ptrauth (ptr @_ZN2D02m0Ev, i32 0, i64 53119, ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 2)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTch0_h4_N2D02m1Ev, i32 0, i64 15165, ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, i32 0, i64 43073, ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2D0D1Ev, i32 0, i64 25525, ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 5)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2D0D0Ev, i32 0, i64 21295, ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 6)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2D02m1Ev, i32 0, i64 35045, ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 7)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2D02m3Ev, i32 0, i64 10565, ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 8))] }, align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZN2D02m0Ev, [i64 0, i64 53119, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 2) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTch0_h4_N2D02m1Ev, [i64 0, i64 15165, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, [i64 0, i64 43073, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2D0D1Ev, [i64 0, i64 25525, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 5) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2D0D0Ev, [i64 0, i64 21295, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 6) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2D02m1Ev, [i64 0, i64 35045, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 7) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2D02m3Ev, [i64 0, i64 10565, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 8) to i64)])] }, align 8 // CHECK: @_ZTV2D1 = unnamed_addr constant { [8 x ptr] } { [8 x ptr] [ptr null, ptr @_ZTI2D1, -// CHECK-SAME: ptr ptrauth (ptr @_ZN2D12m0Ev, i32 0, i64 53119, ptr getelementptr inbounds ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 2)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTch0_h4_N2D12m1Ev, i32 0, i64 15165, ptr getelementptr inbounds ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, i32 0, i64 43073, ptr getelementptr inbounds ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2D1D1Ev, i32 0, i64 25525, ptr getelementptr inbounds ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 5)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2D1D0Ev, i32 0, i64 21295, ptr getelementptr inbounds ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 6)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2D12m1Ev, i32 0, i64 52864, ptr getelementptr inbounds ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 7))] }, align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZN2D12m0Ev, [i64 0, i64 53119, i64 ptrtoint (ptr getelementptr inbounds ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 2) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTch0_h4_N2D12m1Ev, [i64 0, i64 15165, i64 ptrtoint (ptr getelementptr inbounds ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, [i64 0, i64 43073, i64 ptrtoint (ptr getelementptr inbounds ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2D1D1Ev, [i64 0, i64 25525, i64 ptrtoint (ptr getelementptr inbounds ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 5) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2D1D0Ev, [i64 0, i64 21295, i64 ptrtoint (ptr getelementptr inbounds ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 6) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2D12m1Ev, [i64 0, i64 52864, i64 ptrtoint (ptr getelementptr inbounds ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 7) to i64)])] }, align 8 // CHECK: @_ZTV2D2 = unnamed_addr constant { [9 x ptr], [8 x ptr] } { [9 x ptr] [ptr null, ptr @_ZTI2D2, -// CHECK-SAME: ptr ptrauth (ptr @_ZN2D22m0Ev, i32 0, i64 53119, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 2)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTch0_h4_N2D22m1Ev, i32 0, i64 15165, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, i32 0, i64 43073, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2D2D1Ev, i32 0, i64 25525, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 5)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2D2D0Ev, i32 0, i64 21295, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 6)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2D22m1Ev, i32 0, i64 35045, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 7)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2D22m3Ev, i32 0, i64 10565, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 8))], +// CHECK-SAME: ptr ptrauth (ptr @_ZN2D22m0Ev, [i64 0, i64 53119, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 2) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTch0_h4_N2D22m1Ev, [i64 0, i64 15165, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, [i64 0, i64 43073, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2D2D1Ev, [i64 0, i64 25525, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 5) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2D2D0Ev, [i64 0, i64 21295, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 6) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2D22m1Ev, [i64 0, i64 35045, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 7) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2D22m3Ev, [i64 0, i64 10565, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 8) to i64)])], // CHECK-SAME: [8 x ptr] [ptr inttoptr (i64 -16 to ptr), ptr @_ZTI2D2, -// CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D22m0Ev, i32 0, i64 53119, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 2)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTchn16_h4_N2D22m1Ev, i32 0, i64 15165, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, i32 0, i64 43073, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D2D1Ev, i32 0, i64 25525, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 5)), -// CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D2D0Ev, i32 0, i64 21295, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 6)), -// CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D22m1Ev, i32 0, i64 52864, ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 7))] }, align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D22m0Ev, [i64 0, i64 53119, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 2) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTchn16_h4_N2D22m1Ev, [i64 0, i64 15165, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, [i64 0, i64 43073, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D2D1Ev, [i64 0, i64 25525, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 5) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D2D0Ev, [i64 0, i64 21295, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 6) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D22m1Ev, [i64 0, i64 52864, i64 ptrtoint (ptr getelementptr inbounds ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 7) to i64)])] }, align 8 // CHECK: @_ZTV2D3 = unnamed_addr constant { [7 x ptr], [7 x ptr], [11 x ptr] } { [7 x ptr] [ptr inttoptr (i64 32 to ptr), ptr null, ptr @_ZTI2D3, -// CHECK-SAME: ptr ptrauth (ptr @_ZN2D32m0Ev, i32 0, i64 44578, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 0, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2D32m1Ev, i32 0, i64 30766, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 0, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2D3D1Ev, i32 0, i64 57279, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 0, i32 5)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2D3D0Ev, i32 0, i64 62452, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 0, i32 6))], +// CHECK-SAME: ptr ptrauth (ptr @_ZN2D32m0Ev, [i64 0, i64 44578, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 0, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2D32m1Ev, [i64 0, i64 30766, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 0, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2D3D1Ev, [i64 0, i64 57279, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 0, i32 5) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2D3D0Ev, [i64 0, i64 62452, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 0, i32 6) to i64)])], // CHECK-SAME: [7 x ptr] [ptr inttoptr (i64 16 to ptr), ptr inttoptr (i64 -16 to ptr), ptr @_ZTI2D3, -// CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D32m0Ev, i32 0, i64 49430, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 1, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D32m1Ev, i32 0, i64 57119, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 1, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D3D1Ev, i32 0, i64 60799, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 1, i32 5)), -// CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D3D0Ev, i32 0, i64 52565, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 1, i32 6))], +// CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D32m0Ev, [i64 0, i64 49430, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 1, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D32m1Ev, [i64 0, i64 57119, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 1, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D3D1Ev, [i64 0, i64 60799, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 1, i32 5) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZThn16_N2D3D0Ev, [i64 0, i64 52565, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 1, i32 6) to i64)])], // CHECK-SAME: [11 x ptr] [ptr inttoptr (i64 -32 to ptr), ptr null, ptr inttoptr (i64 -32 to ptr), ptr inttoptr (i64 -32 to ptr), ptr inttoptr (i64 -32 to ptr), ptr @_ZTI2D3, -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n24_N2D32m0Ev, i32 0, i64 53119, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 2, i32 6)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTcv0_n32_h4_N2D32m1Ev, i32 0, i64 15165, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 2, i32 7)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, i32 0, i64 43073, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 2, i32 8)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N2D3D1Ev, i32 0, i64 25525, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 2, i32 9)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N2D3D0Ev, i32 0, i64 21295, ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 2, i32 10))] }, align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n24_N2D32m0Ev, [i64 0, i64 53119, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 2, i32 6) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTcv0_n32_h4_N2D32m1Ev, [i64 0, i64 15165, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 2, i32 7) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, [i64 0, i64 43073, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 2, i32 8) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N2D3D1Ev, [i64 0, i64 25525, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 2, i32 9) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N2D3D0Ev, [i64 0, i64 21295, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [7 x ptr], [11 x ptr] }, ptr @_ZTV2D3, i32 0, i32 2, i32 10) to i64)])] }, align 8 // CHECK: @_ZTC2D30_2V0 = unnamed_addr constant { [7 x ptr], [11 x ptr] } { [7 x ptr] [ptr inttoptr (i64 32 to ptr), ptr null, ptr @_ZTI2V0, -// CHECK-SAME: ptr ptrauth (ptr @_ZN2V02m0Ev, i32 0, i64 44578, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 0, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2V02m1Ev, i32 0, i64 30766, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 0, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2V0D1Ev, i32 0, i64 57279, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 0, i32 5)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2V0D0Ev, i32 0, i64 62452, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 0, i32 6))], +// CHECK-SAME: ptr ptrauth (ptr @_ZN2V02m0Ev, [i64 0, i64 44578, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 0, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2V02m1Ev, [i64 0, i64 30766, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 0, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2V0D1Ev, [i64 0, i64 57279, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 0, i32 5) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2V0D0Ev, [i64 0, i64 62452, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 0, i32 6) to i64)])], // CHECK-SAME: [11 x ptr] [ptr inttoptr (i64 -32 to ptr), ptr null, ptr inttoptr (i64 -32 to ptr), ptr inttoptr (i64 -32 to ptr), ptr inttoptr (i64 -32 to ptr), ptr @_ZTI2V0, -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n24_N2V02m0Ev, i32 0, i64 53119, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 1, i32 6)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTcv0_n32_h4_N2V02m1Ev, i32 0, i64 15165, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 1, i32 7)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, i32 0, i64 43073, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 1, i32 8)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N2V0D1Ev, i32 0, i64 25525, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 1, i32 9)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N2V0D0Ev, i32 0, i64 21295, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 1, i32 10))] }, align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n24_N2V02m0Ev, [i64 0, i64 53119, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 1, i32 6) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTcv0_n32_h4_N2V02m1Ev, [i64 0, i64 15165, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 1, i32 7) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, [i64 0, i64 43073, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 1, i32 8) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N2V0D1Ev, [i64 0, i64 25525, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 1, i32 9) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N2V0D0Ev, [i64 0, i64 21295, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D30_2V0, i32 0, i32 1, i32 10) to i64)])] }, align 8 // CHECK: @_ZTC2D316_2V1 = unnamed_addr constant { [7 x ptr], [11 x ptr] } { [7 x ptr] [ptr inttoptr (i64 16 to ptr), ptr null, ptr @_ZTI2V1, -// CHECK-SAME: ptr ptrauth (ptr @_ZN2V12m0Ev, i32 0, i64 49430, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 0, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2V12m1Ev, i32 0, i64 57119, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 0, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2V1D1Ev, i32 0, i64 60799, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 0, i32 5)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2V1D0Ev, i32 0, i64 52565, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 0, i32 6))], +// CHECK-SAME: ptr ptrauth (ptr @_ZN2V12m0Ev, [i64 0, i64 49430, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 0, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2V12m1Ev, [i64 0, i64 57119, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 0, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2V1D1Ev, [i64 0, i64 60799, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 0, i32 5) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2V1D0Ev, [i64 0, i64 52565, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 0, i32 6) to i64)])], // CHECK-SAME: [11 x ptr] [ptr inttoptr (i64 -16 to ptr), ptr null, ptr inttoptr (i64 -16 to ptr), ptr inttoptr (i64 -16 to ptr), ptr inttoptr (i64 -16 to ptr), ptr @_ZTI2V1, -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n24_N2V12m0Ev, i32 0, i64 53119, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 1, i32 6)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTcv0_n32_h4_N2V12m1Ev, i32 0, i64 15165, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 1, i32 7)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, i32 0, i64 43073, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 1, i32 8)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N2V1D1Ev, i32 0, i64 25525, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 1, i32 9)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N2V1D0Ev, i32 0, i64 21295, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 1, i32 10))] }, align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n24_N2V12m0Ev, [i64 0, i64 53119, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 1, i32 6) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTcv0_n32_h4_N2V12m1Ev, [i64 0, i64 15165, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 1, i32 7) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN2B02m2Ev, [i64 0, i64 43073, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 1, i32 8) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N2V1D1Ev, [i64 0, i64 25525, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 1, i32 9) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N2V1D0Ev, [i64 0, i64 21295, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC2D316_2V1, i32 0, i32 1, i32 10) to i64)])] }, align 8 struct S0 { @@ -188,23 +188,22 @@ V1::~V1() { // CHECK: %[[THIS1:.*]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T1:[0-9]+]] = ptrtoint ptr %[[T0]] to i64 -// CHECK: %[[T2:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T1]], i32 2, i64 0) +// CHECK: %[[T2:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T1]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T3:[0-9]+]] = inttoptr i64 %[[T2]] to ptr // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[T3]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 %[[T6]], i32 2, i64 0) +// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 %[[T6]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[SIGNED_VTADDR:[0-9]+]] = inttoptr i64 %[[T7]] to ptr // CHECK: store ptr %[[SIGNED_VTADDR]], ptr %[[THIS1]] // CHECK-LABEL: define{{.*}} void @_Z8testB0m0P2B0( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) +// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 0 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 53119) -// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}) [ "ptrauth"(i64 0, i64 53119, i64 %[[T6]]) ] void testB0m0(B0 *a) { a->m0(); @@ -213,13 +212,12 @@ void testB0m0(B0 *a) { // CHECK-LABEL: define{{.*}} void @_Z8testB0m1P2B0( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) +// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 1 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 15165) -// CHECK: call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// CHECK: call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}) [ "ptrauth"(i64 0, i64 15165, i64 %[[T6]]) ] void testB0m1(B0 *a) { a->m1(); @@ -228,13 +226,12 @@ void testB0m1(B0 *a) { // CHECK-LABEL: define{{.*}} void @_Z8testB0m2P2B0( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) +// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 2 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 43073) -// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}) [ "ptrauth"(i64 0, i64 43073, i64 %[[T6]]) ] void testB0m2(B0 *a) { a->m2(); @@ -243,13 +240,12 @@ void testB0m2(B0 *a) { // CHECK-LABEL: define{{.*}} void @_Z8testD0m0P2D0( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) +// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 0 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 53119) -// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(16) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(16) %{{.*}}) [ "ptrauth"(i64 0, i64 53119, i64 %[[T6]]) ] void testD0m0(D0 *a) { a->m0(); @@ -258,13 +254,12 @@ void testD0m0(D0 *a) { // CHECK-LABEL: define{{.*}} void @_Z8testD0m1P2D0( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) +// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 5 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 35045) -// CHECK: call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(16) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// CHECK: call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(16) %{{.*}}) [ "ptrauth"(i64 0, i64 35045, i64 %[[T6]]) ] void testD0m1(D0 *a) { a->m1(); @@ -273,13 +268,12 @@ void testD0m1(D0 *a) { // CHECK-LABEL: define{{.*}} void @_Z8testD0m2P2D0( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) +// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 2 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 43073) -// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}) [ "ptrauth"(i64 0, i64 43073, i64 %[[T6]]) ] void testD0m2(D0 *a) { a->m2(); @@ -288,13 +282,12 @@ void testD0m2(D0 *a) { // CHECK-LABEL: define{{.*}} void @_Z8testD0m3P2D0( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) +// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 6 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 10565) -// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(16) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(16) %{{.*}}) [ "ptrauth"(i64 0, i64 10565, i64 %[[T6]]) ] void testD0m3(D0 *a) { a->m3(); @@ -304,13 +297,12 @@ void testD0m3(D0 *a) { // CHECK-LABEL: define{{.*}} void @_Z8testD1m0P2D1( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) +// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 0 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 53119) -// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(16) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(16) %{{.*}}) [ "ptrauth"(i64 0, i64 53119, i64 %[[T6]]) ] void testD1m0(D1 *a) { a->m0(); @@ -319,13 +311,12 @@ void testD1m0(D1 *a) { // CHECK-LABEL: define{{.*}} void @_Z8testD1m1P2D1( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) +// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 5 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 52864) -// CHECK: call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(16) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// CHECK: call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(16) %{{.*}}) [ "ptrauth"(i64 0, i64 52864, i64 %[[T6]]) ] void testD1m1(D1 *a) { a->m1(); @@ -334,13 +325,12 @@ void testD1m1(D1 *a) { // CHECK-LABEL: define{{.*}} void @_Z8testD1m2P2D1( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) +// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 2 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 43073) -// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(12) %{{.*}}) [ "ptrauth"(i64 0, i64 43073, i64 %[[T6]]) ] void testD1m2(D1 *a) { a->m2(); @@ -350,13 +340,12 @@ void testD1m2(D1 *a) { // CHECK-LABEL: define{{.*}} void @_Z8testD2m0P2D2( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) +// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 0 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 53119) -// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(36) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(36) %{{.*}}) [ "ptrauth"(i64 0, i64 53119, i64 %[[T6]]) ] void testD2m0(D2 *a) { a->m0(); @@ -365,13 +354,12 @@ void testD2m0(D2 *a) { // CHECK-LABEL: define{{.*}} void @_Z8testD2m1P2D2( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) +// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 5 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 35045) -// CHECK: call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(36) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// CHECK: call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(36) %{{.*}}) [ "ptrauth"(i64 0, i64 35045, i64 %[[T6]]) ] void testD2m1(D2 *a) { a->m1(); @@ -394,13 +382,12 @@ void testD2m2D1(D2 *a) { // CHECK-LABEL: define{{.*}} void @_Z8testD2m3P2D2( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) +// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 6 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 10565) -// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(36) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(36) %{{.*}}) [ "ptrauth"(i64 0, i64 10565, i64 %[[T6]]) ] void testD2m3(D2 *a) { a->m3(); @@ -409,13 +396,12 @@ void testD2m3(D2 *a) { // CHECK-LABEL: define{{.*}} void @_Z8testD3m0P2D3( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) +// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 0 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 44578) -// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) [ "ptrauth"(i64 0, i64 44578, i64 %[[T6]]) ] void testD3m0(D3 *a) { a->m0(); @@ -424,13 +410,12 @@ void testD3m0(D3 *a) { // CHECK-LABEL: define{{.*}} void @_Z8testD3m1P2D3( // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]], i32 2, i64 0) +// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T0]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 1 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 30766) -// CHECK: call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// CHECK: call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) [ "ptrauth"(i64 0, i64 30766, i64 %[[T6]]) ] void testD3m1(D3 *a) { a->m1(); @@ -442,20 +427,19 @@ void testD3m1(D3 *a) { // CHECK: %[[V0:.*]] = load ptr, ptr %[[A_ADDR]], align 8 // CHECK: %[[VTABLE:.*]] = load ptr, ptr %[[V0]], align 8 // CHECK: %[[V1:.*]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[V2:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V1]], i32 2, i64 0) +// CHECK: %[[V2:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V1]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[V3:.*]] = inttoptr i64 %[[V2]] to ptr // CHECK: %[[VBASE_OFFSET_PTR:.*]] = getelementptr i8, ptr %[[V3]], i64 -24 // CHECK: %[[VBASE_OFFSET:.*]] = load i64, ptr %[[VBASE_OFFSET_PTR]], align 8 // CHECK: %[[ADD_PTR:.*]] = getelementptr inbounds i8, ptr %[[V0]], i64 %[[VBASE_OFFSET]] // CHECK: %[[VTABLE1:.*]] = load ptr, ptr %[[ADD_PTR]], align 8 // CHECK: %[[V4:.*]] = ptrtoint ptr %[[VTABLE1]] to i64 -// CHECK: %[[V5:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V4]], i32 2, i64 0) +// CHECK: %[[V5:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[V4]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[V6:.*]] = inttoptr i64 %[[V5]] to ptr // CHECK: %[[VFN:.*]] = getelementptr inbounds ptr, ptr %[[V6]], i64 2 // CHECK: %[[V7:.*]] = load ptr, ptr %[[VFN]], align 8 // CHECK: %[[V8:.*]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[V9:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[V8]], i64 43073) -// CHECK: call void %[[V7]](ptr noundef nonnull align 8 dereferenceable(12) %[[ADD_PTR]]) [ "ptrauth"(i32 0, i64 %[[V9]]) ] +// CHECK: call void %[[V7]](ptr noundef nonnull align 8 dereferenceable(12) %[[ADD_PTR]]) [ "ptrauth"(i64 0, i64 43073, i64 %[[V8]]) ] void testD3m2(D3 *a) { a->m2(); @@ -465,13 +449,12 @@ void testD3m2(D3 *a) { // CHECK: load ptr, ptr // CHECK: %[[VTABLE:.*]] = load ptr, ptr %{{.*}} // CHECK: %[[T2:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T2]], i32 2, i64 0) +// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T2]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[VFN:[a-z]+]] = getelementptr inbounds ptr, ptr %[[T4]], i64 3 // CHECK: %[[T5:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 62452) -// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// CHECK: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i64 0, i64 62452, i64 %[[T6]]) ] void testD3Destructor0(D3 *a) { delete a; @@ -481,21 +464,20 @@ void testD3Destructor0(D3 *a) { // CHECK: %[[T6:.*]] = load ptr, ptr % // CHECK: %[[VTABLE0:[a-z0-9]+]] = load ptr, ptr % // CHECK: %[[T2:[0-9]+]] = ptrtoint ptr %[[VTABLE0]] to i64 -// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T2]], i32 2, i64 0) +// CHECK: %[[T3:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T2]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:[0-9]+]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[COMPLETE_OFFSET_PTR:.*]] = getelementptr inbounds i64, ptr %[[T4]], i64 -2 // CHECK: %[[T5:[0-9]+]] = load i64, ptr %[[COMPLETE_OFFSET_PTR]] // CHECK: %[[T7:[0-9]+]] = getelementptr inbounds i8, ptr %[[T6]], i64 %[[T5]] // CHECK: %[[VTABLE1:[a-z0-9]+]] = load ptr, ptr %[[T6]] // CHECK: %[[T9:[0-9]+]] = ptrtoint ptr %[[VTABLE1]] to i64 -// CHECK: %[[T10:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T9]], i32 2, i64 0) +// CHECK: %[[T10:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T9]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T11:[0-9]+]] = inttoptr i64 %[[T10]] to ptr // CHECK: %[[VFN:[a-z0-9]+]] = getelementptr inbounds ptr, ptr %[[T11]], i64 2 // CHECK: %[[T12:[0-9]+]] = load ptr, ptr %[[VFN]] // CHECK: %[[T13:[0-9]+]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T14:[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 %[[T13]], i64 57279) -// DARWIN: %call = call noundef ptr %[[T12]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i32 0, i64 %[[T14]]) ] -// ELF: call void %[[T12]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i32 0, i64 %[[T14]]) ] +// DARWIN: %call = call noundef ptr %[[T12]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i64 0, i64 57279, i64 %[[T13]]) ] +// ELF: call void %[[T12]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i64 0, i64 57279, i64 %[[T13]]) ] // CHECK: call void @_ZdlPv(ptr noundef %[[T7]]) void testD3Destructor1(D3 *a) { @@ -506,14 +488,13 @@ void testD3Destructor1(D3 *a) { // CHECK: load ptr, ptr // CHECK: %[[VTABLE:.*]] = load ptr, ptr % // CHECK: %[[T2:.*]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T3:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[T2]], i32 2, i64 0) +// CHECK: %[[T3:.*]] = call i64 @llvm.ptrauth.auth(i64 %[[T2]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T4:.*]] = inttoptr i64 %[[T3]] to ptr // CHECK: %[[VFN:.*]] = getelementptr inbounds ptr, ptr %[[T4]], i64 2 // CHECK: %[[T5:.*]] = load ptr, ptr %[[VFN]] // CHECK: %[[T6:.*]] = ptrtoint ptr %[[VFN]] to i64 -// CHECK: %[[T7:.*]] = call i64 @llvm.ptrauth.blend(i64 %[[T6]], i64 57279) -// DARWIN: %call = call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i32 0, i64 %[[T7]]) ] -// ELF: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i32 0, i64 %[[T7]]) ] +// DARWIN: %call = call noundef ptr %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i64 0, i64 57279, i64 %[[T6]]) ] +// ELF: call void %[[T5]](ptr noundef nonnull align {{[0-9]+}} dereferenceable(32) %{{.*}}) #{{.*}} [ "ptrauth"(i64 0, i64 57279, i64 %[[T6]]) ] void testD3Destructor2(D3 *a) { a->~D3(); @@ -533,30 +514,30 @@ void materializeConstructors() { // DARWIN-LABEL: define linkonce_odr noundef ptr @_ZN2B0C2Ev( // ELF-LABEL: define linkonce_odr void @_ZN2B0C2Ev( // CHECK: %[[THIS:.*]] = load ptr, ptr % -// CHECK: %[[T0:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 40) ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 2) to i64), i32 2, i64 0) +// CHECK: %[[T0:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 40) ({ [7 x ptr] }, ptr @_ZTV2B0, i32 0, i32 0, i32 2) to i64)) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[SIGNED_VTADDR:[0-9]+]] = inttoptr i64 %[[T0]] to ptr // CHECK: store ptr %[[SIGNED_VTADDR]], ptr %[[THIS]] // DARWIN-LABEL: define linkonce_odr noundef ptr @_ZN2D0C2Ev( // ELF-LABEL: define linkonce_odr void @_ZN2D0C2Ev( -// CHECK: %[[T0:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 56) ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 2) to i64), i32 2, i64 0) +// CHECK: %[[T0:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 56) ({ [9 x ptr] }, ptr @_ZTV2D0, i32 0, i32 0, i32 2) to i64)) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[SIGNED_VTADDR:[0-9]+]] = inttoptr i64 %[[T0]] to ptr // CHECK: store ptr %[[SIGNED_VTADDR]], ptr %[[THIS]] // DARWIN-LABEL: define linkonce_odr noundef ptr @_ZN2D1C2Ev( // ELF-LABEL: define linkonce_odr void @_ZN2D1C2Ev( -// CHECK: %[[T0:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 48) ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 2) to i64), i32 2, i64 0) +// CHECK: %[[T0:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 48) ({ [8 x ptr] }, ptr @_ZTV2D1, i32 0, i32 0, i32 2) to i64)) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[SIGNED_VTADDR:[0-9]+]] = inttoptr i64 %[[T0]] to ptr // CHECK: store ptr %[[SIGNED_VTADDR]], ptr %[[THIS]] // DARWIN-LABEL: define linkonce_odr noundef ptr @_ZN2D2C2Ev( // ELF-LABEL: define linkonce_odr void @_ZN2D2C2Ev( // CHECK: %[[SLOT0:.*]] = load ptr, ptr -// CHECK: %[[SIGN_VTADDR0:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 56) ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 2) to i64), i32 2, i64 0) +// CHECK: %[[SIGN_VTADDR0:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 56) ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 0, i32 2) to i64)) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T1:[0-9]+]] = inttoptr i64 %[[SIGN_VTADDR0]] to ptr // CHECK: store ptr %[[T1]], ptr %[[SLOT0]] // CHECK: %[[T3:[a-z0-9.]+]] = getelementptr inbounds i8, ptr %[[SLOT0]], i64 16 -// CHECK: %[[SIGN_VTADDR1:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 48) ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 2) to i64), i32 2, i64 0) +// CHECK: %[[SIGN_VTADDR1:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr getelementptr inbounds inrange(-16, 48) ({ [9 x ptr], [8 x ptr] }, ptr @_ZTV2D2, i32 0, i32 1, i32 2) to i64)) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T5:[0-9]+]] = inttoptr i64 %[[SIGN_VTADDR1]] to ptr // CHECK: store ptr %[[T5]], ptr %[[T3]] @@ -566,25 +547,25 @@ void materializeConstructors() { // CHECK: %[[VTT:[a-z0-9]+]] = load ptr, ptr %{{.*}} // CHECK: %[[T0:[0-9]+]] = load ptr, ptr %[[VTT]] // CHECK: %[[T1:[0-9]+]] = ptrtoint ptr %[[T0]] to i64 -// CHECK: %[[T2:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T1]], i32 2, i64 0) +// CHECK: %[[T2:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T1]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T3:[0-9]+]] = inttoptr i64 %[[T2]] to ptr // CHECK: %[[VTADDR0:[0-9]+]] = ptrtoint ptr %[[T3]] to i64 -// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 %[[VTADDR0]], i32 2, i64 0) +// CHECK: %[[T7:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 %[[VTADDR0]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[SIGN_VTADDR0:[0-9]+]] = inttoptr i64 %[[T7]] to ptr // CHECK: store ptr %[[SIGN_VTADDR0]], ptr %[[SLOT0]] // CHECK: %[[T9:[0-9]+]] = getelementptr inbounds ptr, ptr %[[VTT]], i64 1 // CHECK: %[[T10:[0-9]+]] = load ptr, ptr %[[T9]] // CHECK: %[[T11:[0-9]+]] = ptrtoint ptr %[[T10]] to i64 -// CHECK: %[[T12:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T11]], i32 2, i64 0) +// CHECK: %[[T12:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T11]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T13:[0-9]+]] = inttoptr i64 %[[T12]] to ptr // CHECK: %[[VTABLE:[a-z]+]] = load ptr, ptr %[[THIS1]] // CHECK: %[[T15:[0-9]+]] = ptrtoint ptr %[[VTABLE]] to i64 -// CHECK: %[[T16:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T15]], i32 2, i64 0) +// CHECK: %[[T16:[0-9]+]] = call i64 @llvm.ptrauth.auth(i64 %[[T15]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[T17:[0-9]+]] = inttoptr i64 %[[T16]] to ptr // CHECK: %[[VBASE_OFFSET_PTR:[a-z.]+]] = getelementptr i8, ptr %[[T17]], i64 -24 // CHECK: %[[VBASE_OFFSET:[a-z.]+]] = load i64, ptr %[[VBASE_OFFSET_PTR]] // CHECK: %[[T20:[a-z.]+]] = getelementptr inbounds i8, ptr %[[THIS1]], i64 %[[VBASE_OFFSET]] // CHECK: %[[VTADDR1:[0-9]+]] = ptrtoint ptr %[[T13]] to i64 -// CHECK: %[[T23:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 %[[VTADDR1]], i32 2, i64 0) +// CHECK: %[[T23:[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 %[[VTADDR1]]) [ "ptrauth"(i64 2, i64 0, i64 0) ] // CHECK: %[[SIGN_VTADDR1:[0-9]+]] = inttoptr i64 %[[T23]] to ptr // CHECK: store ptr %[[SIGN_VTADDR1]], ptr %[[T20]] diff --git a/clang/test/CodeGenCXX/ptrauth-vtable-virtual-inheritance-thunk.cpp b/clang/test/CodeGenCXX/ptrauth-vtable-virtual-inheritance-thunk.cpp index b5c15a29eb6b9..b348ffd6a50ab 100644 --- a/clang/test/CodeGenCXX/ptrauth-vtable-virtual-inheritance-thunk.cpp +++ b/clang/test/CodeGenCXX/ptrauth-vtable-virtual-inheritance-thunk.cpp @@ -6,184 +6,184 @@ // The actual vtable construction // CHECK: @_ZTV1C = unnamed_addr constant { [5 x ptr], [11 x ptr] } { [5 x ptr] [ptr inttoptr (i64 8 to ptr), ptr null, ptr @_ZTI1C, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1CD1Ev, i32 0, i64 31214, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTV1C, i32 0, i32 0, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1CD0Ev, i32 0, i64 8507, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTV1C, i32 0, i32 0, i32 4))], +// CHECK-SAME: ptr ptrauth (ptr @_ZN1CD1Ev, [i64 0, i64 31214, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTV1C, i32 0, i32 0, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1CD0Ev, [i64 0, i64 8507, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTV1C, i32 0, i32 0, i32 4) to i64)])], // CHECK-SAME: [11 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr null, ptr null, ptr null, ptr inttoptr (i64 -8 to ptr), ptr @_ZTI1C, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, i32 0, i64 55636, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTV1C, i32 0, i32 1, i32 6)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1gEv, i32 0, i64 19402, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTV1C, i32 0, i32 1, i32 7)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1hEz, i32 0, i64 31735, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTV1C, i32 0, i32 1, i32 8)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1CD1Ev, i32 0, i64 2043, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTV1C, i32 0, i32 1, i32 9)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1CD0Ev, i32 0, i64 63674, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTV1C, i32 0, i32 1, i32 10))] }, align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, [i64 0, i64 55636, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTV1C, i32 0, i32 1, i32 6) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1gEv, [i64 0, i64 19402, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTV1C, i32 0, i32 1, i32 7) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1hEz, [i64 0, i64 31735, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTV1C, i32 0, i32 1, i32 8) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1CD1Ev, [i64 0, i64 2043, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTV1C, i32 0, i32 1, i32 9) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1CD0Ev, [i64 0, i64 63674, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTV1C, i32 0, i32 1, i32 10) to i64)])] }, align 8 -// CHECK: @_ZTT1C = unnamed_addr constant [2 x ptr] [ptr ptrauth (ptr getelementptr inbounds inrange(-24, 16) ({ [5 x ptr], [11 x ptr] }, ptr @_ZTV1C, i32 0, i32 0, i32 3), i32 2), -// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [5 x ptr], [11 x ptr] }, ptr @_ZTV1C, i32 0, i32 1, i32 6), i32 2)], align 8 +// CHECK: @_ZTT1C = unnamed_addr constant [2 x ptr] [ptr ptrauth (ptr getelementptr inbounds inrange(-24, 16) ({ [5 x ptr], [11 x ptr] }, ptr @_ZTV1C, i32 0, i32 0, i32 3), [i64 2, i64 0, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [5 x ptr], [11 x ptr] }, ptr @_ZTV1C, i32 0, i32 1, i32 6), [i64 2, i64 0, i64 0])], align 8 // CHECK: @_ZTV1D = unnamed_addr constant { [7 x ptr], [11 x ptr] } { [7 x ptr] [ptr inttoptr (i64 8 to ptr), ptr null, ptr @_ZTI1D, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1DD1Ev, i32 0, i64 59423, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1DD0Ev, i32 0, i64 25900, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1gEv, i32 0, i64 59070, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 5)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1hEz, i32 0, i64 65100, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 6))], +// CHECK-SAME: ptr ptrauth (ptr @_ZN1DD1Ev, [i64 0, i64 59423, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1DD0Ev, [i64 0, i64 25900, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1gEv, [i64 0, i64 59070, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 5) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1hEz, [i64 0, i64 65100, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 6) to i64)])], // CHECK-SAME: [11 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr inttoptr (i64 -8 to ptr), ptr inttoptr (i64 -8 to ptr), ptr null, ptr inttoptr (i64 -8 to ptr), ptr @_ZTI1D, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, i32 0, i64 55636, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 1, i32 6)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n32_N1D1gEv, i32 0, i64 19402, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 1, i32 7)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n40_N1D1hEz, i32 0, i64 31735, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 1, i32 8)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1DD1Ev, i32 0, i64 2043, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 1, i32 9)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1DD0Ev, i32 0, i64 63674, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 1, i32 10))] }, align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, [i64 0, i64 55636, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 1, i32 6) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n32_N1D1gEv, [i64 0, i64 19402, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 1, i32 7) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n40_N1D1hEz, [i64 0, i64 31735, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 1, i32 8) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1DD1Ev, [i64 0, i64 2043, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 1, i32 9) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1DD0Ev, [i64 0, i64 63674, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 1, i32 10) to i64)])] }, align 8 -// CHECK: @_ZTT1D = unnamed_addr constant [2 x ptr] [ptr ptrauth (ptr getelementptr inbounds inrange(-24, 32) ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 3), i32 2), -// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 1, i32 6), i32 2)], align 8 +// CHECK: @_ZTT1D = unnamed_addr constant [2 x ptr] [ptr ptrauth (ptr getelementptr inbounds inrange(-24, 32) ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 0, i32 3), [i64 2, i64 0, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [7 x ptr], [11 x ptr] }, ptr @_ZTV1D, i32 0, i32 1, i32 6), [i64 2, i64 0, i64 0])], align 8 // CHECK: @_ZTV1F = unnamed_addr constant { [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] } { [6 x ptr] [ptr inttoptr (i64 32 to ptr), ptr inttoptr (i64 16 to ptr), ptr null, ptr @_ZTI1F, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1FD1Ev, i32 0, i64 31214, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 0, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1FD0Ev, i32 0, i64 8507, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 0, i32 5))], [7 x ptr] [ptr inttoptr (i64 8 to ptr), ptr inttoptr (i64 -8 to ptr), ptr @_ZTI1F, -// CHECK-SAME: ptr ptrauth (ptr @_ZThn8_N1FD1Ev, i32 0, i64 59423, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 1, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZThn8_N1FD0Ev, i32 0, i64 25900, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 1, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1gEv, i32 0, i64 59070, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 1, i32 5)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1hEz, i32 0, i64 65100, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 1, i32 6))], [11 x ptr] [ptr inttoptr (i64 -16 to ptr), ptr inttoptr (i64 -8 to ptr), ptr inttoptr (i64 -8 to ptr), ptr null, ptr inttoptr (i64 -16 to ptr), ptr @_ZTI1F, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, i32 0, i64 55636, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 2, i32 6)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n32_N1D1gEv, i32 0, i64 19402, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 2, i32 7)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n40_N1D1hEz, i32 0, i64 31735, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 2, i32 8)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1FD1EvU11__vtptrauthILj0Lb0Lj62866E, i32 0, i64 2043, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 2, i32 9)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1FD0EvU11__vtptrauthILj0Lb0Lj62866E, i32 0, i64 63674, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 2, i32 10))], [11 x ptr] [ptr inttoptr (i64 -32 to ptr), ptr null, ptr null, ptr null, ptr inttoptr (i64 -32 to ptr), ptr @_ZTI1F, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1fEv, i32 0, i64 28408, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 3, i32 6)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1gEv, i32 0, i64 22926, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 3, i32 7)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1hEz, i32 0, i64 9832, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 3, i32 8)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1FD1Ev, i32 0, i64 5817, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 3, i32 9)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1FD0Ev, i32 0, i64 26464, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 3, i32 10))] }, align 8 - -// CHECK: @_ZTT1F = unnamed_addr constant [8 x ptr] [ptr ptrauth (ptr getelementptr inbounds inrange(-32, 16) ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 0, i32 4), i32 2), -// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-24, 16) ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 0, i32 3), i32 2), -// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 1, i32 6), i32 2), -// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-24, 32) ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 0, i32 3), i32 2), -// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 1, i32 6), i32 2), -// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 2, i32 6), i32 2), -// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-24, 32) ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 1, i32 3), i32 2), -// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 3, i32 6), i32 2)], align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZN1FD1Ev, [i64 0, i64 31214, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 0, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1FD0Ev, [i64 0, i64 8507, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 0, i32 5) to i64)])], [7 x ptr] [ptr inttoptr (i64 8 to ptr), ptr inttoptr (i64 -8 to ptr), ptr @_ZTI1F, +// CHECK-SAME: ptr ptrauth (ptr @_ZThn8_N1FD1Ev, [i64 0, i64 59423, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 1, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZThn8_N1FD0Ev, [i64 0, i64 25900, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 1, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1gEv, [i64 0, i64 59070, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 1, i32 5) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1hEz, [i64 0, i64 65100, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 1, i32 6) to i64)])], [11 x ptr] [ptr inttoptr (i64 -16 to ptr), ptr inttoptr (i64 -8 to ptr), ptr inttoptr (i64 -8 to ptr), ptr null, ptr inttoptr (i64 -16 to ptr), ptr @_ZTI1F, +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, [i64 0, i64 55636, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 2, i32 6) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n32_N1D1gEv, [i64 0, i64 19402, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 2, i32 7) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n40_N1D1hEz, [i64 0, i64 31735, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 2, i32 8) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1FD1EvU11__vtptrauthILj0Lb0Lj62866E, [i64 0, i64 2043, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 2, i32 9) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1FD0EvU11__vtptrauthILj0Lb0Lj62866E, [i64 0, i64 63674, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 2, i32 10) to i64)])], [11 x ptr] [ptr inttoptr (i64 -32 to ptr), ptr null, ptr null, ptr null, ptr inttoptr (i64 -32 to ptr), ptr @_ZTI1F, +// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1fEv, [i64 0, i64 28408, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 3, i32 6) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1gEv, [i64 0, i64 22926, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 3, i32 7) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1hEz, [i64 0, i64 9832, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 3, i32 8) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1FD1Ev, [i64 0, i64 5817, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 3, i32 9) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1FD0Ev, [i64 0, i64 26464, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 3, i32 10) to i64)])] }, align 8 + +// CHECK: @_ZTT1F = unnamed_addr constant [8 x ptr] [ptr ptrauth (ptr getelementptr inbounds inrange(-32, 16) ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 0, i32 4), [i64 2, i64 0, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-24, 16) ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 0, i32 3), [i64 2, i64 0, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 1, i32 6), [i64 2, i64 0, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-24, 32) ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 0, i32 3), [i64 2, i64 0, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 1, i32 6), [i64 2, i64 0, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 2, i32 6), [i64 2, i64 0, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-24, 32) ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 1, i32 3), [i64 2, i64 0, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1F, i32 0, i32 3, i32 6), [i64 2, i64 0, i64 0])], align 8 // CHECK: @_ZTV1G = unnamed_addr constant { [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] } { [6 x ptr] [ptr inttoptr (i64 16 to ptr), ptr inttoptr (i64 24 to ptr), ptr null, ptr @_ZTI1G, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1GD1Ev, i32 0, i64 31214, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 0, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1GD0Ev, i32 0, i64 8507, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 0, i32 5))], [7 x ptr] [ptr inttoptr (i64 16 to ptr), ptr inttoptr (i64 -8 to ptr), ptr @_ZTI1G, -// CHECK-SAME: ptr ptrauth (ptr @_ZThn8_N1GD1Ev, i32 0, i64 59423, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 1, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZThn8_N1GD0Ev, i32 0, i64 25900, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 1, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1gEv, i32 0, i64 59070, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 1, i32 5)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1hEz, i32 0, i64 65100, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 1, i32 6))], [11 x ptr] [ptr inttoptr (i64 -16 to ptr), ptr null, ptr null, ptr null, ptr inttoptr (i64 -16 to ptr), ptr @_ZTI1G, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1fEv, i32 0, i64 28408, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 2, i32 6)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1gEv, i32 0, i64 22926, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 2, i32 7)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1hEz, i32 0, i64 9832, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 2, i32 8)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1GD1Ev, i32 0, i64 5817, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 2, i32 9)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1GD0Ev, i32 0, i64 26464, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 2, i32 10))], [11 x ptr] [ptr inttoptr (i64 -24 to ptr), ptr inttoptr (i64 -16 to ptr), ptr inttoptr (i64 -16 to ptr), ptr null, ptr inttoptr (i64 -24 to ptr), ptr @_ZTI1G, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, i32 0, i64 55636, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 3, i32 6)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n32_N1D1gEv, i32 0, i64 19402, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 3, i32 7)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n40_N1D1hEz, i32 0, i64 31735, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 3, i32 8)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1GD1EvU11__vtptrauthILj0Lb0Lj62866E, i32 0, i64 2043, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 3, i32 9)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1GD0EvU11__vtptrauthILj0Lb0Lj62866E, i32 0, i64 63674, ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 3, i32 10))] }, align 8 - -// CHECK: @_ZTT1G = unnamed_addr constant [8 x ptr] [ptr ptrauth (ptr getelementptr inbounds inrange(-32, 16) ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 0, i32 4), i32 2), -// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-24, 16) ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 0, i32 3), i32 2), -// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 1, i32 6), i32 2), -// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-24, 32) ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 0, i32 3), i32 2), -// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 1, i32 6), i32 2), -// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 2, i32 6), i32 2), -// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 3, i32 6), i32 2), -// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-24, 32) ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 1, i32 3), i32 2)], align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZN1GD1Ev, [i64 0, i64 31214, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 0, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1GD0Ev, [i64 0, i64 8507, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 0, i32 5) to i64)])], [7 x ptr] [ptr inttoptr (i64 16 to ptr), ptr inttoptr (i64 -8 to ptr), ptr @_ZTI1G, +// CHECK-SAME: ptr ptrauth (ptr @_ZThn8_N1GD1Ev, [i64 0, i64 59423, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 1, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZThn8_N1GD0Ev, [i64 0, i64 25900, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 1, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1gEv, [i64 0, i64 59070, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 1, i32 5) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1hEz, [i64 0, i64 65100, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 1, i32 6) to i64)])], [11 x ptr] [ptr inttoptr (i64 -16 to ptr), ptr null, ptr null, ptr null, ptr inttoptr (i64 -16 to ptr), ptr @_ZTI1G, +// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1fEv, [i64 0, i64 28408, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 2, i32 6) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1gEv, [i64 0, i64 22926, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 2, i32 7) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1hEz, [i64 0, i64 9832, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 2, i32 8) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1GD1Ev, [i64 0, i64 5817, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 2, i32 9) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1GD0Ev, [i64 0, i64 26464, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 2, i32 10) to i64)])], [11 x ptr] [ptr inttoptr (i64 -24 to ptr), ptr inttoptr (i64 -16 to ptr), ptr inttoptr (i64 -16 to ptr), ptr null, ptr inttoptr (i64 -24 to ptr), ptr @_ZTI1G, +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, [i64 0, i64 55636, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 3, i32 6) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n32_N1D1gEv, [i64 0, i64 19402, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 3, i32 7) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n40_N1D1hEz, [i64 0, i64 31735, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 3, i32 8) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1GD1EvU11__vtptrauthILj0Lb0Lj62866E, [i64 0, i64 2043, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 3, i32 9) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1GD0EvU11__vtptrauthILj0Lb0Lj62866E, [i64 0, i64 63674, i64 ptrtoint (ptr getelementptr inbounds ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 3, i32 10) to i64)])] }, align 8 + +// CHECK: @_ZTT1G = unnamed_addr constant [8 x ptr] [ptr ptrauth (ptr getelementptr inbounds inrange(-32, 16) ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 0, i32 4), [i64 2, i64 0, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-24, 16) ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 0, i32 3), [i64 2, i64 0, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 1, i32 6), [i64 2, i64 0, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-24, 32) ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 0, i32 3), [i64 2, i64 0, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 1, i32 6), [i64 2, i64 0, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 2, i32 6), [i64 2, i64 0, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-48, 40) ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 3, i32 6), [i64 2, i64 0, i64 0]), +// CHECK-SAME: ptr ptrauth (ptr getelementptr inbounds inrange(-24, 32) ({ [6 x ptr], [7 x ptr], [11 x ptr], [11 x ptr] }, ptr @_ZTV1G, i32 0, i32 1, i32 3), [i64 2, i64 0, i64 0])], align 8 // CHECK: @_ZTV1A = unnamed_addr constant { [7 x ptr] } { [7 x ptr] [ptr null, ptr @_ZTI1A, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, i32 0, i64 55636, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 2)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1gEv, i32 0, i64 19402, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1hEz, i32 0, i64 31735, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1AD1Ev, i32 0, i64 2043, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 5)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1AD0Ev, i32 0, i64 63674, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 6))] }, align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, [i64 0, i64 55636, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 2) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1gEv, [i64 0, i64 19402, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1hEz, [i64 0, i64 31735, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1AD1Ev, [i64 0, i64 2043, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 5) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1AD0Ev, [i64 0, i64 63674, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 6) to i64)])] }, align 8 -// CHECK: @_ZTI1A = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr @_ZTS1A }, align 8 +// CHECK: @_ZTI1A = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), [i64 2, i64 0, i64 0]), ptr @_ZTS1A }, align 8 // CHECK: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr] // CHECK: @_ZTS1A = constant [3 x i8] c"1A\00", align 1 -// CHECK: @_ZTI1C = constant { ptr, ptr, i32, i32, ptr, i64 } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2), i32 2), ptr @_ZTS1C, i32 0, i32 1, ptr @_ZTI1B, i64 -6141 }, align 8 +// CHECK: @_ZTI1C = constant { ptr, ptr, i32, i32, ptr, i64 } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2), [i64 2, i64 0, i64 0]), ptr @_ZTS1C, i32 0, i32 1, ptr @_ZTI1B, i64 -6141 }, align 8 // CHECK: @_ZTVN10__cxxabiv121__vmi_class_type_infoE = external global [0 x ptr] // CHECK: @_ZTS1C = constant [3 x i8] c"1C\00", align 1 -// DARWIN: @_ZTI1B = linkonce_odr hidden constant { ptr, ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), i32 2), ptr inttoptr (i64 add (i64 ptrtoint (ptr @_ZTS1B to i64), i64 -9223372036854775808) to ptr), ptr @_ZTI1A }, align 8 -// ELF: @_ZTI1B = linkonce_odr constant { ptr, ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), i32 2), ptr @_ZTS1B, ptr @_ZTI1A }, comdat, align 8 +// DARWIN: @_ZTI1B = linkonce_odr hidden constant { ptr, ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), [i64 2, i64 0, i64 0]), ptr inttoptr (i64 add (i64 ptrtoint (ptr @_ZTS1B to i64), i64 -9223372036854775808) to ptr), ptr @_ZTI1A }, align 8 +// ELF: @_ZTI1B = linkonce_odr constant { ptr, ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), [i64 2, i64 0, i64 0]), ptr @_ZTS1B, ptr @_ZTI1A }, comdat, align 8 // CHECK: @_ZTVN10__cxxabiv120__si_class_type_infoE = external global [0 x ptr] // DARWIN: @_ZTS1B = linkonce_odr hidden constant [3 x i8] c"1B\00", align 1 // ELF: @_ZTS1B = linkonce_odr constant [3 x i8] c"1B\00", comdat, align 1 -// CHECK: @_ZTI1D = constant { ptr, ptr, i32, i32, ptr, i64 } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2), i32 2), ptr @_ZTS1D, i32 0, i32 1, ptr @_ZTI1B, i64 -6141 }, align 8 +// CHECK: @_ZTI1D = constant { ptr, ptr, i32, i32, ptr, i64 } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2), [i64 2, i64 0, i64 0]), ptr @_ZTS1D, i32 0, i32 1, ptr @_ZTI1B, i64 -6141 }, align 8 // CHECK: @_ZTS1D = constant [3 x i8] c"1D\00", align 1 // CHECK: @_ZTV1E = unnamed_addr constant { [7 x ptr] } { [7 x ptr] [ptr null, ptr @_ZTI1E, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1fEv, i32 0, i64 28408, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1E, i32 0, i32 0, i32 2)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1gEv, i32 0, i64 22926, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1E, i32 0, i32 0, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1hEz, i32 0, i64 9832, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1E, i32 0, i32 0, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1ED1Ev, i32 0, i64 5817, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1E, i32 0, i32 0, i32 5)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1ED0Ev, i32 0, i64 26464, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1E, i32 0, i32 0, i32 6))] }, align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1fEv, [i64 0, i64 28408, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1E, i32 0, i32 0, i32 2) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1gEv, [i64 0, i64 22926, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1E, i32 0, i32 0, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1hEz, [i64 0, i64 9832, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1E, i32 0, i32 0, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1ED1Ev, [i64 0, i64 5817, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1E, i32 0, i32 0, i32 5) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1ED0Ev, [i64 0, i64 26464, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1E, i32 0, i32 0, i32 6) to i64)])] }, align 8 -// CHECK: @_ZTI1E = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr @_ZTS1E }, align 8 +// CHECK: @_ZTI1E = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), [i64 2, i64 0, i64 0]), ptr @_ZTS1E }, align 8 // CHECK: @_ZTS1E = constant [3 x i8] c"1E\00", align 1 // CHECK: @_ZTC1F0_1C = unnamed_addr constant { [5 x ptr], [11 x ptr] } { [5 x ptr] [ptr inttoptr (i64 16 to ptr), ptr null, ptr @_ZTI1C, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1CD1Ev, i32 0, i64 31214, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 0, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1CD0Ev, i32 0, i64 8507, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 0, i32 4))], [11 x ptr] [ptr inttoptr (i64 -16 to ptr), ptr null, ptr null, ptr null, ptr inttoptr (i64 -16 to ptr), ptr @_ZTI1C, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, i32 0, i64 55636, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 1, i32 6)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1gEv, i32 0, i64 19402, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 1, i32 7)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1hEz, i32 0, i64 31735, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 1, i32 8)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1CD1Ev, i32 0, i64 2043, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 1, i32 9)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1CD0Ev, i32 0, i64 63674, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 1, i32 10))] }, align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZN1CD1Ev, [i64 0, i64 31214, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 0, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1CD0Ev, [i64 0, i64 8507, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 0, i32 4) to i64)])], [11 x ptr] [ptr inttoptr (i64 -16 to ptr), ptr null, ptr null, ptr null, ptr inttoptr (i64 -16 to ptr), ptr @_ZTI1C, +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, [i64 0, i64 55636, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 1, i32 6) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1gEv, [i64 0, i64 19402, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 1, i32 7) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1hEz, [i64 0, i64 31735, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 1, i32 8) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1CD1Ev, [i64 0, i64 2043, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 1, i32 9) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1CD0Ev, [i64 0, i64 63674, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 1, i32 10) to i64)])] }, align 8 // CHECK: @_ZTC1F8_1D = unnamed_addr constant { [7 x ptr], [11 x ptr] } { [7 x ptr] [ptr inttoptr (i64 8 to ptr), ptr null, ptr @_ZTI1D, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1DD1Ev, i32 0, i64 59423, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 0, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1DD0Ev, i32 0, i64 25900, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 0, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1gEv, i32 0, i64 59070, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 0, i32 5)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1hEz, i32 0, i64 65100, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 0, i32 6))], [11 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr inttoptr (i64 -8 to ptr), ptr inttoptr (i64 -8 to ptr), ptr null, ptr inttoptr (i64 -8 to ptr), ptr @_ZTI1D, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, i32 0, i64 55636, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 1, i32 6)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n32_N1D1gEv, i32 0, i64 19402, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 1, i32 7)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n40_N1D1hEz, i32 0, i64 31735, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 1, i32 8)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1DD1Ev, i32 0, i64 2043, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 1, i32 9)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1DD0Ev, i32 0, i64 63674, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 1, i32 10))] }, align 8 - -// CHECK: @_ZTI1F = constant { ptr, ptr, i32, i32, ptr, i64, ptr, i64, ptr, i64 } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2), i32 2), ptr @_ZTS1F, i32 3, i32 3, ptr @_ZTI1C, i64 2, ptr @_ZTI1D, i64 2050, ptr @_ZTI1E, i64 -8189 }, align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZN1DD1Ev, [i64 0, i64 59423, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 0, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1DD0Ev, [i64 0, i64 25900, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 0, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1gEv, [i64 0, i64 59070, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 0, i32 5) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1hEz, [i64 0, i64 65100, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 0, i32 6) to i64)])], [11 x ptr] [ptr inttoptr (i64 -8 to ptr), ptr inttoptr (i64 -8 to ptr), ptr inttoptr (i64 -8 to ptr), ptr null, ptr inttoptr (i64 -8 to ptr), ptr @_ZTI1D, +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, [i64 0, i64 55636, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 1, i32 6) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n32_N1D1gEv, [i64 0, i64 19402, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 1, i32 7) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n40_N1D1hEz, [i64 0, i64 31735, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 1, i32 8) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1DD1Ev, [i64 0, i64 2043, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 1, i32 9) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1DD0Ev, [i64 0, i64 63674, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 1, i32 10) to i64)])] }, align 8 + +// CHECK: @_ZTI1F = constant { ptr, ptr, i32, i32, ptr, i64, ptr, i64, ptr, i64 } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2), [i64 2, i64 0, i64 0]), ptr @_ZTS1F, i32 3, i32 3, ptr @_ZTI1C, i64 2, ptr @_ZTI1D, i64 2050, ptr @_ZTI1E, i64 -8189 }, align 8 // CHECK: @_ZTS1F = constant [3 x i8] c"1F\00", align 1 // CHECK: @_ZTC1G0_1C = unnamed_addr constant { [5 x ptr], [11 x ptr] } { [5 x ptr] [ptr inttoptr (i64 24 to ptr), ptr null, ptr @_ZTI1C, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1CD1Ev, i32 0, i64 31214, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 0, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1CD0Ev, i32 0, i64 8507, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 0, i32 4))], [11 x ptr] [ptr inttoptr (i64 -24 to ptr), ptr null, ptr null, ptr null, ptr inttoptr (i64 -24 to ptr), ptr @_ZTI1C, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, i32 0, i64 55636, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 1, i32 6)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1gEv, i32 0, i64 19402, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 1, i32 7)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1hEz, i32 0, i64 31735, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 1, i32 8)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1CD1Ev, i32 0, i64 2043, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 1, i32 9)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1CD0Ev, i32 0, i64 63674, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 1, i32 10))] }, align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZN1CD1Ev, [i64 0, i64 31214, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 0, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1CD0Ev, [i64 0, i64 8507, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 0, i32 4) to i64)])], [11 x ptr] [ptr inttoptr (i64 -24 to ptr), ptr null, ptr null, ptr null, ptr inttoptr (i64 -24 to ptr), ptr @_ZTI1C, +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, [i64 0, i64 55636, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 1, i32 6) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1gEv, [i64 0, i64 19402, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 1, i32 7) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1hEz, [i64 0, i64 31735, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 1, i32 8) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1CD1Ev, [i64 0, i64 2043, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 1, i32 9) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1CD0Ev, [i64 0, i64 63674, i64 ptrtoint (ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 1, i32 10) to i64)])] }, align 8 // CHECK: @_ZTC1G8_1D = unnamed_addr constant { [7 x ptr], [11 x ptr] } { [7 x ptr] [ptr inttoptr (i64 16 to ptr), ptr null, ptr @_ZTI1D, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1DD1Ev, i32 0, i64 59423, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 0, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1DD0Ev, i32 0, i64 25900, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 0, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1gEv, i32 0, i64 59070, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 0, i32 5)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1hEz, i32 0, i64 65100, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 0, i32 6))], [11 x ptr] [ptr inttoptr (i64 -16 to ptr), ptr inttoptr (i64 -16 to ptr), ptr inttoptr (i64 -16 to ptr), ptr null, ptr inttoptr (i64 -16 to ptr), ptr @_ZTI1D, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, i32 0, i64 55636, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 1, i32 6)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n32_N1D1gEv, i32 0, i64 19402, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 1, i32 7)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n40_N1D1hEz, i32 0, i64 31735, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 1, i32 8)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1DD1Ev, i32 0, i64 2043, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 1, i32 9)), -// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1DD0Ev, i32 0, i64 63674, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 1, i32 10))] }, align 8 - -// CHECK: @_ZTI1G = constant { ptr, ptr, i32, i32, ptr, i64, ptr, i64, ptr, i64 } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2), i32 2), ptr @_ZTS1G, i32 3, i32 3, ptr @_ZTI1E, i64 -8189, ptr @_ZTI1C, i64 2, ptr @_ZTI1D, i64 2050 }, align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZN1DD1Ev, [i64 0, i64 59423, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 0, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1DD0Ev, [i64 0, i64 25900, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 0, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1gEv, [i64 0, i64 59070, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 0, i32 5) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1D1hEz, [i64 0, i64 65100, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 0, i32 6) to i64)])], [11 x ptr] [ptr inttoptr (i64 -16 to ptr), ptr inttoptr (i64 -16 to ptr), ptr inttoptr (i64 -16 to ptr), ptr null, ptr inttoptr (i64 -16 to ptr), ptr @_ZTI1D, +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, [i64 0, i64 55636, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 1, i32 6) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n32_N1D1gEv, [i64 0, i64 19402, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 1, i32 7) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n40_N1D1hEz, [i64 0, i64 31735, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 1, i32 8) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1DD1Ev, [i64 0, i64 2043, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 1, i32 9) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1DD0Ev, [i64 0, i64 63674, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 1, i32 10) to i64)])] }, align 8 + +// CHECK: @_ZTI1G = constant { ptr, ptr, i32, i32, ptr, i64, ptr, i64, ptr, i64 } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2), [i64 2, i64 0, i64 0]), ptr @_ZTS1G, i32 3, i32 3, ptr @_ZTI1E, i64 -8189, ptr @_ZTI1C, i64 2, ptr @_ZTI1D, i64 2050 }, align 8 // CHECK: @_ZTS1G = constant [3 x i8] c"1G\00", align 1 // CHECK: @_ZTV1B = linkonce_odr unnamed_addr constant { [7 x ptr] } { [7 x ptr] [ptr null, ptr @_ZTI1B, -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, i32 0, i64 55636, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 2)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1gEv, i32 0, i64 19402, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 3)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1hEz, i32 0, i64 31735, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 4)), -// CHECK-SAME: ptr ptrauth (ptr @_ZN1BD1Ev, i32 0, i64 2043, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 5)), -// DARWIN-SAME: ptr ptrauth (ptr @_ZN1BD0Ev, i32 0, i64 63674, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 6))] }, align 8 -// ELF-SAME: ptr ptrauth (ptr @_ZN1BD0Ev, i32 0, i64 63674, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 6))] }, comdat, align 8 +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, [i64 0, i64 55636, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 2) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1gEv, [i64 0, i64 19402, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 3) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1hEz, [i64 0, i64 31735, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 4) to i64)]), +// CHECK-SAME: ptr ptrauth (ptr @_ZN1BD1Ev, [i64 0, i64 2043, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 5) to i64)]), +// DARWIN-SAME: ptr ptrauth (ptr @_ZN1BD0Ev, [i64 0, i64 63674, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 6) to i64)])] }, align 8 +// ELF-SAME: ptr ptrauth (ptr @_ZN1BD0Ev, [i64 0, i64 63674, i64 ptrtoint (ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 6) to i64)])] }, comdat, align 8 extern "C" int printf(const char *format, ...); @@ -292,26 +292,26 @@ int main() { // And check the thunks // DARWIN: ptr @_ZTv0_n48_N1CD1Ev(ptr noundef %this) // ELF: void @_ZTv0_n48_N1CD1Ev(ptr noundef %this) -// CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]], i32 2, i64 62866) +// CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]]) [ "ptrauth"(i64 2, i64 62866, i64 0) ] // CHECK: void @_ZTv0_n48_N1CD0Ev(ptr noundef %this) -// CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]], i32 2, i64 62866) +// CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]]) [ "ptrauth"(i64 2, i64 62866, i64 0) ] // DARWIN: ptr @_ZTv0_n48_N1DD1Ev(ptr noundef %this) // ELF: void @_ZTv0_n48_N1DD1Ev(ptr noundef %this) -// CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]], i32 2, i64 62866) +// CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]]) [ "ptrauth"(i64 2, i64 62866, i64 0) ] // CHECK: void @_ZTv0_n48_N1DD0Ev(ptr noundef %this) -// CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]], i32 2, i64 62866) +// CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]]) [ "ptrauth"(i64 2, i64 62866, i64 0) ] // CHECK: void @_ZTv0_n48_N1FD0EvU11__vtptrauthILj0Lb0Lj62866E(ptr noundef %this) -// CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]], i32 2, i64 62866) +// CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]]) [ "ptrauth"(i64 2, i64 62866, i64 0) ] // CHECK: void @_ZTv0_n48_N1FD0Ev(ptr noundef %this) -// CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]], i32 2, i64 12810) +// CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]]) [ "ptrauth"(i64 2, i64 12810, i64 0) ] // CHECK: void @_ZTv0_n48_N1GD0Ev(ptr noundef %this) -// CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]], i32 2, i64 12810) +// CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]]) [ "ptrauth"(i64 2, i64 12810, i64 0) ] // CHECK: void @_ZTv0_n48_N1GD0EvU11__vtptrauthILj0Lb0Lj62866E(ptr noundef %this) -// CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]], i32 2, i64 62866) +// CHECK: [[TEMP:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TEMP:%.*]]) [ "ptrauth"(i64 2, i64 62866, i64 0) ] diff --git a/clang/test/CodeGenCXX/ptrauth.cpp b/clang/test/CodeGenCXX/ptrauth.cpp index b0c069f43969b..3e1507944b25e 100644 --- a/clang/test/CodeGenCXX/ptrauth.cpp +++ b/clang/test/CodeGenCXX/ptrauth.cpp @@ -5,7 +5,7 @@ void f(void); auto &f_ref = f; // CHECK: define {{(dso_local )?}}void @_Z1gv( -// CHECK: call void ptrauth (ptr @_Z1fv, i32 0)() [ "ptrauth"(i32 0, i64 0) ] +// CHECK: call void ptrauth (ptr @_Z1fv, [i64 0, i64 0, i64 0])() [ "ptrauth"(i64 0, i64 0, i64 0) ] void g() { f_ref(); } diff --git a/clang/test/CodeGenCXX/ubsan-vtable-checks.cpp b/clang/test/CodeGenCXX/ubsan-vtable-checks.cpp index c891ff0a4fa42..96f5392c7154c 100644 --- a/clang/test/CodeGenCXX/ubsan-vtable-checks.cpp +++ b/clang/test/CodeGenCXX/ubsan-vtable-checks.cpp @@ -31,16 +31,15 @@ int get_v(T* t) { // CHECK-NULL: load ptr, ptr {{.*}} // CHECK-PTRAUTH: [[CAST_VTABLE:%.*]] = ptrtoint ptr %vtable to i64 - // CHECK-PTRAUTH: [[STRIPPED_VTABLE:%.*]] = call i64 @llvm.ptrauth.strip(i64 [[CAST_VTABLE]], i32 0), !nosanitize + // CHECK-PTRAUTH: [[STRIPPED_VTABLE:%.*]] = call i64 @llvm.ptrauth.strip(i64 [[CAST_VTABLE]]) [ "ptrauth"(i64 0) ], !nosanitize // CHECK-PTRAUTH: [[STRIPPED_PTR:%.*]] = inttoptr i64 [[STRIPPED_VTABLE]] to ptr // CHECK-PTRAUTH: [[STRIPPED_INT:%.*]] = ptrtoint ptr [[STRIPPED_PTR]] to i64 // Make sure authed vtable pointer feeds into hashing // CHECK-PTRAUTH: {{%.*}} = mul i64 [[STRIPPED_INT]], {{.*}} // Verify that we authenticate for the actual vcall - // CHECK-PTRAUTH: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 17113) // CHECK-PTRAUTH: [[CAST_VTABLE:%.*]] = ptrtoint ptr %vtable2 to i64 - // CHECK-PTRAUTH: [[AUTHED_INT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[CAST_VTABLE]], i32 2, i64 [[BLENDED]]) + // CHECK-PTRAUTH: [[AUTHED_INT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[CAST_VTABLE]]) [ "ptrauth"(i64 2, i64 17113, i64 {{%.*}}) ] // CHECK-PTRAUTH: [[AUTHED_PTR:%.*]] = inttoptr i64 [[AUTHED_INT]] to ptr // CHECK-PTRAUTH: {{%.*}} = getelementptr inbounds ptr, ptr [[AUTHED_PTR]], i64 2 return t->v(); @@ -58,7 +57,7 @@ void delete_it(T *t) { // First, we check that vtable is not loaded before a type check. // CHECK-PTRAUTH: ptrtoint ptr {{%.*}} to i64 // CHECK-PTRAUTH: [[CAST_VTABLE:%.*]] = ptrtoint ptr [[VTABLE:%.*]] to i64 - // CHECK-PTRAUTH: [[STRIPPED_VTABLE:%.*]] = call i64 @llvm.ptrauth.strip(i64 [[CAST_VTABLE]], i32 0) + // CHECK-PTRAUTH: [[STRIPPED_VTABLE:%.*]] = call i64 @llvm.ptrauth.strip(i64 [[CAST_VTABLE]]) [ "ptrauth"(i64 0) ] // CHECK-PTRAUTH: [[STRIPPED_PTR:%.*]] = inttoptr i64 [[STRIPPED_VTABLE]] to ptr // CHECK-PTRAUTH: [[STRIPPED_INT:%.*]] = ptrtoint ptr [[STRIPPED_PTR]] to i64 // CHECK-PTRAUTH: {{%.*}} = mul i64 [[STRIPPED_INT]], {{.*}} @@ -66,9 +65,8 @@ void delete_it(T *t) { // Second, we check that vtable is actually loaded once the type check is done. // ptrauth for the virtual function load // CHECK-PTRAUTH: [[VTABLE2:%.*]] = load ptr, ptr {{.*}} - // CHECK-PTRAUTH: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 %{{.*}}, i64 17113) // CHECK-PTRAUTH: [[CAST_VTABLE:%.*]] = ptrtoint ptr [[VTABLE2]] to i64 - // CHECK-PTRAUTH: [[AUTHED_INT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[CAST_VTABLE]], i32 2, i64 [[BLENDED]]) + // CHECK-PTRAUTH: [[AUTHED_INT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[CAST_VTABLE]]) [ "ptrauth"(i64 2, i64 17113, i64 %{{.*}}) ] // CHECK-PTRAUTH: [[AUTHED_PTR:%.*]] = inttoptr i64 [[AUTHED_INT]] to ptr // CHECK-PTRAUTH: getelementptr inbounds ptr, ptr // CHECK-PTRAUTH {{%.*}} = getelementptr inbounds ptr, ptr [[AUTHED_PTR]], i64 1 @@ -82,16 +80,14 @@ U* dyncast(T *t) { // CHECK-VPTR-NOT: call ptr @__{{dynamic_cast|RTDynamicCast}} // CHECK-VPTR: br i1 {{.*}} label %{{.*}} // CHECK-PTRAUTH: [[V0:%.*]] = ptrtoint ptr {{%.*}} to i64 - // CHECK-PTRAUTH: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[V0]], i64 17113) // CHECK-PTRAUTH: [[CAST_VTABLE:%.*]] = ptrtoint ptr {{%.*}} to i64 - // CHECK-PTRAUTH: [[STRIPPED_VTABLE:%.*]] = call i64 @llvm.ptrauth.strip(i64 [[CAST_VTABLE]], i32 0) + // CHECK-PTRAUTH: [[STRIPPED_VTABLE:%.*]] = call i64 @llvm.ptrauth.strip(i64 [[CAST_VTABLE]]) [ "ptrauth"(i64 0) ] // CHECK-PTRAUTH: [[STRIPPED_PTR:%.*]] = inttoptr i64 [[STRIPPED_VTABLE]] to ptr // CHECK-PTRAUTH: [[STRIPPED_INT:%.*]] = ptrtoint ptr [[STRIPPED_PTR]] to i64 // CHECK-PTRAUTH: {{%.*}} = mul i64 [[STRIPPED_INT]], {{.*}} // CHECK-VPTR: call void @__ubsan_handle_dynamic_type_cache_miss_abort - // CHECK-PTRAUTH: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 17113) // CHECK-PTRAUTH: [[CAST_VTABLE:%.*]] = ptrtoint ptr %vtable1 to i64 - // CHECK-PTRAUTH: [[AUTHED_INT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[CAST_VTABLE]], i32 2, i64 [[BLENDED]]) + // CHECK-PTRAUTH: [[AUTHED_INT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[CAST_VTABLE]]) [ "ptrauth"(i64 2, i64 17113, i64 {{%.*}}) ] // CHECK-PTRAUTH: [[AUTHED_PTR:%.*]] = inttoptr i64 [[AUTHED_INT]] to ptr // CHECK-PTRAUTH: {{%.*}} = load volatile i8, ptr [[AUTHED_PTR]], align 8 // Second, we check that dynamic_cast is actually called once the type check is done. diff --git a/clang/test/CodeGenObjC/ptrauth-attr-exception.m b/clang/test/CodeGenObjC/ptrauth-attr-exception.m index 8c07a698ecc70..289d13ab2c0b1 100644 --- a/clang/test/CodeGenObjC/ptrauth-attr-exception.m +++ b/clang/test/CodeGenObjC/ptrauth-attr-exception.m @@ -13,5 +13,5 @@ @interface A : Root @implementation A @end -// CHECK: @"OBJC_EHTYPE_$_A" = global %struct._objc_typeinfo { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @objc_ehtype_vtable, i32 2), i32 2), ptr @OBJC_CLASS_NAME_, ptr @"OBJC_CLASS_$_A" } +// CHECK: @"OBJC_EHTYPE_$_A" = global %struct._objc_typeinfo { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @objc_ehtype_vtable, i32 2), [i64 2, i64 0, i64 0]), ptr @OBJC_CLASS_NAME_, ptr @"OBJC_CLASS_$_A" } //. @"OBJC_EHTYPE_$_A" = global %struct._objc_typeinfo { ptr getelementptr inbounds (ptr, ptr @objc_ehtype_vtable, i32 2), ptr @OBJC_CLASS_NAME_, ptr @"OBJC_CLASS_$_A" } diff --git a/clang/test/CodeGenObjC/ptrauth-block-descriptor-pointer.m b/clang/test/CodeGenObjC/ptrauth-block-descriptor-pointer.m index b51670fd6459a..58090ce19ffed 100644 --- a/clang/test/CodeGenObjC/ptrauth-block-descriptor-pointer.m +++ b/clang/test/CodeGenObjC/ptrauth-block-descriptor-pointer.m @@ -13,10 +13,10 @@ void a() { } // CHECK: [[BLOCK_DESCRIPTOR_NAME:@"__block_descriptor_.*"]] = linkonce_odr hidden unnamed_addr constant { i64, i64, ptr, ptr } { i64 0, i64 32, ptr @.str, ptr null } -// CHECK: @__block_literal_global = internal constant { ptr, i32, i32, ptr, ptr } { ptr @_NSConcreteGlobalBlock, i32 1342177280, i32 0, ptr ptrauth (ptr @__a_block_invoke, i32 0, i64 0, ptr getelementptr inbounds ({ ptr, i32, i32, ptr, ptr }, ptr @__block_literal_global, i32 0, i32 3)), ptr ptrauth (ptr [[BLOCK_DESCRIPTOR_NAME]], i32 2, i64 49339, ptr getelementptr inbounds ({ ptr, i32, i32, ptr, ptr }, ptr @__block_literal_global, i32 0, i32 4)) } +// CHECK: @__block_literal_global = internal constant { ptr, i32, i32, ptr, ptr } { ptr @_NSConcreteGlobalBlock, i32 1342177280, i32 0, ptr ptrauth (ptr @__a_block_invoke, [i64 0, i64 0, i64 ptrtoint (ptr getelementptr inbounds ({ ptr, i32, i32, ptr, ptr }, ptr @__block_literal_global, i32 0, i32 3) to i64)]), ptr ptrauth (ptr [[BLOCK_DESCRIPTOR_NAME]], [i64 2, i64 49339, i64 ptrtoint (ptr getelementptr inbounds ({ ptr, i32, i32, ptr, ptr }, ptr @__block_literal_global, i32 0, i32 4) to i64)]) } // NODESCRIPTORAUTH: [[BLOCK_DESCRIPTOR_NAME:@"__block_descriptor_.*"]] = linkonce_odr hidden unnamed_addr constant { i64, i64, ptr, ptr } { i64 0, i64 32, ptr @.str, ptr null } -// NODESCRIPTORAUTH: @__block_literal_global = internal constant { ptr, i32, i32, ptr, ptr } { ptr @_NSConcreteGlobalBlock, i32 1342177280, i32 0, ptr ptrauth (ptr @__a_block_invoke, i32 0, i64 0, ptr getelementptr inbounds ({ ptr, i32, i32, ptr, ptr }, ptr @__block_literal_global, i32 0, i32 3)), ptr [[BLOCK_DESCRIPTOR_NAME]] } +// NODESCRIPTORAUTH: @__block_literal_global = internal constant { ptr, i32, i32, ptr, ptr } { ptr @_NSConcreteGlobalBlock, i32 1342177280, i32 0, ptr ptrauth (ptr @__a_block_invoke, [i64 0, i64 0, i64 ptrtoint (ptr getelementptr inbounds ({ ptr, i32, i32, ptr, ptr }, ptr @__block_literal_global, i32 0, i32 3) to i64)]), ptr [[BLOCK_DESCRIPTOR_NAME]] } void b(int p) { @@ -28,8 +28,7 @@ void b(int p) { // CHECK: [[BLOCK:%.*]] = alloca <{ ptr, i32, i32, ptr, ptr, i32 }> // CHECK: [[BLOCK_DESCRIPTOR_REF:%.*]] = getelementptr inbounds nuw <{ {{.*}} }>, ptr [[BLOCK]], i32 0, i32 4 // CHECK: [[BLOCK_DESCRIPTOR_REF_INT:%.*]] = ptrtoint ptr [[BLOCK_DESCRIPTOR_REF]] to i64 - // CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[BLOCK_DESCRIPTOR_REF_INT]], i64 49339) - // CHECK: [[SIGNED_REF:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @"__block_descriptor_36_e5_v8\01?0l" to i64), i32 2, i64 [[BLENDED]]) + // CHECK: [[SIGNED_REF:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @"__block_descriptor_36_e5_v8\01?0l" to i64)) [ "ptrauth"(i64 2, i64 49339, i64 [[BLOCK_DESCRIPTOR_REF_INT]]) ] // CHECK: [[SIGNED_REF_PTR:%.*]] = inttoptr i64 [[SIGNED_REF]] to ptr // CHECK: store ptr [[SIGNED_REF_PTR]], ptr [[BLOCK_DESCRIPTOR_REF]] diff --git a/clang/test/CodeGenObjC/ptrauth-block-isa.m b/clang/test/CodeGenObjC/ptrauth-block-isa.m index 248e57769ba1e..638a7bdf79f35 100644 --- a/clang/test/CodeGenObjC/ptrauth-block-isa.m +++ b/clang/test/CodeGenObjC/ptrauth-block-isa.m @@ -2,7 +2,7 @@ void (^globalblock)(void) = ^{}; // CHECK: [[BLOCK_DESCRIPTOR_NAME:@"__block_descriptor_.*"]] = linkonce_odr hidden unnamed_addr constant { i64, i64, ptr, ptr } { i64 0, i64 32, ptr @.str, ptr null }, comdat, align 8 -// CHECK: @__block_literal_global = internal constant { ptr, i32, i32, ptr, ptr } { ptr ptrauth (ptr @_NSConcreteGlobalBlock, i32 2, i64 27361, ptr @__block_literal_global), i32 1342177280, i32 0, ptr ptrauth (ptr @globalblock_block_invoke, i32 0, i64 0, ptr getelementptr inbounds ({ ptr, i32, i32, ptr, ptr }, ptr @__block_literal_global, i32 0, i32 3)), ptr [[BLOCK_DESCRIPTOR_NAME]] } +// CHECK: @__block_literal_global = internal constant { ptr, i32, i32, ptr, ptr } { ptr ptrauth (ptr @_NSConcreteGlobalBlock, [i64 2, i64 27361, i64 ptrtoint (ptr @__block_literal_global to i64)]), i32 1342177280, i32 0, ptr ptrauth (ptr @globalblock_block_invoke, [i64 0, i64 0, i64 ptrtoint (ptr getelementptr inbounds ({ ptr, i32, i32, ptr, ptr }, ptr @__block_literal_global, i32 0, i32 3) to i64)]), ptr [[BLOCK_DESCRIPTOR_NAME]] } @interface A - (int) count; @@ -16,8 +16,7 @@ void test_block_literal(int i) { // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:.*]], align // CHECK: [[ISAPTRADDR:%.*]] = getelementptr inbounds nuw [[BLOCK_T]], ptr [[BLOCK]], i32 0, i32 0 // CHECK-NEXT: [[ISAPTRADDR_I:%.*]] = ptrtoint ptr [[ISAPTRADDR]] to i64 - // CHECK-NEXT: [[ISADISCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[ISAPTRADDR_I]], i64 27361) - // CHECK-NEXT: [[SIGNEDISA:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @_NSConcreteStackBlock to i64), i32 2, i64 [[ISADISCRIMINATOR]]) + // CHECK-NEXT: [[SIGNEDISA:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @_NSConcreteStackBlock to i64)) [ "ptrauth"(i64 2, i64 27361, i64 [[ISAPTRADDR_I]]) ] // CHECK-NEXT: [[SIGNEDISAPTR:%.*]] = inttoptr i64 [[SIGNEDISA]] to ptr // CHECK-NEXT: store ptr [[SIGNEDISAPTR]], ptr [[ISAPTRADDR]] use_block(^{return i;}); @@ -31,8 +30,7 @@ void test_conversion(id a) { // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:.*]], align // CHECK: [[ISAPTRADDR:%.*]] = getelementptr inbounds nuw [[BLOCK_T]], ptr [[BLOCK]], i32 0, i32 0 // CHECK-NEXT: [[ISAPTRADDR_I:%.*]] = ptrtoint ptr [[ISAPTRADDR]] to i64 - // CHECK-NEXT: [[ISADISCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[ISAPTRADDR_I]], i64 27361) - // CHECK-NEXT: [[SIGNEDISA:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @_NSConcreteStackBlock to i64), i32 2, i64 [[ISADISCRIMINATOR]]) + // CHECK-NEXT: [[SIGNEDISA:%.*]] = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr @_NSConcreteStackBlock to i64)) [ "ptrauth"(i64 2, i64 27361, i64 [[ISAPTRADDR_I]]) ] // CHECK-NEXT: [[SIGNEDISAPTR:%.*]] = inttoptr i64 [[SIGNEDISA]] to ptr // CHECK-NEXT: store ptr [[SIGNEDISAPTR]], ptr [[ISAPTRADDR]] test_conversion_helper(^{ diff --git a/clang/test/CodeGenObjC/ptrauth-class-ro.m b/clang/test/CodeGenObjC/ptrauth-class-ro.m index a80b3d34bf9f4..2e1157ca52ba8 100644 --- a/clang/test/CodeGenObjC/ptrauth-class-ro.m +++ b/clang/test/CodeGenObjC/ptrauth-class-ro.m @@ -1,13 +1,13 @@ // RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -Wno-objc-root-class -fptrauth-objc-class-ro -fobjc-arc -emit-llvm -o - %s | FileCheck %s -// CHECK: @"OBJC_CLASS_$_C" = global %struct._class_t { ptr @"OBJC_METACLASS_$_C", ptr null, ptr @_objc_empty_cache, ptr null, ptr ptrauth (ptr @"_OBJC_CLASS_RO_$_C", i32 2, i64 25080, ptr getelementptr inbounds (%struct._class_t, ptr @"OBJC_CLASS_$_C", i32 0, i32 4)) }, section "__DATA, __objc_data", align 8 -// CHECK: @"OBJC_METACLASS_$_C" = global %struct._class_t { ptr @"OBJC_METACLASS_$_C", ptr @"OBJC_CLASS_$_C", ptr @_objc_empty_cache, ptr null, ptr ptrauth (ptr @"_OBJC_METACLASS_RO_$_C", i32 2, i64 25080, ptr getelementptr inbounds (%struct._class_t, ptr @"OBJC_METACLASS_$_C", i32 0, i32 4)) }, section "__DATA, __objc_data", align 8 +// CHECK: @"OBJC_CLASS_$_C" = global %struct._class_t { ptr @"OBJC_METACLASS_$_C", ptr null, ptr @_objc_empty_cache, ptr null, ptr ptrauth (ptr @"_OBJC_CLASS_RO_$_C", [i64 2, i64 25080, i64 ptrtoint (ptr getelementptr inbounds (%struct._class_t, ptr @"OBJC_CLASS_$_C", i32 0, i32 4) to i64)]) }, section "__DATA, __objc_data", align 8 +// CHECK: @"OBJC_METACLASS_$_C" = global %struct._class_t { ptr @"OBJC_METACLASS_$_C", ptr @"OBJC_CLASS_$_C", ptr @_objc_empty_cache, ptr null, ptr ptrauth (ptr @"_OBJC_METACLASS_RO_$_C", [i64 2, i64 25080, i64 ptrtoint (ptr getelementptr inbounds (%struct._class_t, ptr @"OBJC_METACLASS_$_C", i32 0, i32 4) to i64)]) }, section "__DATA, __objc_data", align 8 // CHECK: @OBJC_CLASS_NAME_ = private unnamed_addr constant [2 x i8] c"C\00", section "__TEXT,__objc_classname,cstring_literals", align 1 // CHECK: @"_OBJC_METACLASS_RO_$_C" = internal global %struct._class_ro_t { i32 131, i32 40, i32 40, ptr null, ptr @OBJC_CLASS_NAME_, ptr null, ptr null, ptr null, ptr null, ptr null }, section "__DATA, __objc_const", align 8 // CHECK: @OBJC_METH_VAR_NAME_ = private unnamed_addr constant [3 x i8] c"m0\00", section "__TEXT,__objc_methname,cstring_literals", align 1 // CHECK: @OBJC_METH_VAR_TYPE_ = private unnamed_addr constant [8 x i8] c"v16@0:8\00", section "__TEXT,__objc_methtype,cstring_literals", align 1 -// CHECK: @"_OBJC_$_INSTANCE_METHODS_C" = internal global { i32, i32, [1 x %struct._objc_method] } { i32 24, i32 1, [1 x %struct._objc_method] [%struct._objc_method { ptr @OBJC_METH_VAR_NAME_, ptr @OBJC_METH_VAR_TYPE_, ptr ptrauth (ptr @"\01-[C m0]", i32 0, i64 0, ptr getelementptr inbounds ({ i32, i32, [1 x %struct._objc_method] }, ptr @"_OBJC_$_INSTANCE_METHODS_C", i32 0, i32 2, i32 0, i32 2)) }] }, section "__DATA, __objc_const", align 8 -// CHECK: @"_OBJC_CLASS_RO_$_C" = internal global %struct._class_ro_t { i32 130, i32 0, i32 0, ptr null, ptr @OBJC_CLASS_NAME_, ptr ptrauth (ptr @"_OBJC_$_INSTANCE_METHODS_C", i32 2, i64 49936, ptr getelementptr inbounds (%struct._class_ro_t, ptr @"_OBJC_CLASS_RO_$_C", i32 0, i32 5)), ptr null, ptr null, ptr null, ptr null }, section "__DATA, __objc_const", align 8 +// CHECK: @"_OBJC_$_INSTANCE_METHODS_C" = internal global { i32, i32, [1 x %struct._objc_method] } { i32 24, i32 1, [1 x %struct._objc_method] [%struct._objc_method { ptr @OBJC_METH_VAR_NAME_, ptr @OBJC_METH_VAR_TYPE_, ptr ptrauth (ptr @"\01-[C m0]", [i64 0, i64 0, i64 ptrtoint (ptr getelementptr inbounds ({ i32, i32, [1 x %struct._objc_method] }, ptr @"_OBJC_$_INSTANCE_METHODS_C", i32 0, i32 2, i32 0, i32 2) to i64)]) }] }, section "__DATA, __objc_const", align 8 +// CHECK: @"_OBJC_CLASS_RO_$_C" = internal global %struct._class_ro_t { i32 130, i32 0, i32 0, ptr null, ptr @OBJC_CLASS_NAME_, ptr ptrauth (ptr @"_OBJC_$_INSTANCE_METHODS_C", [i64 2, i64 49936, i64 ptrtoint (ptr getelementptr inbounds (%struct._class_ro_t, ptr @"_OBJC_CLASS_RO_$_C", i32 0, i32 5) to i64)]), ptr null, ptr null, ptr null, ptr null }, section "__DATA, __objc_const", align 8 // CHECK: @OBJC_SELECTOR_REFERENCES_ = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", align 8 // CHECK: @"OBJC_LABEL_CLASS_$" = private global [1 x ptr] [ptr @"OBJC_CLASS_$_C"], section "__DATA,__objc_classlist,regular,no_dead_strip" diff --git a/clang/test/CodeGenObjC/ptrauth-class.m b/clang/test/CodeGenObjC/ptrauth-class.m index c5ad03665f2a7..3ccbf4e12d425 100644 --- a/clang/test/CodeGenObjC/ptrauth-class.m +++ b/clang/test/CodeGenObjC/ptrauth-class.m @@ -32,9 +32,8 @@ void setTestStructIsa(struct TestStruct *t, Class c) { // CHECK: [[ISA_SLOT:%.*]] = getelementptr inbounds nuw %struct.TestStruct, ptr %0, i32 0, i32 0 // CHECK: [[C:%.*]] = load ptr, ptr %c.addr, align 8 // CHECK: [[CAST_ISA_SLOT:%.*]] = ptrtoint ptr [[ISA_SLOT]] to i64 - // CHECK: [[BLENDED_VALUE:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_ISA_SLOT]], i64 1234) // CHECK: [[CAST_C:%.*]] = ptrtoint ptr [[C]] to i64 - // CHECK: [[AUTHENTICATED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[CAST_C]], i32 2, i64 [[BLENDED_VALUE]]) + // CHECK: [[AUTHENTICATED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[CAST_C]]) [ "ptrauth"(i64 2, i64 1234, i64 [[CAST_ISA_SLOT]]) ] } // CHECK-LABEL: define void @setTestClassIsa(ptr %t, ptr %c) #0 { @@ -49,9 +48,8 @@ void setTestClassIsa(TestClass *t, Class c) { // CHECK: [[ADDED_PTR:%.*]] = getelementptr inbounds i8, ptr %1, i64 [[IVAR_OFFSET64]] // CHECK: [[C_VALUE:%.*]] = load ptr, ptr [[C_ADDR]], align 8 // CHECK: [[CAST_ISA_SLOT:%.*]] = ptrtoint ptr [[ADDED_PTR]] to i64 - // CHECK: [[BLENDED_VALUE:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_ISA_SLOT]], i64 1234) // CHECK: [[CAST_C_VALUE:%.*]] = ptrtoint ptr [[C_VALUE]] to i64 - // CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[CAST_C_VALUE]], i32 2, i64 [[BLENDED_VALUE]]) + // CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[CAST_C_VALUE]]) [ "ptrauth"(i64 2, i64 1234, i64 [[CAST_ISA_SLOT]]) ] } // CHECK-LABEL: define ptr @getTestStructIsa(ptr %t) #0 { @@ -62,9 +60,8 @@ Class getTestStructIsa(struct TestStruct *t) { // CHECK: [[ISA_SLOT:%.*]] = getelementptr inbounds nuw %struct.TestStruct, ptr [[T_VALUE]], i32 0, i32 0 // CHECK: [[ISA_VALUE:%.*]] = load ptr, ptr [[ISA_SLOT]], align 8 // CHECK: [[CAST_ISA_SLOT:%.*]] = ptrtoint ptr %isa to i64 - // CHECK: [[BLENDED_VALUE:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_ISA_SLOT]], i64 1234) // CHECK: [[CAST_ISA_VALUE:%.*]] = ptrtoint ptr [[ISA_VALUE]] to i64 - // CHECK: [[SIGNED_VALUE:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[CAST_ISA_VALUE]], i32 2, i64 [[BLENDED_VALUE]]) + // CHECK: [[SIGNED_VALUE:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[CAST_ISA_VALUE]]) [ "ptrauth"(i64 2, i64 1234, i64 [[CAST_ISA_SLOT]]) ] } // CHECK-LABEL: define ptr @getTestClassIsa(ptr %t) #0 { @@ -77,10 +74,9 @@ Class getTestClassIsa(TestClass *t) { // CHECK: [[ADD_PTR:%.*]] = getelementptr inbounds i8, ptr [[T]], i64 [[IVAR_CONV]] // CHECK: [[LOADED_VALUE:%.*]] = load ptr, ptr [[ADD_PTR]], align 8 // CHECK: [[INT_VALUE:%.*]] = ptrtoint ptr [[ADD_PTR]] to i64 - // CHECK: [[BLENDED_VALUE:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[INT_VALUE]], i64 1234) // CHECK: [[NULL_CHECK:%.*]] = icmp ne ptr [[LOADED_VALUE]], null // CHECK: [[CAST_VALUE:%.*]] = ptrtoint ptr [[LOADED_VALUE]] to i64 - // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[CAST_VALUE]], i32 2, i64 [[BLENDED_VALUE]]) + // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[CAST_VALUE]]) [ "ptrauth"(i64 2, i64 1234, i64 [[INT_VALUE]]) ] } // Just enough to verify we do actually authenticate qualified Class @@ -94,10 +90,9 @@ Class getTestConstClassIsa(TestConstClass *t) { // CHECK: [[ADD_PTR:%.*]] = getelementptr inbounds i8, ptr [[T]], i64 [[IVAR_CONV]] // CHECK: [[LOADED_VALUE:%.*]] = load ptr, ptr [[ADD_PTR]], align 8 // CHECK: [[INT_VALUE:%.*]] = ptrtoint ptr [[ADD_PTR]] to i64 - // CHECK: [[BLENDED_VALUE:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[INT_VALUE]], i64 1234) // CHECK: [[NULL_CHECK:%.*]] = icmp ne ptr [[LOADED_VALUE]], null // CHECK: [[CAST_VALUE:%.*]] = ptrtoint ptr [[LOADED_VALUE]] to i64 - // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[CAST_VALUE]], i32 2, i64 [[BLENDED_VALUE]]) + // CHECK: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[CAST_VALUE]]) [ "ptrauth"(i64 2, i64 1234, i64 [[INT_VALUE]]) ] } #endif diff --git a/clang/test/CodeGenObjC/ptrauth-objc-interface-selector.m b/clang/test/CodeGenObjC/ptrauth-objc-interface-selector.m index 15f7d03a0ba2d..7aa567291380f 100644 --- a/clang/test/CodeGenObjC/ptrauth-objc-interface-selector.m +++ b/clang/test/CodeGenObjC/ptrauth-objc-interface-selector.m @@ -31,44 +31,31 @@ @interface Test { @end // CHECK-AUTHENTICATED-SEL-LABEL: define internal ptr @"\01-[Test test:]" -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 22466) -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 22466) -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 {{%.*}}, i32 3, i64 {{%.*}}, i32 3, i64 {{%.*}}) +// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 {{%.*}}) [ "ptrauth"(i64 3, i64 22466, i64 {{%.*}}), "ptrauth"(i64 3, i64 22466, i64 {{%.*}}) ] // CHECK-AUTHENTICATED-SEL: {{%.*}} = load volatile ptr, ptr {{%.*}}, align 8 -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 22466) -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 22466) -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 {{%.*}}, i32 3, i64 {{%.*}}, i32 3, i64 {{%.*}}) -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 22467) +// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 {{%.*}}) [ "ptrauth"(i64 3, i64 22466, i64 {{%.*}}), "ptrauth"(i64 3, i64 22466, i64 {{%.*}}) ] // CHECK-AUTHENTICATED-SEL: {{%.*}} = ptrtoint ptr {{%.*}} to i64 -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 22467) // CHECK-AUTHENTICATED-SEL: {{%.*}} = ptrtoint ptr {{%.*}} to i64 -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 {{%.*}}, i32 3, i64 {{%.*}}, i32 3, i64 {{%.*}}) -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 22466) -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.auth(i64 {{%.*}}, i32 3, i64 {{%.*}}) +// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 {{%.*}}) [ "ptrauth"(i64 3, i64 22467, i64 {{%.*}}), "ptrauth"(i64 3, i64 22467, i64 {{%.*}}) ] +// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.auth(i64 {{%.*}}) [ "ptrauth"(i64 3, i64 22466, i64 {{%.*}}) ] // CHECK-AUTHENTICATED-SEL-LABEL: define internal ptr @"\01-[Test auto_sel_property]" -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 22466) -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.auth(i64 {{%.*}}, i32 3, i64 {{%.*}}) +// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.auth(i64 {{%.*}}) [ "ptrauth"(i64 3, i64 22466, i64 {{%.*}}) ] // CHECK-AUTHENTICATED-SEL-LABEL: define internal void @"\01-[Test setAuto_sel_property:]" -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 22466) -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.sign(i64 {{%.*}}, i32 3, i64 {{%.*}}) +// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.sign(i64 {{%.*}}) [ "ptrauth"(i64 3, i64 22466, i64 {{%.*}}) ] // CHECK-AUTHENTICATED-SEL-LABEL: define internal ptr @"\01-[Test const_auto_sel_property]" -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 22466) -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.auth(i64 {{%.*}}, i32 3, i64 {{%.*}}) +// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.auth(i64 {{%.*}}) [ "ptrauth"(i64 3, i64 22466, i64 {{%.*}}) ] // CHECK-AUTHENTICATED-SEL-LABEL: define internal void @"\01-[Test setConst_auto_sel_property:]" -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 22466) -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.sign(i64 {{%.*}}, i32 3, i64 {{%.*}}) +// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.sign(i64 {{%.*}}) [ "ptrauth"(i64 3, i64 22466, i64 {{%.*}}) ] // CHECK-AUTHENTICATED-SEL-LABEL: define internal ptr @"\01-[Test volatile_auto_sel_property]" -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 22466) -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.auth(i64 {{%.*}}, i32 3, i64 {{%.*}}) +// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.auth(i64 {{%.*}}) [ "ptrauth"(i64 3, i64 22466, i64 {{%.*}}) ] // CHECK-AUTHENTICATED-SEL-LABEL: define internal void @"\01-[Test setVolatile_auto_sel_property:]" -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 22466) -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.sign(i64 {{%.*}}, i32 3, i64 {{%.*}}) +// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.sign(i64 {{%.*}}) [ "ptrauth"(i64 3, i64 22466, i64 {{%.*}}) ] @implementation Test - (SEL)test:(Test *)in { @@ -83,11 +70,14 @@ void auto_sel(Test *out, Test *in) { out->auto_sel = in->auto_sel; } // CHECK-AUTHENTICATED-SEL-LABEL: define void @auto_sel -// CHECK-AUTHENTICATED-SEL: [[DST_DESCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_DST_ADDR:%.*]], i64 22466) -// CHECK-AUTHENTICATED-SEL: [[CAST_SRC_ADDR:%.*]] = ptrtoint ptr [[SRC_ADDR:%.*]] to i64 -// CHECK-AUTHENTICATED-SEL: [[SRC_DESCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_SRC_ADDR]], i64 22466) +// CHECK-AUTHENTICATED-SEL: [[V0:%.*]] = load ptr, ptr %out.addr +// CHECK-AUTHENTICATED-SEL: [[SRC_ADDR:%.*]] = getelementptr inbounds i8, ptr [[V0]], i64 0 +// CHECK-AUTHENTICATED-SEL: [[V1:%.*]] = load ptr, ptr %in.addr +// CHECK-AUTHENTICATED-SEL: [[DST_ADDR:%.*]] = getelementptr inbounds i8, ptr [[V1]], i64 0 +// CHECK-AUTHENTICATED-SEL: [[CAST_DST_ADDR:%.*]] = ptrtoint ptr [[DST_ADDR]] to i64 +// CHECK-AUTHENTICATED-SEL: [[CAST_SRC_ADDR:%.*]] = ptrtoint ptr [[SRC_ADDR]] to i64 // CHECK-AUTHENTICATED-SEL: [[SRC_SEL:%.*]] = ptrtoint ptr [[SRC_SEL_ADDR:%.*]] to i64 -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[SRC_SEL]], i32 3, i64 [[DST_DESCRIMINATOR]], i32 3, i64 [[SRC_DESCRIMINATOR]]) +// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[SRC_SEL]]) [ "ptrauth"(i64 3, i64 22466, i64 [[CAST_DST_ADDR]]), "ptrauth"(i64 3, i64 22466, i64 [[CAST_SRC_ADDR]]) ] // CHECK-UNAUTHENTICATED-SEL-LABEL: define void @auto_sel SEL const_auto_sel(Test *in) { @@ -95,9 +85,8 @@ SEL const_auto_sel(Test *in) { } // CHECK-AUTHENTICATED-SEL-LABEL: define ptr @const_auto_sel -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 22466) // CHECK-AUTHENTICATED-SEL: {{%.*}} = ptrtoint ptr {{%.*}} to i64 -// CHECK-AUTHENTICATED-SEL: [[AUTHENTICATED:%.*]] = call i64 @llvm.ptrauth.auth(i64 {{%.*}}, i32 3, i64 {{%.*}}) +// CHECK-AUTHENTICATED-SEL: [[AUTHENTICATED:%.*]] = call i64 @llvm.ptrauth.auth(i64 {{%.*}}) [ "ptrauth"(i64 3, i64 22466, i64 {{%.*}}) ] // CHECK-AUTHENTICATED-SEL: [[RESULT:%.*]] = inttoptr i64 [[AUTHENTICATED]] to ptr void volatile_auto_sel(Test *out, Test *in) { @@ -105,26 +94,35 @@ void volatile_auto_sel(Test *out, Test *in) { } // CHECK-AUTHENTICATED-SEL-LABEL: define void @volatile_auto_sel -// CHECK-AUTHENTICATED-SEL: [[DST_DESCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_DST_ADDR:%.*]], i64 22466) -// CHECK-AUTHENTICATED-SEL: [[CAST_SRC_ADDR:%.*]] = ptrtoint ptr [[SRC_ADDR:%.*]] to i64 -// CHECK-AUTHENTICATED-SEL: [[SRC_DESCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_SRC_ADDR]], i64 22466) +// CHECK-AUTHENTICATED-SEL: [[V0:%.*]] = load ptr, ptr %out.addr +// CHECK-AUTHENTICATED-SEL: [[SRC_ADDR:%.*]] = getelementptr inbounds i8, ptr [[V0]], i64 16 +// CHECK-AUTHENTICATED-SEL: [[V1:%.*]] = load ptr, ptr %in.addr +// CHECK-AUTHENTICATED-SEL: [[DST_ADDR:%.*]] = getelementptr inbounds i8, ptr [[V1]], i64 16 +// CHECK-AUTHENTICATED-SEL: [[CAST_DST_ADDR:%.*]] = ptrtoint ptr [[DST_ADDR]] to i64 +// CHECK-AUTHENTICATED-SEL: [[CAST_SRC_ADDR:%.*]] = ptrtoint ptr [[SRC_ADDR]] to i64 // CHECK-AUTHENTICATED-SEL: [[SRC_SEL:%.*]] = ptrtoint ptr [[SRC_SEL_ADDR:%.*]] to i64 -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[SRC_SEL]], i32 3, i64 [[DST_DESCRIMINATOR]], i32 3, i64 [[SRC_DESCRIMINATOR]]) +// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[SRC_SEL]]) [ "ptrauth"(i64 3, i64 22466, i64 [[CAST_DST_ADDR]]), "ptrauth"(i64 3, i64 22466, i64 [[CAST_SRC_ADDR]]) ] void manual(Test *out, Test *in) { out->manual = in->manual; } // CHECK-AUTHENTICATED-SEL-LABEL: define void @manual -// CHECK-AUTHENTICATED-SEL: [[DST_DESCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_DST_ADDR:%.*]], i64 22467) -// CHECK-AUTHENTICATED-SEL: [[CAST_SRC_ADDR:%.*]] = ptrtoint ptr [[SRC_ADDR:%.*]] to i64 -// CHECK-AUTHENTICATED-SEL: [[SRC_DESCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_SRC_ADDR]], i64 22467) +// CHECK-AUTHENTICATED-SEL: [[V0:%.*]] = load ptr, ptr %out.addr +// CHECK-AUTHENTICATED-SEL: [[SRC_ADDR:%.*]] = getelementptr inbounds i8, ptr [[V0]], i64 24 +// CHECK-AUTHENTICATED-SEL: [[V0:%.*]] = load ptr, ptr %in.addr +// CHECK-AUTHENTICATED-SEL: [[DST_ADDR:%.*]] = getelementptr inbounds i8, ptr [[V1]], i64 24 +// CHECK-AUTHENTICATED-SEL: [[CAST_DST_ADDR:%.*]] = ptrtoint ptr [[DST_ADDR]] to i64 +// CHECK-AUTHENTICATED-SEL: [[CAST_SRC_ADDR:%.*]] = ptrtoint ptr [[SRC_ADDR]] to i64 // CHECK-AUTHENTICATED-SEL: [[SRC_SEL:%.*]] = ptrtoint ptr [[SRC_SEL_ADDR:%.*]] to i64 -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[SRC_SEL]], i32 3, i64 [[DST_DESCRIMINATOR]], i32 3, i64 [[SRC_DESCRIMINATOR]]) +// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[SRC_SEL]]) [ "ptrauth"(i64 3, i64 22467, i64 [[CAST_DST_ADDR]]), "ptrauth"(i64 3, i64 22467, i64 [[CAST_SRC_ADDR]]) ] // CHECK-UNAUTHENTICATED-SEL-LABEL: define void @manual -// CHECK-UNAUTHENTICATED-SEL: [[DST_DESCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_DST_ADDR:%.*]], i64 22467) -// CHECK-UNAUTHENTICATED-SEL: [[CAST_SRC_ADDR:%.*]] = ptrtoint ptr [[SRC_ADDR:%.*]] to i64 -// CHECK-UNAUTHENTICATED-SEL: [[SRC_DESCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_SRC_ADDR]], i64 22467) +// CHECK-UNAUTHENTICATED-SEL: [[V0:%.*]] = load ptr, ptr %out.addr +// CHECK-UNAUTHENTICATED-SEL: [[SRC_ADDR:%.*]] = getelementptr inbounds i8, ptr [[V0]], i64 24 +// CHECK-UNAUTHENTICATED-SEL: [[V1:%.*]] = load ptr, ptr %in.addr +// CHECK-UNAUTHENTICATED-SEL: [[DST_ADDR:%.*]] = getelementptr inbounds i8, ptr [[V1]], i64 24 +// CHECK-UNAUTHENTICATED-SEL: [[CAST_DST_ADDR:%.*]] = ptrtoint ptr [[DST_ADDR]] to i64 +// CHECK-UNAUTHENTICATED-SEL: [[CAST_SRC_ADDR:%.*]] = ptrtoint ptr [[SRC_ADDR]] to i64 // CHECK-UNAUTHENTICATED-SEL: [[SRC_SEL:%.*]] = ptrtoint ptr [[SRC_SEL_ADDR:%.*]] to i64 -// CHECK-UNAUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[SRC_SEL]], i32 3, i64 [[DST_DESCRIMINATOR]], i32 3, i64 [[SRC_DESCRIMINATOR]]) +// CHECK-UNAUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[SRC_SEL]]) [ "ptrauth"(i64 3, i64 22467, i64 [[CAST_DST_ADDR]]), "ptrauth"(i64 3, i64 22467, i64 [[CAST_SRC_ADDR]]) ] diff --git a/clang/test/CodeGenObjC/ptrauth-objc-isa-super.m b/clang/test/CodeGenObjC/ptrauth-objc-isa-super.m index 69fd01f28067d..7eb7cb14f4502 100644 --- a/clang/test/CodeGenObjC/ptrauth-objc-isa-super.m +++ b/clang/test/CodeGenObjC/ptrauth-objc-isa-super.m @@ -12,7 +12,7 @@ @class NSString; -// CHECK: @"OBJC_METACLASS_$_C" = global %struct._class_t { ptr ptrauth (ptr @"OBJC_METACLASS_$_Base", i32 2, i64 27361, ptr @"OBJC_METACLASS_$_C"), ptr ptrauth (ptr @"OBJC_METACLASS_$_Base", i32 2, i64 46507, ptr getelementptr inbounds (%struct._class_t, ptr @"OBJC_METACLASS_$_C", i32 0, i32 1)), ptr @_objc_empty_cache, ptr null, ptr @"_OBJC_METACLASS_RO_$_C" } +// CHECK: @"OBJC_METACLASS_$_C" = global %struct._class_t { ptr ptrauth (ptr @"OBJC_METACLASS_$_Base", [i64 2, i64 27361, i64 ptrtoint (ptr @"OBJC_METACLASS_$_C" to i64)]), ptr ptrauth (ptr @"OBJC_METACLASS_$_Base", [i64 2, i64 46507, i64 ptrtoint (ptr getelementptr inbounds (%struct._class_t, ptr @"OBJC_METACLASS_$_C", i32 0, i32 1) to i64)]), ptr @_objc_empty_cache, ptr null, ptr @"_OBJC_METACLASS_RO_$_C" } // CHECK: @"OBJC_CLASSLIST_SUP_REFS_$_" = private global ptr @"OBJC_METACLASS_$_C" // CHECK: @OBJC_METH_VAR_NAME_ = private unnamed_addr constant [5 x i8] c"test\00" // CHECK: @OBJC_SELECTOR_REFERENCES_ = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_ @@ -20,12 +20,12 @@ // CHECK: @OBJC_CLASS_NAME_ = private unnamed_addr constant [2 x i8] c"C\00" // CHECK: @OBJC_METH_VAR_NAME_.1 = private unnamed_addr constant [11 x i8] c"super_test\00" // CHECK: @OBJC_METH_VAR_TYPE_ = private unnamed_addr constant [8 x i8] c"v16@0:8\00" -// CHECK: @"_OBJC_$_CLASS_METHODS_C" = internal global { i32, i32, [1 x %struct._objc_method] } { i32 24, i32 1, [1 x %struct._objc_method] [%struct._objc_method { ptr @OBJC_METH_VAR_NAME_.1, ptr @OBJC_METH_VAR_TYPE_, ptr ptrauth (ptr @"\01+[C super_test]", i32 0, i64 0, ptr getelementptr inbounds ({ i32, i32, [1 x %struct._objc_method] }, ptr @"_OBJC_$_CLASS_METHODS_C", i32 0, i32 2, i32 0, i32 2)) }] } -// CHECK: @"_OBJC_METACLASS_RO_$_C" = internal global %struct._class_ro_t { i32 129, i32 40, i32 40, ptr null, ptr @OBJC_CLASS_NAME_, ptr ptrauth (ptr @"_OBJC_$_CLASS_METHODS_C", i32 2, i64 49936, ptr getelementptr inbounds (%struct._class_ro_t, ptr @"_OBJC_METACLASS_RO_$_C", i32 0, i32 5)), ptr null, ptr null, ptr null, ptr null } +// CHECK: @"_OBJC_$_CLASS_METHODS_C" = internal global { i32, i32, [1 x %struct._objc_method] } { i32 24, i32 1, [1 x %struct._objc_method] [%struct._objc_method { ptr @OBJC_METH_VAR_NAME_.1, ptr @OBJC_METH_VAR_TYPE_, ptr ptrauth (ptr @"\01+[C super_test]", [i64 0, i64 0, i64 ptrtoint (ptr getelementptr inbounds ({ i32, i32, [1 x %struct._objc_method] }, ptr @"_OBJC_$_CLASS_METHODS_C", i32 0, i32 2, i32 0, i32 2) to i64)]) }] } +// CHECK: @"_OBJC_METACLASS_RO_$_C" = internal global %struct._class_ro_t { i32 129, i32 40, i32 40, ptr null, ptr @OBJC_CLASS_NAME_, ptr ptrauth (ptr @"_OBJC_$_CLASS_METHODS_C", [i64 2, i64 49936, i64 ptrtoint (ptr getelementptr inbounds (%struct._class_ro_t, ptr @"_OBJC_METACLASS_RO_$_C", i32 0, i32 5) to i64)]), ptr null, ptr null, ptr null, ptr null } // CHECK: @"OBJC_CLASS_$_Base" = external global %struct._class_t // CHECK: @"_OBJC_CLASS_RO_$_C" = internal global %struct._class_ro_t { i32 128, i32 0, i32 0, ptr null, ptr @OBJC_CLASS_NAME_, ptr null, ptr null, ptr null, ptr null, ptr null } -// @"_OBJC_CLASS_RO_$_C" = internal global %struct._class_ro_t { i32 128, i32 0, i32 0, ptr null, ptr @OBJC_CLASS_NAME_, ptr ptrauth (ptr null, i32 2, i64 49936, ptr getelementptr inbounds (%struct._class_ro_t, ptr @"_OBJC_CLASS_RO_$_C", i32 0, i32 5)), ptr null, ptr null, ptr null, ptr null } -// CHECK: @"OBJC_CLASS_$_C" = global %struct._class_t { ptr ptrauth (ptr @"OBJC_METACLASS_$_C", i32 2, i64 27361, ptr @"OBJC_CLASS_$_C"), ptr ptrauth (ptr @"OBJC_CLASS_$_Base", i32 2, i64 46507, ptr getelementptr inbounds (%struct._class_t, ptr @"OBJC_CLASS_$_C", i32 0, i32 1)), ptr @_objc_empty_cache, ptr null, ptr @"_OBJC_CLASS_RO_$_C" } +// @"_OBJC_CLASS_RO_$_C" = internal global %struct._class_ro_t { i32 128, i32 0, i32 0, ptr null, ptr @OBJC_CLASS_NAME_, ptr ptrauth (ptr null, [i64 2, i64 49936, i64 ptrtoint (ptr getelementptr inbounds (%struct._class_ro_t, ptr @"_OBJC_CLASS_RO_$_C", i32 0, i32 5) to i64]), ptr null, ptr null, ptr null, ptr null } +// CHECK: @"OBJC_CLASS_$_C" = global %struct._class_t { ptr ptrauth (ptr @"OBJC_METACLASS_$_C", [i64 2, i64 27361, i64 ptrtoint (ptr @"OBJC_CLASS_$_C" to i64)]), ptr ptrauth (ptr @"OBJC_CLASS_$_Base", [i64 2, i64 46507, i64 ptrtoint (ptr getelementptr inbounds (%struct._class_t, ptr @"OBJC_CLASS_$_C", i32 0, i32 1) to i64)]), ptr @_objc_empty_cache, ptr null, ptr @"_OBJC_CLASS_RO_$_C" } // CHECK: @"OBJC_LABEL_CLASS_$" = private global [1 x ptr] [ptr @"OBJC_CLASS_$_C"] @interface Base diff --git a/clang/test/CodeGenObjC/ptrauth-objc-method-list-pointer.m b/clang/test/CodeGenObjC/ptrauth-objc-method-list-pointer.m index e7cb5642ee490..ea19dd0d87638 100644 --- a/clang/test/CodeGenObjC/ptrauth-objc-method-list-pointer.m +++ b/clang/test/CodeGenObjC/ptrauth-objc-method-list-pointer.m @@ -6,12 +6,12 @@ @implementation X -(void)meth {} @end -// CHECK: @"OBJC_CLASS_$_X" = global %struct._class_t { ptr @"OBJC_METACLASS_$_X", ptr null, ptr @_objc_empty_cache, ptr null, ptr ptrauth (ptr @"_OBJC_CLASS_RO_$_X", i32 2, i64 25080, ptr getelementptr inbounds (%struct._class_t, ptr @"OBJC_CLASS_$_X", i32 0, i32 4)) } -// CHECK: @"OBJC_METACLASS_$_X" = global %struct._class_t { ptr @"OBJC_METACLASS_$_X", ptr @"OBJC_CLASS_$_X", ptr @_objc_empty_cache, ptr null, ptr ptrauth (ptr @"_OBJC_METACLASS_RO_$_X", i32 2, i64 25080, ptr getelementptr inbounds (%struct._class_t, ptr @"OBJC_METACLASS_$_X", i32 0, i32 4)) } +// CHECK: @"OBJC_CLASS_$_X" = global %struct._class_t { ptr @"OBJC_METACLASS_$_X", ptr null, ptr @_objc_empty_cache, ptr null, ptr ptrauth (ptr @"_OBJC_CLASS_RO_$_X", [i64 2, i64 25080, i64 ptrtoint (ptr getelementptr inbounds (%struct._class_t, ptr @"OBJC_CLASS_$_X", i32 0, i32 4) to i64)]) } +// CHECK: @"OBJC_METACLASS_$_X" = global %struct._class_t { ptr @"OBJC_METACLASS_$_X", ptr @"OBJC_CLASS_$_X", ptr @_objc_empty_cache, ptr null, ptr ptrauth (ptr @"_OBJC_METACLASS_RO_$_X", [i64 2, i64 25080, i64 ptrtoint (ptr getelementptr inbounds (%struct._class_t, ptr @"OBJC_METACLASS_$_X", i32 0, i32 4) to i64)]) } // CHECK: @OBJC_CLASS_NAME_ = private unnamed_addr constant [2 x i8] c"X\00" // CHECK: @"_OBJC_METACLASS_RO_$_X" = private global %struct._class_ro_t { i32 3, i32 40, i32 40, ptr null, ptr @OBJC_CLASS_NAME_, ptr null, ptr null, ptr null, ptr null, ptr null } // CHECK: @OBJC_METH_VAR_NAME_ = private unnamed_addr constant [5 x i8] c"meth\00" // CHECK: @OBJC_METH_VAR_TYPE_ = private unnamed_addr constant [8 x i8] c"v16@0:8\00" -// CHECK: @"_OBJC_$_INSTANCE_METHODS_X" = private global { i32, i32, [1 x %struct._objc_method] } { i32 24, i32 1, [1 x %struct._objc_method] [%struct._objc_method { ptr @OBJC_METH_VAR_NAME_, ptr @OBJC_METH_VAR_TYPE_, ptr ptrauth (ptr @"\01-[X meth]", i32 0, i64 0, ptr getelementptr inbounds ({ i32, i32, [1 x %struct._objc_method] }, ptr @"_OBJC_$_INSTANCE_METHODS_X", i32 0, i32 2, i32 0, i32 2)) }] } -// CHECK: @"_OBJC_CLASS_RO_$_X" = private global %struct._class_ro_t { i32 2, i32 0, i32 0, ptr null, ptr @OBJC_CLASS_NAME_, ptr ptrauth (ptr @"_OBJC_$_INSTANCE_METHODS_X", i32 2, i64 49936, ptr getelementptr inbounds (%struct._class_ro_t, ptr @"_OBJC_CLASS_RO_$_X", i32 0, i32 5)), ptr null, ptr null, ptr null, ptr null } +// CHECK: @"_OBJC_$_INSTANCE_METHODS_X" = private global { i32, i32, [1 x %struct._objc_method] } { i32 24, i32 1, [1 x %struct._objc_method] [%struct._objc_method { ptr @OBJC_METH_VAR_NAME_, ptr @OBJC_METH_VAR_TYPE_, ptr ptrauth (ptr @"\01-[X meth]", [i64 0, i64 0, i64 ptrtoint (ptr getelementptr inbounds ({ i32, i32, [1 x %struct._objc_method] }, ptr @"_OBJC_$_INSTANCE_METHODS_X", i32 0, i32 2, i32 0, i32 2) to i64)]) }] } +// CHECK: @"_OBJC_CLASS_RO_$_X" = private global %struct._class_ro_t { i32 2, i32 0, i32 0, ptr null, ptr @OBJC_CLASS_NAME_, ptr ptrauth (ptr @"_OBJC_$_INSTANCE_METHODS_X", [i64 2, i64 49936, i64 ptrtoint (ptr getelementptr inbounds (%struct._class_ro_t, ptr @"_OBJC_CLASS_RO_$_X", i32 0, i32 5) to i64)]), ptr null, ptr null, ptr null, ptr null } // CHECK: @"OBJC_LABEL_CLASS_$" = private global [1 x ptr] [ptr @"OBJC_CLASS_$_X"] diff --git a/clang/test/CodeGenObjC/ptrauth-property-backing.m b/clang/test/CodeGenObjC/ptrauth-property-backing.m index 8c6bcb45e7446..c306a0e7e90cf 100644 --- a/clang/test/CodeGenObjC/ptrauth-property-backing.m +++ b/clang/test/CodeGenObjC/ptrauth-property-backing.m @@ -23,13 +23,11 @@ @implementation Root // CHECK-LABEL: define internal ptr @"\01-[Root field1]" // CHECK: [[LOAD:%.*]] = load atomic i64, ptr [[ADDR:%.*]] unordered // CHECK: [[CAST_ADDR:%.*]] = ptrtoint ptr [[ADDR]] to i64 -// CHECK: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_ADDR]], i64 1) -// CHECK: [[RESULT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[LOAD]], i32 1, i64 [[BLEND]]) +// CHECK: [[RESULT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[LOAD]]) [ "ptrauth"(i64 1, i64 1, i64 [[CAST_ADDR]]) ] // CHECK-LABEL: define internal void @"\01-[Root setField1:]" // CHECK: [[CAST_ADDR:%.*]] = ptrtoint ptr [[ADDR:%.*]] to i64 -// CHECK: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_ADDR]], i64 1) -// CHECK: [[RESULT:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[VALUE:%.*]], i32 1, i64 [[BLEND]]) +// CHECK: [[RESULT:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[VALUE:%.*]]) [ "ptrauth"(i64 1, i64 1, i64 [[CAST_ADDR]]) ] // CHECK: [[PHI:%.*]] = phi i64 [ 0, {{%.*}} ], [ [[RESULT]], {{%.*}} ] // CHECK: store atomic i64 [[PHI]], ptr [[ADDR]] unordered @@ -37,15 +35,13 @@ @implementation Root // CHECK: load ptr, ptr // CHECK: [[LOAD:%.*]] = load ptr, ptr [[ADDR:%.*]], // CHECK: [[CAST_ADDR:%.*]] = ptrtoint ptr [[ADDR]] to i64 -// CHECK: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_ADDR:%.*]], i64 1) // CHECK: [[VALUE:%.*]] = ptrtoint ptr [[LOAD]] to i64 -// CHECK: [[RESULT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VALUE]], i32 1, i64 [[BLEND]]) +// CHECK: [[RESULT:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[VALUE]]) [ "ptrauth"(i64 1, i64 1, i64 [[CAST_ADDR:%.*]]) ] // CHECK-LABEL: define internal void @"\01-[Root setField2:]" // CHECK: [[CAST_ADDR:%.*]] = ptrtoint ptr [[ADDR:%.*]] to i64 -// CHECK: [[BLEND:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_ADDR]], i64 1) // CHECK: [[CAST_VALUE:%.*]] = ptrtoint ptr [[VALUE:%.*]] to i64 -// CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[CAST_VALUE]], i32 1, i64 [[BLEND]]) +// CHECK: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[CAST_VALUE]]) [ "ptrauth"(i64 1, i64 1, i64 [[CAST_ADDR]]) ] // CHECK: [[RESULT:%.*]] = inttoptr i64 [[SIGNED]] to ptr // CHECK: [[PHI:%.*]] = phi ptr [ null, {{%.*}} ], [ [[RESULT]], {{%.*}} ] // CHECK: store ptr [[PHI]], ptr [[ADDR]] @@ -53,28 +49,24 @@ @implementation Root // CHECK-LABEL: define internal ptr @"\01-[Root field3]" // CHECK: [[VALUE:%.*]] = load atomic i64, ptr [[ADDR:%.*]] unordered, align 8 // CHECK: [[CASTED_ADDR:%.*]] = ptrtoint ptr [[ADDR]] to i64 -// CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CASTED_ADDR]], i64 1) -// CHECK: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[VALUE]], i32 1, i64 [[BLENDED]], i32 0, i64 0 +// CHECK: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[VALUE]]) [ "ptrauth"(i64 1, i64 1, i64 [[CASTED_ADDR]]), "ptrauth"(i64 0, i64 0, i64 0) ] // CHECK-LABEL: define internal void @"\01-[Root setField3:]" // CHECK: [[VALUE:%.*]] = load i64, ptr {{%.*}}, align 8 // CHECK: [[CASTED_ADDR:%.*]] = ptrtoint ptr {{%.*}} to i64 -// CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CASTED_ADDR]], i64 1) -// CHECK: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[VALUE]], i32 0, i64 0, i32 1, i64 [[BLENDED]]) +// CHECK: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[VALUE]]) [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 1, i64 1, i64 [[CASTED_ADDR]]) ] // CHECK: store atomic i64 // CHECK-LABEL: define internal ptr @"\01-[Root field4]" // CHECK: load ptr, ptr // CHECK: [[VALUE:%.*]] = load ptr, ptr [[ADDR:%.*]], // CHECK: [[CASTED_ADDR:%.*]] = ptrtoint ptr [[ADDR]] to i64 -// CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CASTED_ADDR]], i64 123) // CHECK: [[CAST_VALUE:%.*]] = ptrtoint ptr [[VALUE]] to i64 -// CHECK: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[CAST_VALUE]], i32 1, i64 [[BLENDED]], i32 0, i64 0) +// CHECK: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[CAST_VALUE]]) [ "ptrauth"(i64 1, i64 123, i64 [[CASTED_ADDR]]), "ptrauth"(i64 0, i64 0, i64 0) ] // CHECK-LABEL: define internal void @"\01-[Root setField4:]" // CHECK: [[CAST_ADDR:%.*]] = ptrtoint ptr {{%.*}} to i64 -// CHECK: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_ADDR]], i64 123) // CHECK: resign.nonnull: // CHECK: [[VALUE:%.*]] = ptrtoint ptr %1 to i64 -// CHECK: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[VALUE]], i32 0, i64 0, i32 1, i64 [[BLENDED]]) +// CHECK: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[VALUE]]) [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 1, i64 123, i64 [[CAST_ADDR]]) ] diff --git a/clang/test/CodeGenObjCXX/ptrauth-objc-interface-selector.mm b/clang/test/CodeGenObjCXX/ptrauth-objc-interface-selector.mm index fc90f5ffcbcf6..8f7f2dd1d3828 100644 --- a/clang/test/CodeGenObjCXX/ptrauth-objc-interface-selector.mm +++ b/clang/test/CodeGenObjCXX/ptrauth-objc-interface-selector.mm @@ -39,11 +39,14 @@ void auto_sel(Test *out, Test *in) { out->auto_sel = in->auto_sel; } // CHECK-AUTHENTICATED-SEL: define void @auto_sel -// CHECK-AUTHENTICATED-SEL: [[DST_DESCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_DST_ADDR:%.*]], i64 22466) -// CHECK-AUTHENTICATED-SEL: [[CAST_SRC_ADDR:%.*]] = ptrtoint ptr [[SRC_ADDR:%.*]] to i64 -// CHECK-AUTHENTICATED-SEL: [[SRC_DESCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_SRC_ADDR]], i64 22466) +// CHECK-AUTHENTICATED-SEL: [[V0:%.*]] = load ptr, ptr %out.addr +// CHECK-AUTHENTICATED-SEL: [[SRC_ADDR:%.*]] = getelementptr inbounds i8, ptr [[V0]], i64 {{%.*}} +// CHECK-AUTHENTICATED-SEL: [[V1:%.*]] = load ptr, ptr %in.addr +// CHECK-AUTHENTICATED-SEL: [[DST_ADDR:%.*]] = getelementptr inbounds i8, ptr [[V1]], i64 {{%.*}} +// CHECK-AUTHENTICATED-SEL: [[CAST_DST_ADDR:%.*]] = ptrtoint ptr [[DST_ADDR]] to i64 +// CHECK-AUTHENTICATED-SEL: [[CAST_SRC_ADDR:%.*]] = ptrtoint ptr [[SRC_ADDR]] to i64 // CHECK-AUTHENTICATED-SEL: [[SRC_SEL:%.*]] = ptrtoint ptr [[SRC_SEL_ADDR:%.*]] to i64 -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[SRC_SEL]], i32 3, i64 [[DST_DESCRIMINATOR]], i32 3, i64 [[SRC_DESCRIMINATOR]]) +// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[SRC_SEL]]) [ "ptrauth"(i64 3, i64 22466, i64 [[CAST_DST_ADDR]]), "ptrauth"(i64 3, i64 22466, i64 [[CAST_SRC_ADDR]]) ] // CHECK-UNAUTHENTICATED-SEL: define void @auto_sel SEL const_auto_sel(Test *in) { @@ -52,9 +55,8 @@ SEL const_auto_sel(Test *in) { } // CHECK-AUTHENTICATED-SEL: define ptr @const_auto_sel -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.blend(i64 {{%.*}}, i64 22466) // CHECK-AUTHENTICATED-SEL: {{%.*}} = ptrtoint ptr {{%.*}} to i64 -// CHECK-AUTHENTICATED-SEL: [[AUTHENTICATED:%.*]] = call i64 @llvm.ptrauth.auth(i64 {{%.*}}, i32 3, i64 {{%.*}}) +// CHECK-AUTHENTICATED-SEL: [[AUTHENTICATED:%.*]] = call i64 @llvm.ptrauth.auth(i64 {{%.*}}) [ "ptrauth"(i64 3, i64 22466, i64 {{%.*}}) ] // CHECK-AUTHENTICATED-SEL: [[RESULT:%.*]] = inttoptr i64 [[AUTHENTICATED]] to ptr void volatile_auto_sel(Test *out, Test *in) { @@ -63,28 +65,37 @@ void volatile_auto_sel(Test *out, Test *in) { } // CHECK-AUTHENTICATED-SEL: define void @volatile_auto_sel -// CHECK-AUTHENTICATED-SEL: [[DST_DESCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_DST_ADDR:%.*]], i64 22466) -// CHECK-AUTHENTICATED-SEL: [[CAST_SRC_ADDR:%.*]] = ptrtoint ptr [[SRC_ADDR:%.*]] to i64 -// CHECK-AUTHENTICATED-SEL: [[SRC_DESCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_SRC_ADDR]], i64 22466) +// CHECK-AUTHENTICATED-SEL: [[V1:%.*]] = load ptr, ptr %out.addr +// CHECK-AUTHENTICATED-SEL: [[SRC_ADDR:%.*]] = getelementptr inbounds i8, ptr [[V1]], i64 {{%.*}} +// CHECK-AUTHENTICATED-SEL: [[V2:%.*]] = load ptr, ptr %in.addr +// CHECK-AUTHENTICATED-SEL: [[DST_ADDR:%.*]] = getelementptr inbounds i8, ptr [[V2]], i64 {{%.*}} +// CHECK-AUTHENTICATED-SEL: [[CAST_DST_ADDR:%.*]] = ptrtoint ptr [[DST_ADDR]] to i64 +// CHECK-AUTHENTICATED-SEL: [[CAST_SRC_ADDR:%.*]] = ptrtoint ptr [[SRC_ADDR]] to i64 // CHECK-AUTHENTICATED-SEL: [[SRC_SEL:%.*]] = ptrtoint ptr [[SRC_SEL_ADDR:%.*]] to i64 -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[SRC_SEL]], i32 3, i64 [[DST_DESCRIMINATOR]], i32 3, i64 [[SRC_DESCRIMINATOR]]) +// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[SRC_SEL]]) [ "ptrauth"(i64 3, i64 22466, i64 [[CAST_DST_ADDR]]), "ptrauth"(i64 3, i64 22466, i64 [[CAST_SRC_ADDR]]) ] void manual(Test *out, Test *in) { out->manual = in->manual; } // CHECK-AUTHENTICATED-SEL: define void @manual -// CHECK-AUTHENTICATED-SEL: [[DST_DESCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_DST_ADDR:%.*]], i64 22467) -// CHECK-AUTHENTICATED-SEL: [[CAST_SRC_ADDR:%.*]] = ptrtoint ptr [[SRC_ADDR:%.*]] to i64 -// CHECK-AUTHENTICATED-SEL: [[SRC_DESCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_SRC_ADDR]], i64 22467) +// CHECK-AUTHENTICATED-SEL: [[V0:%.*]] = load ptr, ptr %out.addr +// CHECK-AUTHENTICATED-SEL: [[SRC_ADDR:%.*]] = getelementptr inbounds i8, ptr [[V0]], i64 {{%.*}} +// CHECK-AUTHENTICATED-SEL: [[V1:%.*]] = load ptr, ptr %in.addr +// CHECK-AUTHENTICATED-SEL: [[DST_ADDR:%.*]] = getelementptr inbounds i8, ptr [[V1]], i64 {{%.*}} +// CHECK-AUTHENTICATED-SEL: [[CAST_DST_ADDR:%.*]] = ptrtoint ptr [[DST_ADDR]] to i64 +// CHECK-AUTHENTICATED-SEL: [[CAST_SRC_ADDR:%.*]] = ptrtoint ptr [[SRC_ADDR]] to i64 // CHECK-AUTHENTICATED-SEL: [[SRC_SEL:%.*]] = ptrtoint ptr [[SRC_SEL_ADDR:%.*]] to i64 -// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[SRC_SEL]], i32 3, i64 [[DST_DESCRIMINATOR]], i32 3, i64 [[SRC_DESCRIMINATOR]]) +// CHECK-AUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[SRC_SEL]]) [ "ptrauth"(i64 3, i64 22467, i64 [[CAST_DST_ADDR]]), "ptrauth"(i64 3, i64 22467, i64 [[CAST_SRC_ADDR]]) ] // CHECK-UNAUTHENTICATED-SEL: define void @manual -// CHECK-UNAUTHENTICATED-SEL: [[DST_DESCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_DST_ADDR:%.*]], i64 22467) -// CHECK-UNAUTHENTICATED-SEL: [[CAST_SRC_ADDR:%.*]] = ptrtoint ptr [[SRC_ADDR:%.*]] to i64 -// CHECK-UNAUTHENTICATED-SEL: [[SRC_DESCRIMINATOR:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[CAST_SRC_ADDR]], i64 22467) +// CHECK-UNAUTHENTICATED-SEL: [[V0:%.*]] = load ptr, ptr %out.addr +// CHECK-UNAUTHENTICATED-SEL: [[SRC_ADDR:%.*]] = getelementptr inbounds i8, ptr [[V0]], i64 {{%.*}} +// CHECK-UNAUTHENTICATED-SEL: [[V1:%.*]] = load ptr, ptr %in.addr +// CHECK-UNAUTHENTICATED-SEL: [[DST_ADDR:%.*]] = getelementptr inbounds i8, ptr [[V1]], i64 {{%.*}} +// CHECK-UNAUTHENTICATED-SEL: [[CAST_DST_ADDR:%.*]] = ptrtoint ptr [[DST_ADDR]] to i64 +// CHECK-UNAUTHENTICATED-SEL: [[CAST_SRC_ADDR:%.*]] = ptrtoint ptr [[SRC_ADDR]] to i64 // CHECK-UNAUTHENTICATED-SEL: [[SRC_SEL:%.*]] = ptrtoint ptr [[SRC_SEL_ADDR:%.*]] to i64 -// CHECK-UNAUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[SRC_SEL]], i32 3, i64 [[DST_DESCRIMINATOR]], i32 3, i64 [[SRC_DESCRIMINATOR]]) +// CHECK-UNAUTHENTICATED-SEL: {{%.*}} = call i64 @llvm.ptrauth.resign(i64 [[SRC_SEL]]) [ "ptrauth"(i64 3, i64 22467, i64 [[CAST_DST_ADDR]]), "ptrauth"(i64 3, i64 22467, i64 [[CAST_SRC_ADDR]]) ] } diff --git a/clang/test/Sema/ptrauth-blend.c b/clang/test/Sema/ptrauth-blend.c new file mode 100644 index 0000000000000..dc3359b718cf4 --- /dev/null +++ b/clang/test/Sema/ptrauth-blend.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -S -verify -fptrauth-intrinsics %s + +typedef __UINTPTR_TYPE__ uintptr_t; + +void callee(uintptr_t disc); + +uintptr_t test_blend_can_only_be_used_as_argument_of_ptrauth_intrinsic(int *dp) { + (void)__builtin_ptrauth_blend_discriminator(dp, 1); // expected-error {{Standalone blend builtin is not supported}} + uintptr_t tmp1 = __builtin_ptrauth_blend_discriminator(dp, 2); // expected-error {{Standalone blend builtin is not supported}} + int *tmp2 = __builtin_ptrauth_sign_unauthenticated(dp, 0, tmp1); + callee(__builtin_ptrauth_blend_discriminator(dp, 3)); // expected-error {{Standalone blend builtin is not supported}} + return __builtin_ptrauth_blend_discriminator(dp, 4); // expected-error {{Standalone blend builtin is not supported}} +} diff --git a/libcxxabi/src/cxa_personality.cpp b/libcxxabi/src/cxa_personality.cpp index b7eb0f23dbe06..25125d14120a1 100644 --- a/libcxxabi/src/cxa_personality.cpp +++ b/libcxxabi/src/cxa_personality.cpp @@ -606,13 +606,11 @@ set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context, auto stackPointer = _Unwind_GetGR(context, UNW_REG_SP); // We manually re-sign the IP as the __ptrauth qualifiers cannot // express the required relationship with the destination address - const auto existingDiscriminator = - ptrauth_blend_discriminator(&results.landingPad, - __ptrauth_scan_results_landingpad_disc); unw_word_t newIP /* opaque __ptrauth(ptrauth_key_return_address, stackPointer, 0) */ = (unw_word_t)ptrauth_auth_and_resign(*(void* const*)&results.landingPad, __ptrauth_scan_results_landingpad_key, - existingDiscriminator, + ptrauth_blend_discriminator(&results.landingPad, + __ptrauth_scan_results_landingpad_disc), ptrauth_key_return_address, stackPointer); _Unwind_SetIP(context, newIP); @@ -974,17 +972,13 @@ using __cxa_catch_temp_type = decltype(__cxa_exception::catchTemp); static inline void set_landing_pad(scan_results& results, const __cxa_catch_temp_type& source) { #if __has_feature(ptrauth_calls) - const uintptr_t sourceDiscriminator = - ptrauth_blend_discriminator(&source, __ptrauth_cxxabi_catch_temp_disc); - const uintptr_t targetDiscriminator = - ptrauth_blend_discriminator(&results.landingPad, - __ptrauth_scan_results_landingpad_disc); uintptr_t reauthenticatedLandingPad = (uintptr_t)ptrauth_auth_and_resign(*reinterpret_cast(&source), __ptrauth_cxxabi_catch_temp_key, - sourceDiscriminator, + ptrauth_blend_discriminator(&source, __ptrauth_cxxabi_catch_temp_disc), __ptrauth_scan_results_landingpad_key, - targetDiscriminator); + ptrauth_blend_discriminator(&results.landingPad, + __ptrauth_scan_results_landingpad_disc)); memmove(reinterpret_cast(&results.landingPad), reinterpret_cast(&reauthenticatedLandingPad), sizeof(reauthenticatedLandingPad)); @@ -996,17 +990,13 @@ static inline void set_landing_pad(scan_results& results, static inline void get_landing_pad(__cxa_catch_temp_type &dest, const scan_results &results) { #if __has_feature(ptrauth_calls) - const uintptr_t sourceDiscriminator = - ptrauth_blend_discriminator(&results.landingPad, - __ptrauth_scan_results_landingpad_disc); - const uintptr_t targetDiscriminator = - ptrauth_blend_discriminator(&dest, __ptrauth_cxxabi_catch_temp_disc); uintptr_t reauthenticatedPointer = (uintptr_t)ptrauth_auth_and_resign(*reinterpret_cast(&results.landingPad), __ptrauth_scan_results_landingpad_key, - sourceDiscriminator, + ptrauth_blend_discriminator(&results.landingPad, + __ptrauth_scan_results_landingpad_disc), __ptrauth_cxxabi_catch_temp_key, - targetDiscriminator); + ptrauth_blend_discriminator(&dest, __ptrauth_cxxabi_catch_temp_disc)); memmove(reinterpret_cast(&dest), reinterpret_cast(&reauthenticatedPointer), sizeof(reauthenticatedPointer)); diff --git a/libunwind/src/DwarfParser.hpp b/libunwind/src/DwarfParser.hpp index 2b04ae2831f9a..da50c6cbfcff8 100644 --- a/libunwind/src/DwarfParser.hpp +++ b/libunwind/src/DwarfParser.hpp @@ -397,18 +397,19 @@ const char *CFI_Parser::parseCIE(A &addressSpace, pint_t cie, // schema. If we could guarantee the encoding of the personality we // could avoid this by simply giving resultAddr the correct ptrauth // schema and performing an assignment. + void *signedPtr = ptrauth_auth_and_resign( + (void *)personality, ptrauth_key_function_pointer, #if defined(__arm64e__) - const auto oldDiscriminator = resultAddr; + resultAddr, #else - const auto oldDiscriminator = ptrauth_blend_discriminator( - (void *)resultAddr, __ptrauth_unwind_pauthtest_personality_disc); + ptrauth_blend_discriminator( + (void *)resultAddr, + __ptrauth_unwind_pauthtest_personality_disc), #endif - const auto discriminator = ptrauth_blend_discriminator( - &cieInfo->personality, - __ptrauth_unwind_cie_info_personality_disc); - void *signedPtr = ptrauth_auth_and_resign( - (void *)personality, ptrauth_key_function_pointer, - oldDiscriminator, ptrauth_key_function_pointer, discriminator); + ptrauth_key_function_pointer, + ptrauth_blend_discriminator( + &cieInfo->personality, + __ptrauth_unwind_cie_info_personality_disc)); personality = (pint_t)signedPtr; } #endif diff --git a/llvm/docs/GlobalISel/GenericOpcode.rst b/llvm/docs/GlobalISel/GenericOpcode.rst index 329d9d13ebddd..71f16645d5a58 100644 --- a/llvm/docs/GlobalISel/GenericOpcode.rst +++ b/llvm/docs/GlobalISel/GenericOpcode.rst @@ -67,6 +67,8 @@ The signed address of a global value. Operands: address to be signed (pointer), key (32-bit imm), address for address discrimination (zero if not needed) and an extra discriminator (64-bit imm). +FIXME + .. code-block:: none %0:_(p0) = G_PTRAUTH_GLOBAL_VALUE %1:_(p0), s32, %2:_(p0), s64 diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 02865f8a29c67..023a1f85c48be 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -5309,28 +5309,20 @@ authentication signature embedded into some bits, as described in the `Pointer Authentication `__ document. A '``ptrauth``' constant is simply a constant equivalent to the -``llvm.ptrauth.sign`` intrinsic, potentially fed by a discriminator -``llvm.ptrauth.blend`` if needed. +``llvm.ptrauth.sign`` intrinsic. Its type is the same as the first argument. An integer constant discriminator and an address discriminator may be optionally specified. Otherwise, they have values ``i64 0`` and ``ptr null``. -If the address discriminator is ``null`` then the expression is equivalent to +The expression '``ptrauth(ptr CST, i32 KEY, i64 DISC, ptr ADDRDISC)``' is +equivalent to .. code-block:: llvm - %tmp = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr CST to i64), i32 KEY, i64 DISC) + %tmp = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr CST to i64)) [ "ptrauth"(i64 KEY, i64 DISC, i64 ptrtoint (ptr ADDRDISC to i64)) ] %val = inttoptr i64 %tmp to ptr -Otherwise, the expression is equivalent to: - -.. code-block:: llvm - - %tmp1 = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr ADDRDISC to i64), i64 DISC) - %tmp2 = call i64 @llvm.ptrauth.sign(i64 ptrtoint (ptr CST to i64), i32 KEY, i64 %tmp1) - %val = inttoptr i64 %tmp2 to ptr - If the deactivation symbol operand ``DS`` has a non-null value, the semantics are as if a :ref:`deactivation-symbol operand bundle ` were added to the ``llvm.ptrauth.sign`` intrinsic @@ -5338,6 +5330,11 @@ calls above, with ``DS`` as the only operand. .. _constantexprs: +That is, the first operand of '``ptrauth``' constant is the pointer to be +signed (the only argument of '``@llvm.ptrauth.sign``') and all the remaining +operands have the same interpretation as in ``"ptrauth"`` call operand bundle +(with trivial type conversion). + Constant Expressions -------------------- diff --git a/llvm/docs/PointerAuth.md b/llvm/docs/PointerAuth.md index 84e0af7577c7d..17c8d912bf125 100644 --- a/llvm/docs/PointerAuth.md +++ b/llvm/docs/PointerAuth.md @@ -16,8 +16,9 @@ For more details, see the clang documentation page for At the IR level, it is represented using: * a [set of intrinsics](#intrinsics) (to sign/authenticate pointers) +* a [call operand bundle](#operand-bundle) (to authenticate called pointers + and to pass signing schema description to the intrinsics) * a [signed pointer constant](#constant) (to sign globals) -* a [call operand bundle](#operand-bundle) (to authenticate called pointers) * a [set of function attributes](#function-attributes) (to describe what pointers are signed and how, to control implicit codegen in the backend, as well as preserve invariants in the mid-level optimizer) @@ -31,6 +32,54 @@ This support is used to implement the Darwin arm64e ABI, as well as the ## LLVM IR Representation +### Operand Bundle + +Most pointer authentication intrinsics, as well as authenticated indirect calls, +are parameterized by signing schema description expressed by a `ptrauth` call +operand bundle. A `ptrauth` call operand bundle has one or more `i64` operands, +whose interpretation is target-dependent: `"ptrauth"(i64 op1, i64 op2, ...)`. +A particular target may require some of the operands to be integer constants. + +#### Authenticated indirect calls + +Function pointers used as indirect call targets can be signed when materialized, +and authenticated before calls. This can be accomplished with the +[`llvm.ptrauth.auth`](#llvm-ptrauth-auth) intrinsic, feeding its result to +an indirect call. + +However, that exposes the intermediate, unauthenticated pointer, e.g., if it +gets spilled to the stack. An attacker can then overwrite the pointer in +memory, negating the security benefit provided by pointer authentication. +To prevent that, the `ptrauth` operand bundle may be used: it guarantees that +the intermediate call target is kept in a register and never stored to memory. +This hardening benefit is similar to that provided by +[`llvm.ptrauth.resign`](#llvm-ptrauth-resign)). + +Concretely: + +```llvm +define void @f(ptr %fp) { + call void %fp() [ "ptrauth"(i64 , i64 , ...) ] + ret void +} +``` + +is functionally equivalent to: + +```llvm +define void @f(ptr %fp) { + %fp_i = ptrtoint ptr %fp to i64 + %fp_auth = call i64 @llvm.ptrauth.auth(i64 %fp_i) [ "ptrauth"(i64 , i64 , ...) ] + %fp_auth_p = inttoptr i64 %fp_auth to ptr + call void %fp_auth_p() + ret void +} +``` + +but with the added guarantee that `%fp_i`, `%fp_auth`, and `%fp_auth_p` +are not stored to (and reloaded from) memory. + + ### Intrinsics These intrinsics are provided by LLVM to expose pointer authentication @@ -42,7 +91,7 @@ operations. ##### Syntax: ```llvm -declare i64 @llvm.ptrauth.sign(i64 , i32 , i64 ) +declare i64 @llvm.ptrauth.sign(i64 ) [ "ptrauth"(...) ] ``` ##### Overview: @@ -53,20 +102,19 @@ The '`llvm.ptrauth.sign`' intrinsic signs a raw pointer. ##### Arguments: The `value` argument is the raw pointer value to be signed. -The `key` argument is the identifier of the key to be used to generate the -signed value. -The `discriminator` argument is the additional diversity data to be used as a -discriminator (an integer, an address, or a blend of the two). + +The `ptrauth` call operand bundle describes the signing schema in a +target-specific way. ##### Semantics: -The '`llvm.ptrauth.sign`' intrinsic implements the `sign`_ operation. +The '`llvm.ptrauth.sign`' intrinsic implements the `sign` operation. It returns a signed value. If `value` is already a signed value, the behavior is undefined. -If `value` is not a pointer value for which `key` is appropriate, the -behavior is undefined. +If `value` is not a pointer value for which the chosen signing schema is +appropriate, the behavior is undefined. #### '`llvm.ptrauth.auth`' @@ -74,7 +122,7 @@ behavior is undefined. ##### Syntax: ```llvm -declare i64 @llvm.ptrauth.auth(i64 , i32 , i64 ) +declare i64 @llvm.ptrauth.auth(i64 ) [ "ptrauth"(...) ] ``` ##### Overview: @@ -84,16 +132,15 @@ The '`llvm.ptrauth.auth`' intrinsic authenticates a signed pointer. ##### Arguments: The `value` argument is the signed pointer value to be authenticated. -The `key` argument is the identifier of the key that was used to generate -the signed value. -The `discriminator` argument is the additional diversity data to be used as a -discriminator. + +The `ptrauth` call operand bundle describes the signing schema that was used +to generate the signed value in a target-specific way. ##### Semantics: -The '`llvm.ptrauth.auth`' intrinsic implements the `auth`_ operation. +The '`llvm.ptrauth.auth`' intrinsic implements the `auth` operation. It returns a raw pointer value. -If `value` does not have a correct signature for `key` and `discriminator`, +If `value` does not have a correct signature for the signing schema, the intrinsic traps in a target-specific way. @@ -102,7 +149,7 @@ the intrinsic traps in a target-specific way. ##### Syntax: ```llvm -declare i64 @llvm.ptrauth.strip(i64 , i32 ) +declare i64 @llvm.ptrauth.strip(i64 ) [ "ptrauth"(...) ] ``` ##### Overview: @@ -114,27 +161,28 @@ possibly-signed pointer. ##### Arguments: The `value` argument is the signed pointer value to be stripped. -The `key` argument is the identifier of the key that was used to generate -the signed value. + +The `ptrauth` call operand bundle describes the signing schema that was used +to generate the signed value in a target-specific way. ##### Semantics: -The '`llvm.ptrauth.strip`' intrinsic implements the `strip`_ operation. +The '`llvm.ptrauth.strip`' intrinsic implements the `strip` operation. It returns a raw pointer value. It does **not** check that the signature is valid. -`key` should identify a key that is appropriate for `value`, as defined -by the target-specific [keys](#keys)). +The signing schema should be appropriate for `value`, as defined by the +particular target. -If `value` is a raw pointer value, it is returned as-is (provided the `key` +If `value` is a raw pointer value, it is returned as-is (provided the schema is appropriate for the pointer). -If `value` is not a pointer value for which `key` is appropriate, the +If `value` is not a pointer value for which the schema is appropriate, the behavior is target-specific. -If `value` is a signed pointer value, but `key` does not identify the -same key that was used to generate `value`, the behavior is -target-specific. +If `value` is a signed pointer value, but the signing schema described by the +`ptrauth` bundle passed to this call is not compatible with the schema that was +used to generate `value`, the behavior is target-specific. #### '`llvm.ptrauth.resign`' @@ -142,35 +190,31 @@ target-specific. ##### Syntax: ```llvm -declare i64 @llvm.ptrauth.resign(i64 , - i32 , i64 , - i32 , i64 ) +declare i64 @llvm.ptrauth.resign(i64 ) [ "ptrauth"(), "ptrauth"() ] ``` ##### Overview: The '`llvm.ptrauth.resign`' intrinsic re-signs a signed pointer using -a different key and diversity data. +a different signing schema. ##### Arguments: -The `value` argument is the signed pointer value to be authenticated. -The `old key` argument is the identifier of the key that was used to generate -the signed value. -The `old discriminator` argument is the additional diversity data to be used -as a discriminator in the auth operation. -The `new key` argument is the identifier of the key to use to generate the +The `value` argument is the signed pointer value to be re-signed. + +The first `ptrauth` bundle specifies the signing schema that was used to +generate the signed value. + +The second `ptrauth` bundle specifies the signing schema to use to generate the resigned value. -The `new discriminator` argument is the additional diversity data to be used -as a discriminator in the sign operation. ##### Semantics: -The '`llvm.ptrauth.resign`' intrinsic performs a combined `auth`_ and `sign`_ +The '`llvm.ptrauth.resign`' intrinsic performs a combined `auth` and `sign` operation, without exposing the intermediate raw pointer. It returns a signed pointer value. -If `value` does not have a correct signature for `old key` and -`old discriminator`, the intrinsic traps in a target-specific way. +If `value` does not have a correct signature for the original signing schema, +the intrinsic traps in a target-specific way. #### '`llvm.ptrauth.sign_generic`' @@ -203,32 +247,6 @@ As opposed to [`llvm.ptrauth.sign`](#llvm-ptrauth-sign), it does not interpret `value` as a pointer value. Instead, it is an arbitrary data value. -#### '`llvm.ptrauth.blend`' - -##### Syntax: - -```llvm -declare i64 @llvm.ptrauth.blend(i64
, i64 ) -``` - -##### Overview: - -The '`llvm.ptrauth.blend`' intrinsic blends a pointer address discriminator -with a small integer discriminator to produce a new "blended" discriminator. - -##### Arguments: - -The `address discriminator` argument is a pointer value. -The `integer discriminator` argument is a small integer, as specified by the -target. - -##### Semantics: - -The '`llvm.ptrauth.blend`' intrinsic combines a small integer discriminator -with a pointer address discriminator, in a way that is specified by the target -implementation. - - ### Constant [Intrinsics](#intrinsics) can be used to produce signed pointers dynamically, @@ -250,45 +268,6 @@ is equivalent to: %signedval = call i64 @llvm.ptrauth.sign(ptr CST, i32 KEY, i64 %disc) ``` -### Operand Bundle - -Function pointers used as indirect call targets can be signed when materialized, -and authenticated before calls. This can be accomplished with the -[`llvm.ptrauth.auth`](#llvm-ptrauth-auth) intrinsic, feeding its result to -an indirect call. - -However, that exposes the intermediate, unauthenticated pointer, e.g., if it -gets spilled to the stack. An attacker can then overwrite the pointer in -memory, negating the security benefit provided by pointer authentication. -To prevent that, the `ptrauth` operand bundle may be used: it guarantees that -the intermediate call target is kept in a register and never stored to memory. -This hardening benefit is similar to that provided by -[`llvm.ptrauth.resign`](#llvm-ptrauth-resign)). - -Concretely: - -```llvm -define void @f(void ()* %fp) { - call void %fp() [ "ptrauth"(i32 , i64 ) ] - ret void -} -``` - -is functionally equivalent to: - -```llvm -define void @f(void ()* %fp) { - %fp_i = ptrtoint void ()* %fp to i64 - %fp_auth = call i64 @llvm.ptrauth.auth(i64 %fp_i, i32 , i64 ) - %fp_auth_p = inttoptr i64 %fp_auth to void ()* - call void %fp_auth_p() - ret void -} -``` - -but with the added guarantee that `%fp_i`, `%fp_auth`, and `%fp_auth_p` -are not stored to (and reloaded from) memory. - ### Function Attributes @@ -321,6 +300,20 @@ authentication primitives, based on Armv8.3-A instructions. The Armv8.3-A architecture extension defines the PAuth feature, which provides support for instructions that manipulate Pointer Authentication Codes (PAC). +Sign and auth operations are parameterized by a constant key identifier and +a 64-bit discriminator value which is computed according to signing schema. + +On AArch64, `ptrauth` bundle may have either one or three operands, depending +on the callee. The former operand is always a constant integer denoting the +[key identifier](#keys) and the rest operands describe the discriminator: +* `"ptrauth"(i64 )`: the operation uses the key `` and the + discriminator is not applicable. This form is used by `@llvm.ptrauth.strip` + intrinsic. +* `"ptrauth"(i64 , i64 , i64 %addr_modif)`: the discriminator + to be used is computed by [blending](#blend-operation) an integer modifier + into an address modifier. `const_modif` must be unsigned 16-bit integer + constant and zero value means `addr_modif` is used without any blending. + #### Keys 5 keys are supported by the PAuth feature. @@ -334,6 +327,13 @@ constructs: used implicitly, to implement the [`llvm.ptrauth.sign_generic`](#llvm-ptrauth-sign-generic) intrinsic. +#### Blend operation + +The semantics of the blend operation are specified by the ABI. In both the +ELF PAuth ABI Extension and arm64e, it's a `MOVK` into the high 16 bits. +Consequently, this limits the width of the integer discriminator used in blends +to 16 bits. + #### Instructions The IR [Intrinsics](#intrinsics) described above map onto these @@ -341,10 +341,6 @@ instructions as such: * [`llvm.ptrauth.sign`](#llvm-ptrauth-sign): `PAC{I,D}{A,B}{Z,SP,}` * [`llvm.ptrauth.auth`](#llvm-ptrauth-auth): `AUT{I,D}{A,B}{Z,SP,}` * [`llvm.ptrauth.strip`](#llvm-ptrauth-strip): `XPAC{I,D}` -* [`llvm.ptrauth.blend`](#llvm-ptrauth-blend): The semantics of the blend - operation are specified by the ABI. In both the ELF PAuth ABI Extension and - arm64e, it's a `MOVK` into the high 16 bits. Consequently, this limits - the width of the integer discriminator used in blends to 16 bits. * [`llvm.ptrauth.sign_generic`](#llvm-ptrauth-sign-generic): `PACGA` * [`llvm.ptrauth.resign`](#llvm-ptrauth-resign): `AUT*+PAC*`. These are represented as a single pseudo-instruction in the backend to guarantee that diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index 83dd1eba876e6..047fa6e94b70f 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -1755,10 +1755,16 @@ LLVM_C_ABI unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy); */ LLVM_C_ABI LLVMValueRef LLVMGetConstantPtrAuthPointer(LLVMValueRef PtrAuth); +LLVM_C_ABI unsigned LLVMGetConstantPtrAuthSchemaSize(LLVMValueRef PtrAuth); + +LLVM_C_ABI LLVMValueRef +LLVMGetConstantPtrAuthSchemaOperand(LLVMValueRef PtrAuth, unsigned Idx); + /** * Get the key value for the associated ConstantPtrAuth constant. * * @see llvm::ConstantPtrAuth::getKey + * @deprecated */ LLVM_C_ABI LLVMValueRef LLVMGetConstantPtrAuthKey(LLVMValueRef PtrAuth); @@ -1766,6 +1772,7 @@ LLVM_C_ABI LLVMValueRef LLVMGetConstantPtrAuthKey(LLVMValueRef PtrAuth); * Get the discriminator value for the associated ConstantPtrAuth constant. * * @see llvm::ConstantPtrAuth::getDiscriminator + * @deprecated */ LLVM_C_ABI LLVMValueRef LLVMGetConstantPtrAuthDiscriminator(LLVMValueRef PtrAuth); @@ -1775,10 +1782,14 @@ LLVMGetConstantPtrAuthDiscriminator(LLVMValueRef PtrAuth); * constant. * * @see llvm::ConstantPtrAuth::getAddrDiscriminator + * @deprecated */ LLVM_C_ABI LLVMValueRef LLVMGetConstantPtrAuthAddrDiscriminator(LLVMValueRef PtrAuth); +LLVM_C_ABI LLVMValueRef +LLVMGetConstantPtrAuthDeactivationSymbol(LLVMValueRef PtrAuth); + /** * @} */ @@ -2535,10 +2546,12 @@ LLVM_C_ABI LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, * Create a ConstantPtrAuth constant with the given values. * * @see llvm::ConstantPtrAuth::get() + * FIXME Compatibility? */ -LLVM_C_ABI LLVMValueRef LLVMConstantPtrAuth(LLVMValueRef Ptr, LLVMValueRef Key, - LLVMValueRef Disc, - LLVMValueRef AddrDisc); +LLVM_C_ABI LLVMValueRef LLVMConstantPtrAuth(LLVMValueRef Ptr, + LLVMValueRef *Schema, + unsigned SchemaSize, + LLVMValueRef DeactivationSymbol); /** * @} diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h index 2451d588bdbf7..304a67e0c80ed 100644 --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -436,9 +436,10 @@ enum ConstantsCodes { // asmstr,conststr] CST_CODE_CE_GEP_WITH_INRANGE = 31, // [opty, flags, range, n x operands] CST_CODE_CE_GEP = 32, // [opty, flags, n x operands] - CST_CODE_PTRAUTH = 33, // [ptr, key, disc, addrdisc] - CST_CODE_PTRAUTH2 = 34, // [ptr, key, disc, addrdisc, + CST_CODE_PTRAUTH_OLD = 33, // [ptr, key, disc, addrdisc] + CST_CODE_PTRAUTH_OLD2 = 34, // [ptr, key, disc, addrdisc, // deactivation_symbol] + CST_CODE_PTRAUTH3 = 35, // [ptr, n x i64, deactivation_symbol] }; /// CastOpcodes - These are values used in the bitcode files to encode which diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h index fea900f37ec74..205aba89bc4aa 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h @@ -98,8 +98,7 @@ class LLVM_ABI CallLowering { }; struct PtrAuthInfo { - uint64_t Key; - Register Discriminator; + SmallVector Operands; }; struct CallLoweringInfo { diff --git a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 9d6038db4391f..c55f50b06ea22 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -600,6 +600,9 @@ class IRTranslator : public MachineFunctionPass { Intrinsic::ID ID, MachineIRBuilder &MIRBuilder); + bool translatePtrAuthIntrinsic(const CallInst &CI, unsigned Opcode, + MachineIRBuilder &MIRBuilder); + /// @} // Builder for machine instruction a la IRBuilder. diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index 5f3f1d386569c..3d64cffc99fa1 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -982,9 +982,8 @@ class LLVM_ABI MachineIRBuilder { /// Build and insert G_PTRAUTH_GLOBAL_VALUE /// /// \return a MachineInstrBuilder for the newly created instruction. - MachineInstrBuilder buildConstantPtrAuth(const DstOp &Res, - const ConstantPtrAuth *CPA, - Register Addr, Register AddrDisc); + MachineInstrBuilder buildConstantPtrAuth(const DstOp &Res, Register Ptr, + Register Schema); /// Build and insert \p Res = COPY Op /// diff --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h index b32f3dacbb3a4..eebbb69638ccd 100644 --- a/llvm/include/llvm/CodeGen/ISDOpcodes.h +++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h @@ -94,11 +94,23 @@ enum NodeType { BlockAddress, /// A ptrauth constant. - /// ptr, key, addr-disc, disc + /// ptr, bundle_token /// Note that the addr-disc can be a non-constant value, to allow representing /// a constant global address signed using address-diversification, in code. PtrAuthGlobalAddress, + /// A temporary node representing the operands of "ptrauth" bundle in the + /// original LLVM IR. + /// It has target-dependent number of i64 operands and produces a token value + /// passed as input operand to one of PtrAuth(Auth|Sign|Resign|Strip) nodes. + PtrAuthBundle, + + /// Various PtrAuth operations. + PtrAuthAuth, + PtrAuthSign, + PtrAuthResign, + PtrAuthStrip, + /// The address of the GOT GLOBAL_OFFSET_TABLE, diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h index 149366c69bdcc..32d9598a7f2d3 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -40,6 +40,7 @@ #include "llvm/CodeGenTypes/MachineValueType.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/CallingConv.h" +#include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" @@ -4609,8 +4610,29 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase { /// Return true if the target supports kcfi operand bundles. virtual bool supportKCFIBundles() const { return false; } - /// Return true if the target supports ptrauth operand bundles. - virtual bool supportPtrAuthBundles() const { return false; } +protected: + /// Perform target-specific validation of PtrAuth schema descriptions that + /// is not covered by Verifier but relied upon by the backend. + virtual std::optional + validatePtrAuthSchema(const Value &V) const { + return "this target does not support pointer authentication"; + } + +public: + /// Convenience function to report fatal error if user-provided IR violates + /// the assumptions relied upon by the backend. + /// + /// This function is intended to handle possible invalid user input and thus + /// always performs the check, whether the assertions are enabled or not. + void reportFatalErrorOnInvalidPtrAuthSchema(const Value &V) const { + assert(isa(V) || isa(V)); + if (auto Error = validatePtrAuthSchema(V)) { + errs() << "Ptrauth schema violates target-specific constraints:\n"; + V.print(errs()); + errs() << "\n"; + reportFatalUsageError(("Invalid ptrauth schema: " + *Error).c_str()); + } + } /// Perform necessary initialization to handle a subset of CSRs explicitly /// via copies. This function is called at the beginning of instruction @@ -4720,8 +4742,7 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase { /// pointer-authenticating indirect calls. It is equivalent to the "ptrauth" /// operand bundle found on the call instruction, if any. struct PtrAuthInfo { - uint64_t Key; - SDValue Discriminator; + SmallVector Operands; }; /// This structure contains all information that is necessary for lowering diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h index e3f2eb9fa44b8..7b67c763da9e5 100644 --- a/llvm/include/llvm/IR/Constants.h +++ b/llvm/include/llvm/IR/Constants.h @@ -1033,20 +1033,19 @@ class ConstantPtrAuth final : public Constant { friend struct ConstantPtrAuthKeyType; friend class Constant; - constexpr static IntrusiveOperandsAllocMarker AllocMarker{5}; - - ConstantPtrAuth(Constant *Ptr, ConstantInt *Key, ConstantInt *Disc, - Constant *AddrDisc, Constant *DeactivationSymbol); - - void *operator new(size_t s) { return User::operator new(s, AllocMarker); } + ConstantPtrAuth(Constant *Ptr, ArrayRef Schema, + Constant *DeactivationSymbol, AllocInfo AllocInfo); void destroyConstantImpl(); Value *handleOperandChangeImpl(Value *From, Value *To); public: /// Return a pointer signed with the specified parameters. - LLVM_ABI static ConstantPtrAuth *get(Constant *Ptr, ConstantInt *Key, - ConstantInt *Disc, Constant *AddrDisc, + // LLVM_ABI static ConstantPtrAuth *get(Constant *Ptr, ConstantArray *Schema, + // Constant *DeactivationSymbol); + + LLVM_ABI static ConstantPtrAuth *get(Constant *Ptr, + ArrayRef SchemaArgs, Constant *DeactivationSymbol); /// Produce a new ptrauth expression signing the given value using @@ -1059,28 +1058,40 @@ class ConstantPtrAuth final : public Constant { /// The pointer that is signed in this ptrauth signed pointer. Constant *getPointer() const { return cast(Op<0>().get()); } + ArrayRef getSchema() const { + return ArrayRef(op_begin() + 2, op_end()); + } + /// The Key ID, an i32 constant. - ConstantInt *getKey() const { return cast(Op<1>().get()); } + ConstantInt *getKey() const { + // FIXME remove this + return cast(getSchema()[0]); + } /// The integer discriminator, an i64 constant, or 0. ConstantInt *getDiscriminator() const { - return cast(Op<2>().get()); + // FIXME remove this + return cast(getSchema()[1]); } /// The address discriminator if any, or the null constant. /// If present, this must be a value equivalent to the storage location of /// the only global-initializer user of the ptrauth signed pointer. + // FIXME Remove Constant *getAddrDiscriminator() const { - return cast(Op<3>().get()); + // FIXME remove this + return cast(getSchema()[2]); } /// Whether there is any non-null address discriminator. + // FIXME Remove bool hasAddressDiscriminator() const { + // FIXME remove this return !getAddrDiscriminator()->isNullValue(); } Constant *getDeactivationSymbol() const { - return cast(Op<4>().get()); + return cast(Op<1>().get()); } /// A constant value for the address discriminator which has special @@ -1094,14 +1105,15 @@ class ConstantPtrAuth final : public Constant { /// These discriminators can't be used in real pointer-auth values; they /// can only be used in "prototype" values that indicate how some real /// schema is supposed to be produced. + // FIXME Rethink? LLVM_ABI bool hasSpecialAddressDiscriminator(uint64_t Value) const; /// Check whether an authentication operation with key \p Key and (possibly /// blended) discriminator \p Discriminator is known to be compatible with /// this ptrauth signed pointer. - LLVM_ABI bool isKnownCompatibleWith(const Value *Key, - const Value *Discriminator, - const DataLayout &DL) const; + // FIXME: LLVM_ABI + bool isKnownCompatibleWith(ArrayRef BundleOperands, + const DataLayout &DL) const; /// Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Value *V) { @@ -1111,7 +1123,7 @@ class ConstantPtrAuth final : public Constant { template <> struct OperandTraits - : public FixedNumOperandTraits {}; + : public VariadicOperandTraits {}; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantPtrAuth, Constant) diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index 8f3cc54747074..91c13b061f9fd 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -2858,45 +2858,35 @@ def int_vector_partial_reduce_fadd : DefaultAttrsIntrinsic<[LLVMMatchType<0>], //===----------------- Pointer Authentication Intrinsics ------------------===// // -// Sign an unauthenticated pointer using the specified key and discriminator, -// passed in that order. -// Returns the first argument, with some known bits replaced with a signature. +// Sign an unauthenticated pointer using the specified signing schema. +// Requires exactly one "ptrauth" call operand bundle specifying the schema. +// Returns the first argument, with embedded signature. def int_ptrauth_sign : - DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty], - [IntrNoMem, ImmArg>]>; + DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>; -// Authenticate a signed pointer, using the specified key and discriminator. -// Returns the first argument, with the signature bits removed. +// Authenticate a signed pointer, using the specified signing schema. +// Requires exactly one "ptrauth" call operand bundle specifying the schema. +// Returns the first argument, with the signature removed. // The signature must be valid. -def int_ptrauth_auth : Intrinsic<[llvm_i64_ty], - [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty], - [IntrNoMem,ImmArg>]>; +def int_ptrauth_auth : Intrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>; // Authenticate a signed pointer and resign it. -// The second (key) and third (discriminator) arguments specify the signing -// schema used for authenticating. -// The fourth and fifth arguments specify the schema used for signing. +// Requires exactly two "ptrauth" call operand bundles specifying the signing +// schemas. +// The first operand bundle specifies the schema used for authenticating. +// The second operand bundle specifies the schema used for signing. // The signature must be valid. // This is a combined form of @llvm.ptrauth.sign and @llvm.ptrauth.auth, with // an additional integrity guarantee on the intermediate value. -def int_ptrauth_resign : Intrinsic<[llvm_i64_ty], - [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty, - llvm_i32_ty, llvm_i64_ty], - [IntrNoMem, ImmArg>, - ImmArg>]>; +def int_ptrauth_resign : Intrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>; // Strip the embedded signature out of a signed pointer. -// The second argument specifies the key. +// Requires exactly one "ptrauth" call operand bundle carrying a +// target-specific information required to remove the signature. // This behaves like @llvm.ptrauth.auth, but doesn't require the signature to // be valid. def int_ptrauth_strip : - DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty], - [IntrNoMem, ImmArg>]>; - -// Blend a small integer discriminator with an address discriminator, producing -// a new discriminator value. -def int_ptrauth_blend : - DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>; + DefaultAttrsIntrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>; // Compute the signature of a value, using a given discriminator. // This differs from @llvm.ptrauth.sign in that it doesn't embed the computed diff --git a/llvm/include/llvm/IR/User.h b/llvm/include/llvm/IR/User.h index cbb4379b68c41..cc14a3ace35fd 100644 --- a/llvm/include/llvm/IR/User.h +++ b/llvm/include/llvm/IR/User.h @@ -44,6 +44,7 @@ struct OperandTraits; class User : public Value { friend struct HungoffOperandTraits; template friend struct ConstantAggrKeyType; + friend struct ConstantPtrAuthKeyType; LLVM_ATTRIBUTE_ALWAYS_INLINE static void * allocateFixedOperandUser(size_t, unsigned, unsigned); diff --git a/llvm/include/llvm/SandboxIR/Constant.h b/llvm/include/llvm/SandboxIR/Constant.h index 2fe923f6c3866..a677cd68512d4 100644 --- a/llvm/include/llvm/SandboxIR/Constant.h +++ b/llvm/include/llvm/SandboxIR/Constant.h @@ -1362,26 +1362,35 @@ class ConstantPtrAuth final : public Constant { public: /// Return a pointer signed with the specified parameters. - LLVM_ABI static ConstantPtrAuth *get(Constant *Ptr, ConstantInt *Key, - ConstantInt *Disc, Constant *AddrDisc, + LLVM_ABI static ConstantPtrAuth *get(Constant *Ptr, ConstantArray *Schema, Constant *DeactivationSymbol); + LLVM_ABI static ConstantPtrAuth *get(Constant *Ptr, + ArrayRef Schema, + Constant *DeactivationSymbol); + + // ConstantArray *getSchema() const; + /// The pointer that is signed in this ptrauth signed pointer. LLVM_ABI Constant *getPointer() const; /// The Key ID, an i32 constant. + // FIXME Remove LLVM_ABI ConstantInt *getKey() const; /// The integer discriminator, an i64 constant, or 0. + // FIXME Remove LLVM_ABI ConstantInt *getDiscriminator() const; /// The address discriminator if any, or the null constant. /// If present, this must be a value equivalent to the storage location of /// the only global-initializer user of the ptrauth signed pointer. + // FIXME Remove LLVM_ABI Constant *getAddrDiscriminator() const; Constant *getDeactivationSymbol() const; /// Whether there is any non-null address discriminator. + // FIXME Remove bool hasAddressDiscriminator() const { return cast(Val)->hasAddressDiscriminator(); } @@ -1390,6 +1399,7 @@ class ConstantPtrAuth final : public Constant { /// These discriminators can't be used in real pointer-auth values; they /// can only be used in "prototype" values that indicate how some real /// schema is supposed to be produced. + // FIXME Rethink? bool hasSpecialAddressDiscriminator(uint64_t Value) const { return cast(Val)->hasSpecialAddressDiscriminator( Value); @@ -1398,10 +1408,13 @@ class ConstantPtrAuth final : public Constant { /// Check whether an authentication operation with key \p Key and (possibly /// blended) discriminator \p Discriminator is known to be compatible with /// this ptrauth signed pointer. - bool isKnownCompatibleWith(const Value *Key, const Value *Discriminator, + bool isKnownCompatibleWith(ArrayRef BundleOperands, const DataLayout &DL) const { + SmallVector Operands; + for (auto *V : BundleOperands) + Operands.push_back(V->Val); return cast(Val)->isKnownCompatibleWith( - Key->Val, Discriminator->Val, DL); + Operands, DL); } /// Produce a new ptrauth expression signing the given value using diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def index 0d92f50a09d38..9431d2320dbb1 100644 --- a/llvm/include/llvm/Support/TargetOpcodes.def +++ b/llvm/include/llvm/Support/TargetOpcodes.def @@ -331,6 +331,18 @@ HANDLE_TARGET_OPCODE(G_GLOBAL_VALUE) /// Generic ptrauth-signed reference to global value. HANDLE_TARGET_OPCODE(G_PTRAUTH_GLOBAL_VALUE) +/// A temporary instruction representing the operands of "ptrauth" bundle in +/// the original LLVM IR. +/// It has target-dependent number of i64 operands and produces a token value +/// passed as input operand to one of G_PTRAUTH_* instructions. +HANDLE_TARGET_OPCODE(G_PTRAUTH_BUNDLE) + +/// Various PtrAuth operations. +HANDLE_TARGET_OPCODE(G_PTRAUTH_AUTH) +HANDLE_TARGET_OPCODE(G_PTRAUTH_SIGN) +HANDLE_TARGET_OPCODE(G_PTRAUTH_RESIGN) +HANDLE_TARGET_OPCODE(G_PTRAUTH_STRIP) + /// Generic instruction to materialize the address of an object in the constant /// pool. HANDLE_TARGET_OPCODE(G_CONSTANT_POOL) diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td index 1b65b8b73527d..787adcc6b3d40 100644 --- a/llvm/include/llvm/Target/GenericOpcodes.td +++ b/llvm/include/llvm/Target/GenericOpcodes.td @@ -133,7 +133,42 @@ def G_GLOBAL_VALUE : GenericInstruction { def G_PTRAUTH_GLOBAL_VALUE : GenericInstruction { let OutOperandList = (outs type0:$dst); - let InOperandList = (ins unknown:$addr, i32imm:$key, type1:$addrdisc, i64imm:$disc); + let InOperandList = (ins type0:$addr, untyped_imm_0:$schema); + let hasSideEffects = 0; +} + +def G_PTRAUTH_BUNDLE : GenericInstruction { + let OutOperandList = (outs untyped_imm_0:$dst); + let InOperandList = (ins type0:$op1, variable_ops); + let hasSideEffects = 0; + let variadicOpsType = type0; +} + +def G_PTRAUTH_AUTH : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$value, untyped_imm_0:$schema); + // Authentication should not be speculated: moving G_PTRAUTH_AUTH above the + // point where it is known to succeed under correct program operation may + // lead to program crashes. + let hasSideEffects = 1; +} + +def G_PTRAUTH_SIGN : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$value, untyped_imm_0:$schema); + let hasSideEffects = 0; +} + +def G_PTRAUTH_RESIGN : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$value, untyped_imm_0:$old_schema, untyped_imm_0:$new_schema); + // Resign includes authentication and thus should not be speculated. + let hasSideEffects = 1; +} + +def G_PTRAUTH_STRIP : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$value, untyped_imm_0:$schema); let hasSideEffects = 0; } diff --git a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td index a69e089779315..4d000ce1c393e 100644 --- a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td +++ b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td @@ -224,6 +224,12 @@ def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; + // Broadly speaking G_LOAD is equivalent to ISD::LOAD but there are some // complications that tablegen must take care of. For example, Predicates such // as isSignExtLoad require that this is not a perfect 1:1 mapping since a diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td index a9750a5ab03f9..06dfcd5769b04 100644 --- a/llvm/include/llvm/Target/TargetSelectionDAG.td +++ b/llvm/include/llvm/Target/TargetSelectionDAG.td @@ -911,6 +911,24 @@ def convergencectrl_loop : SDNode<"ISD::CONVERGENCECTRL_LOOP", def convergencectrl_glue : SDNode<"ISD::CONVERGENCECTRL_GLUE", SDTypeProfile<0, 1, [SDTCisVT<0, untyped>]>>; +// Pointer Authentication operations. + +def SDTPtrAuthBundle : SDTypeProfile<1, -1, [ + SDTCisVT<0, untyped> +]>; +def SDTPtrAuthOneSchema : SDTypeProfile<1, 2, [ // auth, sign, strip + SDTCisVT<0, i64>, SDTCisVT<1, i64>, SDTCisVT<2, untyped> +]>; +def SDTPtrAuthTwoSchemas : SDTypeProfile<1, 3, [ // resign + SDTCisVT<0, i64>, SDTCisVT<1, i64>, SDTCisVT<2, untyped>, SDTCisVT<3, untyped> +]>; + +def ptrauth_bundle : SDNode<"ISD::PtrAuthBundle", SDTPtrAuthBundle, []>; +def ptrauth_auth : SDNode<"ISD::PtrAuthAuth", SDTPtrAuthOneSchema, []>; +def ptrauth_sign : SDNode<"ISD::PtrAuthSign", SDTPtrAuthOneSchema, []>; +def ptrauth_strip : SDNode<"ISD::PtrAuthStrip", SDTPtrAuthOneSchema, []>; +def ptrauth_resign : SDNode<"ISD::PtrAuthResign", SDTPtrAuthTwoSchemas, []>; + //===----------------------------------------------------------------------===// // Selection DAG Condition Codes diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 2a0246074a462..3a1e48e2b2838 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -3353,6 +3353,20 @@ bool LLParser::parseOptionalOperandBundles( return false; } +static void upgradeOperandBundles( + SmallVectorImpl &BundleList) { + // AutoUpgrader.h exposes an API that accepts std::vector. + // Skip meaningless allocations if no bundles were parsed. + // FIXME Is it possible to change UpgradeOperandBundles function to accept + // SmallVectorImpl instead of std::vector? + if (BundleList.empty()) + return; + + std::vector BundleVector(BundleList.begin(), BundleList.end()); + UpgradeOperandBundles(BundleVector); + BundleList.assign(BundleVector.begin(), BundleVector.end()); +} + bool LLParser::checkValueID(LocTy Loc, StringRef Kind, StringRef Prefix, unsigned NextID, unsigned ID) { if (ID < NextID) @@ -4249,27 +4263,43 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { return false; } case lltok::kw_ptrauth: { - // ValID ::= 'ptrauth' '(' ptr @foo ',' i32 - // (',' i64 (',' ptr addrdisc (',' ptr ds)? - // )? )? ')' + // ValID ::= 'ptrauth' '(' ptr @foo ',' + // '[' i64 schema_op (',' i64 schema_op)* ']' + // (',' ptr ds)? ')' Lex.Lex(); - Constant *Ptr, *Key; - Constant *Disc = nullptr, *AddrDisc = nullptr, - *DeactivationSymbol = nullptr; + Constant *Ptr; + SmallVector Schema; + Constant *DeactivationSymbol = nullptr; + + Constant *TmpSchemaOp; if (parseToken(lltok::lparen, "expected '(' in constant ptrauth expression") || parseGlobalTypeAndValue(Ptr) || parseToken(lltok::comma, "expected comma in constant ptrauth expression") || - parseGlobalTypeAndValue(Key)) + parseToken(lltok::lsquare, + "expected '[' in constant ptrauth expression")) return true; - // If present, parse the optional disc/addrdisc/ds. - if (EatIfPresent(lltok::comma) && parseGlobalTypeAndValue(Disc)) + + if (EatIfPresent(lltok::rsquare)) + return error(ID.Loc, "schema of ptrauth constant must not be empty"); + + if (parseGlobalTypeAndValue(TmpSchemaOp)) return true; - if (EatIfPresent(lltok::comma) && parseGlobalTypeAndValue(AddrDisc)) + + Schema.push_back(TmpSchemaOp); + while (EatIfPresent(lltok::comma)) { + if (parseGlobalTypeAndValue(TmpSchemaOp)) + return true; + Schema.push_back(TmpSchemaOp); + } + + if (parseToken(lltok::rsquare, + "expected ']' in constant ptrauth expression")) return true; + if (EatIfPresent(lltok::comma) && parseGlobalTypeAndValue(DeactivationSymbol)) return true; @@ -4278,29 +4308,11 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { return true; if (!Ptr->getType()->isPointerTy()) - return error(ID.Loc, "constant ptrauth base pointer must be a pointer"); - - auto *KeyC = dyn_cast(Key); - if (!KeyC || KeyC->getBitWidth() != 32) - return error(ID.Loc, "constant ptrauth key must be i32 constant"); - - ConstantInt *DiscC = nullptr; - if (Disc) { - DiscC = dyn_cast(Disc); - if (!DiscC || DiscC->getBitWidth() != 64) - return error( - ID.Loc, - "constant ptrauth integer discriminator must be i64 constant"); - } else { - DiscC = ConstantInt::get(Type::getInt64Ty(Context), 0); - } + return error(ID.Loc, "base pointer of ptrauth constant must be a pointer"); - if (AddrDisc) { - if (!AddrDisc->getType()->isPointerTy()) - return error( - ID.Loc, "constant ptrauth address discriminator must be a pointer"); - } else { - AddrDisc = ConstantPointerNull::get(PointerType::get(Context, 0)); + for (Constant *Op : Schema) { + if (!Op->getType()->isIntegerTy(64)) + return error(ID.Loc, "schema of ptrauth constant must be a tuple of i64"); } if (!DeactivationSymbol) @@ -4310,8 +4322,7 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { return error(ID.Loc, "constant ptrauth deactivation symbol must be a pointer"); - ID.ConstantVal = - ConstantPtrAuth::get(Ptr, KeyC, DiscC, AddrDisc, DeactivationSymbol); + ID.ConstantVal = ConstantPtrAuth::get(Ptr, Schema, DeactivationSymbol); ID.Kind = ValID::t_Constant; return false; } @@ -7747,6 +7758,8 @@ bool LLParser::parseInvoke(Instruction *&Inst, PerFunctionState &PFS) { parseTypeAndBasicBlock(UnwindBB, PFS)) return true; + upgradeOperandBundles(BundleList); + // If RetType is a non-function pointer type, then this is the short syntax // for the call, which means that RetType is just the return type. Infer the // rest of the function argument types from the arguments that are present. @@ -8042,6 +8055,8 @@ bool LLParser::parseCallBr(Instruction *&Inst, PerFunctionState &PFS) { parseToken(lltok::lsquare, "expected '[' in callbr")) return true; + upgradeOperandBundles(BundleList); + // parse the destination list. SmallVector IndirectDests; @@ -8453,6 +8468,8 @@ bool LLParser::parseCall(Instruction *&Inst, PerFunctionState &PFS, parseOptionalOperandBundles(BundleList, PFS)) return true; + upgradeOperandBundles(BundleList); + // If RetType is a non-function pointer type, then this is the short syntax // for the call, which means that RetType is just the return type. Infer the // rest of the function argument types from the arguments that are present. diff --git a/llvm/lib/Bitcode/CMakeLists.txt b/llvm/lib/Bitcode/CMakeLists.txt index ff7e290cad1bb..3d07fea511f61 100644 --- a/llvm/lib/Bitcode/CMakeLists.txt +++ b/llvm/lib/Bitcode/CMakeLists.txt @@ -1,2 +1,3 @@ +add_compile_options(-O0) add_subdirectory(Reader) add_subdirectory(Writer) diff --git a/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp b/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp index 911ec7501eb8b..9f416cf9d17e2 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeAnalyzer.cpp @@ -222,7 +222,9 @@ GetCodeName(unsigned CodeID, unsigned BlockID, STRINGIFY_CODE(CST_CODE, CE_UNOP) STRINGIFY_CODE(CST_CODE, DSO_LOCAL_EQUIVALENT) STRINGIFY_CODE(CST_CODE, NO_CFI_VALUE) - STRINGIFY_CODE(CST_CODE, PTRAUTH) + STRINGIFY_CODE(CST_CODE, PTRAUTH_OLD) + STRINGIFY_CODE(CST_CODE, PTRAUTH_OLD2) + STRINGIFY_CODE(CST_CODE, PTRAUTH3) case bitc::CST_CODE_BLOCKADDRESS: return "CST_CODE_BLOCKADDRESS"; STRINGIFY_CODE(CST_CODE, DATA) diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 90e6ffbf8992b..e1797f057c7e1 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1601,24 +1601,48 @@ Expected BitcodeReader::materializeValue(unsigned StartValID, } else { switch (BC->Opcode) { case BitcodeConstant::ConstantPtrAuthOpcode: { - auto *Key = dyn_cast(ConstOps[1]); - if (!Key) - return error("ptrauth key operand must be ConstantInt"); - - auto *Disc = dyn_cast(ConstOps[2]); - if (!Disc) - return error("ptrauth disc operand must be ConstantInt"); - - Constant *DeactivationSymbol = - ConstOps.size() > 4 ? ConstOps[4] - : ConstantPointerNull::get(cast( - ConstOps[3]->getType())); + Constant *Ptr = nullptr; + Constant *DeactivationSymbol = nullptr; + SmallVector Schema; + + Type *Int64Ty = Type::getInt64Ty(BC->getContext()); + + switch (BC->Flags) { + default: + llvm_unreachable("Expected CST_CODE_PTRAUTH* constant"); + case bitc::CST_CODE_PTRAUTH_OLD2: + // Upgrade (ptr @ptr, i32 key, i64 disc, ptr @addr_disc, ptr @ds) + DeactivationSymbol = ConstOps[4]; + [[fallthrough]]; + case bitc::CST_CODE_PTRAUTH_OLD: + // Upgrade (ptr @ptr, i32 key, i64 disc, ptr @addr_disc) + Ptr = ConstOps[0]; + Schema.push_back(ConstantExpr::getBitCast(ConstOps[1], Int64Ty)); + Schema.push_back(ConstOps[2]); + Schema.push_back(ConstantExpr::getPtrToInt(ConstOps[3], Int64Ty)); + break; + case bitc::CST_CODE_PTRAUTH3: + Ptr = ConstOps[0]; + DeactivationSymbol = ConstOps[1]; + Schema.assign(&ConstOps[2], ConstOps.end()); + break; + } + + if (!Ptr->getType()->isPointerTy()) + return error( + "ptrauth signed operand must be a pointer"); + + for (Constant *C : Schema) + if (!C->getType()->isIntegerTy(64)) + return error("ptrauth schema operands must be i64 constants"); + + if (!DeactivationSymbol) + DeactivationSymbol = Constant::getNullValue(Ptr->getType()); if (!DeactivationSymbol->getType()->isPointerTy()) return error( "ptrauth deactivation symbol operand must be a pointer"); - C = ConstantPtrAuth::get(ConstOps[0], Key, Disc, ConstOps[3], - DeactivationSymbol); + C = ConstantPtrAuth::get(Ptr, Schema, DeactivationSymbol); break; } case BitcodeConstant::NoCFIOpcode: { @@ -3812,26 +3836,38 @@ Error BitcodeReader::parseConstants() { Record[1]); break; } - case bitc::CST_CODE_PTRAUTH: { + case bitc::CST_CODE_PTRAUTH_OLD: { if (Record.size() < 4) return error("Invalid ptrauth record"); // Ptr, Key, Disc, AddrDisc V = BitcodeConstant::create(Alloc, CurTy, - BitcodeConstant::ConstantPtrAuthOpcode, + {BitcodeConstant::ConstantPtrAuthOpcode, bitc::CST_CODE_PTRAUTH_OLD}, {(unsigned)Record[0], (unsigned)Record[1], (unsigned)Record[2], (unsigned)Record[3]}); break; } - case bitc::CST_CODE_PTRAUTH2: { + case bitc::CST_CODE_PTRAUTH_OLD2: { if (Record.size() < 5) return error("Invalid ptrauth record"); // Ptr, Key, Disc, AddrDisc, DeactivationSymbol V = BitcodeConstant::create( - Alloc, CurTy, BitcodeConstant::ConstantPtrAuthOpcode, + Alloc, CurTy, {BitcodeConstant::ConstantPtrAuthOpcode, bitc::CST_CODE_PTRAUTH_OLD2}, {(unsigned)Record[0], (unsigned)Record[1], (unsigned)Record[2], (unsigned)Record[3], (unsigned)Record[4]}); break; } + case bitc::CST_CODE_PTRAUTH3: { + if (Record.size() < 3) + return error("Invalid ptrauth record"); + // Ptr, DeactivationSymbol, SchemaArg0 [, SchemaArg1, ...] + + SmallVector Operands; + llvm::append_range(Operands, Record); + + V = BitcodeConstant::create( + Alloc, CurTy, {BitcodeConstant::ConstantPtrAuthOpcode, bitc::CST_CODE_PTRAUTH3}, Operands); + break; + } } assert(V->getType() == getTypeByID(CurTyID) && "Incorrect result type ID"); diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 845ecb4672cf2..02f10472133bc 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -3030,12 +3030,11 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal, Record.push_back(VE.getTypeID(NC->getGlobalValue()->getType())); Record.push_back(VE.getValueID(NC->getGlobalValue())); } else if (const auto *CPA = dyn_cast(C)) { - Code = bitc::CST_CODE_PTRAUTH2; + Code = bitc::CST_CODE_PTRAUTH3; Record.push_back(VE.getValueID(CPA->getPointer())); - Record.push_back(VE.getValueID(CPA->getKey())); - Record.push_back(VE.getValueID(CPA->getDiscriminator())); - Record.push_back(VE.getValueID(CPA->getAddrDiscriminator())); Record.push_back(VE.getValueID(CPA->getDeactivationSymbol())); + for (const Use &U : CPA->getSchema()) + Record.push_back(VE.getValueID(cast(U))); } else { #ifndef NDEBUG C->dump(); diff --git a/llvm/lib/Bitstream/CMakeLists.txt b/llvm/lib/Bitstream/CMakeLists.txt index 49def158f6904..1fe568f8340c9 100644 --- a/llvm/lib/Bitstream/CMakeLists.txt +++ b/llvm/lib/Bitstream/CMakeLists.txt @@ -1,2 +1,3 @@ +add_compile_options(-O0) add_subdirectory(Reader) # The writer is header-only. diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 63ed7d598455f..f808ffe503fa4 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -2188,6 +2188,39 @@ bool IRTranslator::translateConvergenceControlIntrinsic( return true; } +bool IRTranslator::translatePtrAuthIntrinsic(const CallInst &CI, + unsigned Opcode, + MachineIRBuilder &MIRBuilder) { + TLI->reportFatalErrorOnInvalidPtrAuthSchema(CI); + + auto TranslatePtrAuthBundle = [&](unsigned Index) { + auto Bundle = CI.getOperandBundleAt(Index); + assert(Bundle.getTagID() == LLVMContext::OB_ptrauth); + + SmallVector SchemaOps; + for (const Use &Operand : Bundle.Inputs) + SchemaOps.push_back(getOrCreateVReg(*Operand)); + + Register Res = MRI->createGenericVirtualRegister(LLT::token()); + MIRBuilder.buildInstr(TargetOpcode::G_PTRAUTH_BUNDLE, {Res}, SchemaOps); + + return Res; + }; + + SmallVector SrcOps; + SrcOps.push_back(getOrCreateVReg(*CI.getArgOperand(0))); + SrcOps.push_back(TranslatePtrAuthBundle(0)); + if (Opcode == TargetOpcode::G_PTRAUTH_RESIGN) + SrcOps.push_back(TranslatePtrAuthBundle(1)); + + Register Dst = getOrCreateVReg(CI); + auto MIB = MIRBuilder.buildInstr(Opcode, {Dst}, SrcOps); + if (auto Bundle = CI.getOperandBundle(LLVMContext::OB_deactivation_symbol)) + MIB->setDeactivationSymbol(*MF, Bundle->Inputs[0].get()); + + return true; +} + bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID, MachineIRBuilder &MIRBuilder) { if (auto *MI = dyn_cast(&CI)) { @@ -2207,6 +2240,18 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID, switch (ID) { default: break; + case Intrinsic::ptrauth_auth: + return translatePtrAuthIntrinsic(CI, TargetOpcode::G_PTRAUTH_AUTH, + MIRBuilder); + case Intrinsic::ptrauth_sign: + return translatePtrAuthIntrinsic(CI, TargetOpcode::G_PTRAUTH_SIGN, + MIRBuilder); + case Intrinsic::ptrauth_resign: + return translatePtrAuthIntrinsic(CI, TargetOpcode::G_PTRAUTH_RESIGN, + MIRBuilder); + case Intrinsic::ptrauth_strip: + return translatePtrAuthIntrinsic(CI, TargetOpcode::G_PTRAUTH_STRIP, + MIRBuilder); case Intrinsic::lifetime_start: case Intrinsic::lifetime_end: { // No stack colouring in O0, discard region information. @@ -2751,19 +2796,24 @@ bool IRTranslator::translateCallBase(const CallBase &CB, // Functions should never be ptrauth-called directly. assert(!CB.getCalledFunction() && "invalid direct ptrauth call"); - const Value *Key = Bundle->Inputs[0]; - const Value *Discriminator = Bundle->Inputs[1]; + assert(!isa(CB) && + "Should be handled by translateKnownIntrinsic"); + + TLI->reportFatalErrorOnInvalidPtrAuthSchema(CB); + + SmallVector BundleOperands(Bundle->Inputs.begin(), + Bundle->Inputs.end()); // Look through ptrauth constants to try to eliminate the matching bundle // and turn this into a direct call with no ptrauth. // CallLowering will use the raw pointer if it doesn't find the PAI. const auto *CalleeCPA = dyn_cast(CB.getCalledOperand()); if (!CalleeCPA || !isa(CalleeCPA->getPointer()) || - !CalleeCPA->isKnownCompatibleWith(Key, Discriminator, *DL)) { + !CalleeCPA->isKnownCompatibleWith(BundleOperands, *DL)) { // If we can't make it direct, package the bundle into PAI. - Register DiscReg = getOrCreateVReg(*Discriminator); - PAI = CallLowering::PtrAuthInfo{cast(Key)->getZExtValue(), - DiscReg}; + PAI = CallLowering::PtrAuthInfo(); + for (const Value *V : BundleOperands) + PAI->Operands.push_back(getOrCreateVReg(*V)); } } @@ -3777,9 +3827,17 @@ bool IRTranslator::translate(const Constant &C, Register Reg) { else if (auto GV = dyn_cast(&C)) EntryBuilder->buildGlobalValue(Reg, GV); else if (auto CPA = dyn_cast(&C)) { + TLI->reportFatalErrorOnInvalidPtrAuthSchema(*CPA); + Register Addr = getOrCreateVReg(*CPA->getPointer()); - Register AddrDisc = getOrCreateVReg(*CPA->getAddrDiscriminator()); - EntryBuilder->buildConstantPtrAuth(Reg, CPA, Addr, AddrDisc); + SmallVector SchemaOps; + for (const Use &Operand : CPA->getSchema()) + SchemaOps.push_back(getOrCreateVReg(*Operand)); + + Register SchemaReg = MRI->createGenericVirtualRegister(LLT::token()); + EntryBuilder->buildInstr(TargetOpcode::G_PTRAUTH_BUNDLE, {SchemaReg}, SchemaOps); + + EntryBuilder->buildConstantPtrAuth(Reg, Addr, SchemaReg); } else if (auto CAZ = dyn_cast(&C)) { Constant &Elt = *CAZ->getElementValue(0u); if (isa(CAZ->getType())) { diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp index 3906b311addf0..047e361bd520c 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -421,14 +421,11 @@ MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res, MachineInstrBuilder MachineIRBuilder::buildConstantPtrAuth(const DstOp &Res, - const ConstantPtrAuth *CPA, - Register Addr, Register AddrDisc) { + Register Ptr, Register Schema) { auto MIB = buildInstr(TargetOpcode::G_PTRAUTH_GLOBAL_VALUE); Res.addDefToMIB(*getMRI(), MIB); - MIB.addUse(Addr); - MIB.addImm(CPA->getKey()->getZExtValue()); - MIB.addUse(AddrDisc); - MIB.addImm(CPA->getDiscriminator()->getZExtValue()); + MIB.addUse(Ptr); + MIB.addUse(Schema); return MIB; } diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp index 9be741d96e456..e49ed809dbacb 100644 --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -2276,6 +2276,7 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) { report("addr operand must be a pointer", &AddrOp, 1); break; } + // TODO default: break; } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 2caf847370383..5501ad20610ff 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1868,10 +1868,18 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) { return DAG.getGlobalAddress(GV, getCurSDLoc(), VT); if (const ConstantPtrAuth *CPA = dyn_cast(C)) { + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + TLI.reportFatalErrorOnInvalidPtrAuthSchema(*CPA); + + SmallVector Ops; + for (const Use &Operand : CPA->getSchema()) + Ops.push_back(getValue(Operand)); + + SDValue Bundle = DAG.getNode(ISD::PtrAuthBundle, getCurSDLoc(), + MVT::Other, Ops); + return DAG.getNode(ISD::PtrAuthGlobalAddress, getCurSDLoc(), VT, - getValue(CPA->getPointer()), getValue(CPA->getKey()), - getValue(CPA->getAddrDiscriminator()), - getValue(CPA->getDiscriminator())); + getValue(CPA->getPointer()), Bundle); } if (isa(C)) @@ -6543,6 +6551,40 @@ void SelectionDAGBuilder::visitVectorExtractLastActive(const CallInst &I, setValue(&I, Result); } +void SelectionDAGBuilder::visitPtrAuthIntrinsic(const CallInst &I, + unsigned Opcode) { + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + SDLoc SDL = getCurSDLoc(); + + TLI.reportFatalErrorOnInvalidPtrAuthSchema(I); + + auto CreatePtrAuthBundle = [&](unsigned Index) { + auto Bundle = I.getOperandBundleAt(Index); + assert(Bundle.getTagID() == LLVMContext::OB_ptrauth); + + SmallVector Ops; + for (const Use &Operand : Bundle.Inputs) + Ops.push_back(getValue(Operand)); + + return DAG.getNode(ISD::PtrAuthBundle, SDL, MVT::Other, Ops); + }; + + SmallVector Ops; + Ops.push_back(getValue(I.getArgOperand(0))); + Ops.push_back(CreatePtrAuthBundle(0)); + if (Opcode == ISD::PtrAuthResign) + Ops.push_back(CreatePtrAuthBundle(1)); + + if (auto Bundle = I.getOperandBundle(LLVMContext::OB_deactivation_symbol)) { + auto *Sym = Bundle->Inputs[0].get(); + SDValue SDSym = getValue(Sym); + SDSym = DAG.getDeactivationSymbol(cast(Sym)); + Ops.push_back(SDSym); + } + + setValue(&I, DAG.getNode(Opcode, SDL, MVT::i64, Ops)); +} + /// Lower the call to the specified intrinsic function. void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { @@ -6560,6 +6602,18 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, // By default, turn this into a target intrinsic node. visitTargetIntrinsic(I, Intrinsic); return; + case Intrinsic::ptrauth_auth: + visitPtrAuthIntrinsic(I, ISD::PtrAuthAuth); + return; + case Intrinsic::ptrauth_sign: + visitPtrAuthIntrinsic(I, ISD::PtrAuthSign); + return; + case Intrinsic::ptrauth_resign: + visitPtrAuthIntrinsic(I, ISD::PtrAuthResign); + return; + case Intrinsic::ptrauth_strip: + visitPtrAuthIntrinsic(I, ISD::PtrAuthStrip); + return; case Intrinsic::vscale: { EVT VT = TLI.getValueType(DAG.getDataLayout(), I.getType()); setValue(&I, DAG.getVScale(sdl, VT, APInt(VT.getSizeInBits(), 1))); @@ -9135,12 +9189,8 @@ void SelectionDAGBuilder::LowerCallTo(const CallBase &CB, SDValue Callee, .setDeactivationSymbol(DeactivationSymbol); // Set the pointer authentication info if we have it. - if (PAI) { - if (!TLI.supportPtrAuthBundles()) - report_fatal_error( - "This target doesn't support calls with ptrauth operand bundles."); + if (PAI) CLI.setPtrAuth(*PAI); - } std::pair Result = lowerInvokable(CLI, EHPadBB); @@ -9767,23 +9817,20 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) { void SelectionDAGBuilder::LowerCallSiteWithPtrAuthBundle( const CallBase &CB, const BasicBlock *EHPadBB) { + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); auto PAB = CB.getOperandBundle("ptrauth"); const Value *CalleeV = CB.getCalledOperand(); - // Gather the call ptrauth data from the operand bundle: - // [ i32 , i64 ] - const auto *Key = cast(PAB->Inputs[0]); - const Value *Discriminator = PAB->Inputs[1]; + assert(!isa(CB) && "Should be handled by visitIntrinsicCall"); + + TLI.reportFatalErrorOnInvalidPtrAuthSchema(CB); - assert(Key->getType()->isIntegerTy(32) && "Invalid ptrauth key"); - assert(Discriminator->getType()->isIntegerTy(64) && - "Invalid ptrauth discriminator"); + SmallVector BundleOperands(PAB->Inputs.begin(), PAB->Inputs.end()); // Look through ptrauth constants to find the raw callee. // Do a direct unauthenticated call if we found it and everything matches. if (const auto *CalleeCPA = dyn_cast(CalleeV)) - if (CalleeCPA->isKnownCompatibleWith(Key, Discriminator, - DAG.getDataLayout())) + if (CalleeCPA->isKnownCompatibleWith(BundleOperands, DAG.getDataLayout())) return LowerCallTo(CB, getValue(CalleeCPA->getPointer()), CB.isTailCall(), CB.isMustTailCall(), EHPadBB); @@ -9791,8 +9838,10 @@ void SelectionDAGBuilder::LowerCallSiteWithPtrAuthBundle( assert(!isa(CalleeV) && "invalid direct ptrauth call"); // Otherwise, do an authenticated indirect call. - TargetLowering::PtrAuthInfo PAI = {Key->getZExtValue(), - getValue(Discriminator)}; + + TargetLowering::PtrAuthInfo PAI; + for (const Value *Operand : BundleOperands) + PAI.Operands.push_back(getValue(Operand)); LowerCallTo(CB, getValue(CalleeV), CB.isTailCall(), CB.isMustTailCall(), EHPadBB, &PAI); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index d2f720df61e72..0b330b713eab3 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -649,6 +649,7 @@ class SelectionDAGBuilder { void visitTargetIntrinsic(const CallInst &I, unsigned Intrinsic); void visitConstrainedFPIntrinsic(const ConstrainedFPIntrinsic &FPI); void visitConvergenceControl(const CallInst &I, unsigned Intrinsic); + void visitPtrAuthIntrinsic(const CallInst &I, unsigned Opcode); void visitVectorHistogram(const CallInst &I, unsigned IntrinsicID); void visitVectorExtractLastActive(const CallInst &I, unsigned Intrinsic); void visitVPLoad(const VPIntrinsic &VPIntrin, EVT VT, diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp index ec5edd5f13978..0546a2bf4568f 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp @@ -139,6 +139,11 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const { case ISD::GlobalAddress: return "GlobalAddress"; case ISD::GlobalTLSAddress: return "GlobalTLSAddress"; case ISD::PtrAuthGlobalAddress: return "PtrAuthGlobalAddress"; + case ISD::PtrAuthBundle: return "PtrAuthBundle"; + case ISD::PtrAuthAuth: return "PtrAuthAuth"; + case ISD::PtrAuthSign: return "PtrAuthSign"; + case ISD::PtrAuthResign: return "PtrAuthResign"; + case ISD::PtrAuthStrip: return "PtrAuthStrip"; case ISD::FrameIndex: return "FrameIndex"; case ISD::JumpTable: return "JumpTable"; case ISD::JUMP_TABLE_DEBUG_INFO: diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 7932765db8359..14f9d3eec7475 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -1674,22 +1674,23 @@ static void writeConstantInternal(raw_ostream &Out, const Constant *CV, if (const auto *CPA = dyn_cast(CV)) { Out << "ptrauth ("; - // ptrauth (ptr CST, i32 KEY[, i64 DISC[, ptr ADDRDISC[, ptr DS]?]?]?) - unsigned NumOpsToWrite = 2; - if (!CPA->getOperand(2)->isNullValue()) - NumOpsToWrite = 3; - if (!CPA->getOperand(3)->isNullValue()) - NumOpsToWrite = 4; - if (!CPA->getOperand(4)->isNullValue()) - NumOpsToWrite = 5; - + // ptrauth (ptr CST, [i64 ARG, ...] (, ptr DS)?) + writeAsOperandInternal(Out, CPA->getOperand(0), WriterCtx, + /*PrintType=*/true); + Out << ", ["; ListSeparator LS; - for (unsigned i = 0, e = NumOpsToWrite; i != e; ++i) { + auto Schema = CPA->getSchema(); + for (unsigned I = 0, N = Schema.size(); I < N; ++I) { Out << LS; - writeAsOperandInternal(Out, CPA->getOperand(i), WriterCtx, - /*PrintType=*/true); + writeAsOperandInternal(Out, Schema[I], WriterCtx, /*PrintType=*/true); } - Out << ')'; + Out << "]"; + Constant *Sym = CPA->getDeactivationSymbol(); + if (!Sym->isNullValue()) { + Out << ", "; + writeAsOperandInternal(Out, Sym, WriterCtx, /*PrintType=*/true); + } + Out << ")"; return; } diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 487db134b0df3..d9be1920ba695 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -1589,11 +1589,46 @@ static bool upgradeIntrinsicFunction1(Function *F, Function *&NewFn, {F->arg_begin()->getType(), F->getArg(1)->getType()}); return true; } + if (Name.consume_front("ptrauth.")) { + // @llvm.ptrauth.sign.generic does not require upgrade. + if (Name == "sign.generic") + break; + + // @llvm.ptrauth.blend is dropped altogether. + if (Name == "blend") { + NewFn = nullptr; + return true; + } + + // All other @llvm.ptrauth.* are upgraded to single-argument intrinsics + // with signing schemas passed via separate call operand bundles. + if (F->getFunctionType()->getNumParams() == 1) + break; + + // FIXME Has to match intrinsics by name prefix, otherwise intrinsics + // auto-declaration is not handled correctly. + Intrinsic::ID ID; + ID = StringSwitch(Name) + .StartsWith("auth", Intrinsic::ptrauth_auth) + .StartsWith("sign", Intrinsic::ptrauth_sign) + .StartsWith("resign", Intrinsic::ptrauth_resign) + .StartsWith("strip", Intrinsic::ptrauth_strip) + .Default(Intrinsic::not_intrinsic); + if (ID == Intrinsic::not_intrinsic) + break; + + rename(F); + NewFn = Intrinsic::getOrInsertDeclaration(F->getParent(), ID); + return true; + } break; case 'r': { if (Name.consume_front("riscv.")) { Intrinsic::ID ID; + // FIXME: Matching on the precise string instead of a substring seems to + // be incompatible with auto-declaration of intrinsics, see + // rv32zknd-intrinsic-autoupgrade.ll for example. ID = StringSwitch(Name) .Case("aes32dsi", Intrinsic::riscv_aes32dsi) .Case("aes32dsmi", Intrinsic::riscv_aes32dsmi) @@ -4673,6 +4708,190 @@ static void upgradeDbgIntrinsicToDbgRecord(StringRef Name, CallBase *CI) { CI->getParent()->insertDbgRecordBefore(DR, CI->getIterator()); } +static CallBase *setOperandBundles(CallBase *CI, ArrayRef OBs) { + IRBuilder<> Builder(CI); + Value *Callee = CI->getCalledOperand(); + SmallVector Args(CI->arg_begin(), CI->arg_end()); + CallBase *NewCI = Builder.CreateCall(CI->getFunctionType(), Callee, + Args, OBs); + NewCI->takeName(CI); + CI->replaceAllUsesWith(NewCI); + CI->eraseFromParent(); + + return NewCI; +} + +// Create a new, generalized "ptrauth" bundle from an old, AArch64-specific one +// by converting "ptrauth"(i32 const_key, i64 disc) to either +// - "ptrauth"(i64 const_key, i64 int_disc, i64 0) , if possible or to +// - "ptrauth"(i64 const_key, i64 0, i64 addr_disc) otherwise +// +// Caller of this function is responsible for distinguishing between old-style +// AArch64 bundles (i32 key) and new-style non-AArch64 bundles that happen to +// have two operands (which must all have i64 type in the new-style bundles). +// +// Note that this function never expands calls to @llvm.ptrauth.blend, which +// are handled by upgradePtrAuthBlend later. +static OperandBundleDef createUpgradedPtrAuthBundle(ConstantInt *Key, + Value *Disc) { + LLVMContext &Ctx = Key->getContext(); + Value *Zero = ConstantInt::get(Ctx, APInt::getZero(64)); + SmallVector Inputs; + + Inputs.push_back(ConstantInt::get(Ctx, Key->getValue().zext(64))); + + auto *IntDisc = dyn_cast(Disc); + if (IntDisc && isUInt<16>(IntDisc->getZExtValue())) + Inputs.append({IntDisc, Zero}); + else + Inputs.append({Zero, Disc}); + + return OperandBundleDef("ptrauth", Inputs); +} + +// Transitions a ptrauth intrinsic call site to a half-upgraded state: +// 1) call %0(a, b, c, d, e) -> call %0(a, 0, 0, 0, 0) [ "ptrauth"(...), +// "ptrauth"(...) ] +// 2) call %0(a, b, c) -> call %0(a, 0, 0) [ "ptrauth"(...) ] +// 3) call %0(a, b) -> call %0(a, 0) [ "ptrauth"(b) ] +// 4) any call site with operand bundles attached - kept intact +// +// Upgrading ptrauth intrinsics requires inspecting their discriminator +// operand(s), which can be computed by a separate call to blend(). +// +// Because @llvm.ptrauth.blend intrinsic is removed by AutoUpgrader, the +// original computation of the discriminator may be removed before regular +// processing of its users occurs. For that reason, as soon as the particular +// call to @llvm.ptrauth.blend() is processed, all its users must be ready to +// absorb the arguments of the original blend call, even if the user is not +// fully resolved at that time. +// +// Thankfully, the transformations to be applied to any *supported* call site +// can be chosen depending merely on the number of arguments and operand +// bundles: in the example above, 1) corresponds to resign() call, 2) to auth() +// and sign(), 3) to strip() and 4) naturally captures the only original use +// case of "ptrauth" bundles (indirect authenticated calls) as well as any +// @llvm.ptrauth.* intrinsics which were lazily processed already. +// +// Note: the half-upgraded call formally uses the same called function +// and the same function signature as the original one. +// Note: authenticated indirect calls with old-style bundles are handled by +// UpgradeOperandBundles function. +static CallBase *upgradeToPtrAuthBundles(CallBase *CI) { + // Skip: intrinsic calls are never indirect. + if (CI->isIndirectCall()) + return CI; + // Skip: current version or already converted to using bundles. + if (CI->getNumOperandBundles()) + return CI; + + LLVMContext &Ctx = CI->getContext(); + Value *Zero32 = ConstantInt::get(Ctx, APInt::getZero(32)); + Value *Zero64 = ConstantInt::get(Ctx, APInt::getZero(64)); + SmallVector OBs; + + auto UpgradeToBundle = [&](unsigned KeyIndex, unsigned DiscIndex) { + ConstantInt *Key = dyn_cast(CI->getArgOperand(KeyIndex)); + Value *Disc = CI->getArgOperand(DiscIndex); + + if (!Key) + reportFatalUsageError("Cannot upgrade: expected constant ptrauth key ID"); + OBs.emplace_back(createUpgradedPtrAuthBundle(Key, Disc)); + + CI->setArgOperand(KeyIndex, Zero32); + CI->setArgOperand(DiscIndex, Zero64); + }; + + switch (CI->arg_size()) { + default: + // Unknown intrinsic or regular function - skip it now, it will be + // reported later as a usage that was not eliminated. + return CI; + case 2: { + // strip(value, key) -> strip(value, 0) [ "ptrauth"(key) ] + ConstantInt *Key = dyn_cast(CI->getArgOperand(1)); + if (!Key) + reportFatalUsageError("Cannot upgrade: expected constant ptrauth key ID"); + + Value *Inputs = {ConstantInt::get(Ctx, Key->getValue().zext(64))}; + OBs.emplace_back("ptrauth", Inputs); + + CI->setArgOperand(1, Zero32); + break; + } + case 3: + // auth(value, key, disc) -> auth(value, 0, 0) [ "ptrauth"(...) ] + // sign(value, key, disc) -> sign(value, 0, 0) [ "ptrauth"(...) ] + UpgradeToBundle(1, 2); + break; + case 5: + // resign(value, old_key, old_disc, new_key, new_disc) -> + // resign(value, 0, 0, 0, 0) [ "ptrauth"(), + // "ptrauth"() ] + UpgradeToBundle(1, 2); + UpgradeToBundle(3, 4); + break; + } + + // Attach operand bundles by re-creating the call. + return setOperandBundles(CI, OBs); +} + +// Fully process a call to @llvm.ptrauth.blend(), lazily upgrading its users +// to the extent that they are able to absorb the information from BlendCall. +static void upgradePtrAuthBlend(CallBase *BlendCall) { + // Collect all call instructions to be upgraded before performing any + // modifications. + SmallPtrSet UpgradableUsers; + for (User *U : BlendCall->users()) + if (auto *Call = dyn_cast(U)) + UpgradableUsers.insert(Call); + + if (BlendCall->arg_size() != 2) + reportFatalUsageError("@llvm.ptrauth.blend must have two arguments"); + Value *AddrDisc = BlendCall->getArgOperand(0); + Value *IntDisc = BlendCall->getArgOperand(1); + + for (CallBase *Call : UpgradableUsers) { + // If Call is an old-style @llvm.ptrauth.* intrinsic call, lazily migrate + // it to "ptrauth" bundles first. + // If Call is an authenticated indirect call, it is expected to have + // already been migrated to a three-operand form by UpgradeOperandBundles. + Call = upgradeToPtrAuthBundles(Call); + + SmallVector OBs; + Call->getOperandBundlesAsDefs(OBs); + + // Expand all bundles which refer to *this* blend() call. + // This may affect multiple bundles in case of resign() intrinsic which + // only changes the key. + for (unsigned I = 0, N = OBs.size(); I < N; ++I) { + auto OB = OBs[I]; + // Skip any bundles that are not of the form + // "ptrauth"(i64 key, i64 0, i64 %this_blend_call) + if (OB.getTag() != "ptrauth" || OB.input_size() != 3 || + OB.inputs()[2] != BlendCall) + continue; + + ConstantInt *TempIntDisc = dyn_cast(OB.inputs()[1]); + if (!TempIntDisc || !TempIntDisc->isZero()) + continue; + + Value *NewBundleOperands[] = {OB.inputs()[0], IntDisc, AddrDisc}; + OBs[I] = OperandBundleDef("ptrauth", NewBundleOperands); + } + + setOperandBundles(Call, OBs); + } + + if (!BlendCall->users().empty()) { + errs() << "Cannot upgrade all uses of @llvm.ptrauth.blend in function:\n"; + BlendCall->getFunction()->print(errs()); + reportFatalUsageError("Cannot upgrade some uses of " + "@llvm.ptrauth.blend()."); + } +} + /// Upgrade a call to an old intrinsic. All argument and return casting must be /// provided to seamlessly integrate with existing context. void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { @@ -4704,6 +4923,8 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { if (!IsX86 && Name == "stackprotectorcheck") { Rep = nullptr; + } else if (Name == "ptrauth.blend") { + upgradePtrAuthBlend(CI); } else if (IsNVVM) { Rep = upgradeNVVMIntrinsicCall(Name, CI, F, Builder); } else if (IsX86) { @@ -5390,6 +5611,19 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { NewCall = Builder.CreateCall(NewFn, Args); break; } + case Intrinsic::ptrauth_auth: + case Intrinsic::ptrauth_sign: + case Intrinsic::ptrauth_resign: + case Intrinsic::ptrauth_strip: + CI = upgradeToPtrAuthBundles(CI); + Builder.SetInsertPoint(CI); + + Value *Args[] = {CI->getArgOperand(0)}; + SmallVector OBs; + CI->getOperandBundlesAsDefs(OBs); + + NewCall = Builder.CreateCall(NewFn, Args, OBs); + break; } assert(NewCall && "Should have either set this variable or returned through " "the default case"); @@ -6415,4 +6649,26 @@ void llvm::UpgradeOperandBundles(std::vector &Bundles) { return OBD.getTag() == "clang.arc.attachedcall" && OBD.inputs().empty(); }); + + for (unsigned I = 0, N = Bundles.size(); I < N; ++I) { + OperandBundleDef &OB = Bundles[I]; + + // Upgrade an old-style AArch64 "ptrauth"(i32 const_key, i64 disc) bundle + // either to + // - "ptrauth"(i64 const_key, i64 int_disc, i64 0), or to + // - "ptrauth"(i64 const_key, i64 0, i64 addr_disc) + // + // Note that this can be trivially distinguished from non-AArch64 bundles + // that could have two operands, as new-style bundles should never have i32 + // operands. + if (OB.getTag() == "ptrauth" && OB.inputs().size() == 2) { + ConstantInt *Key = dyn_cast(OB.inputs()[0]); + Value *Disc = OB.inputs()[1]; + + if (!Key || !Key->getType()->isIntegerTy(32)) + continue; + + Bundles[I] = createUpgradedPtrAuthBundle(Key, Disc); + } + } } diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index 6b82da140256f..a2c3dd7dd45ed 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -1899,7 +1899,7 @@ void UndefValue::destroyConstantImpl() { } else if (getValueID() == PoisonValueVal) { getContext().pImpl->PVConstants.erase(getType()); } - llvm_unreachable("Not a undef or a poison!"); + llvm_unreachable("Not a undef or a poison!"); // unreachable?!? } PoisonValue *PoisonValue::get(Type *Ty) { @@ -2080,34 +2080,45 @@ Value *NoCFIValue::handleOperandChangeImpl(Value *From, Value *To) { //---- ConstantPtrAuth::get() implementations. // -ConstantPtrAuth *ConstantPtrAuth::get(Constant *Ptr, ConstantInt *Key, - ConstantInt *Disc, Constant *AddrDisc, +#if 0 +ConstantPtrAuth *ConstantPtrAuth::get(Constant *Ptr, Constant *Schema, Constant *DeactivationSymbol) { - Constant *ArgVec[] = {Ptr, Key, Disc, AddrDisc, DeactivationSymbol}; + Constant *ArgVec[] = {Ptr, Schema, DeactivationSymbol}; ConstantPtrAuthKeyType MapKey(ArgVec); LLVMContextImpl *pImpl = Ptr->getContext().pImpl; return pImpl->ConstantPtrAuths.getOrCreate(Ptr->getType(), MapKey); } +#endif + +ConstantPtrAuth *ConstantPtrAuth::get(Constant *Ptr, + ArrayRef SchemaArgs, + Constant *DeactivationSymbol) { + ConstantPtrAuthKeyType MapKey(Ptr, SchemaArgs, DeactivationSymbol); + LLVMContextImpl *pImpl = Ptr->getContext().pImpl; + return pImpl->ConstantPtrAuths.getOrCreate(Ptr->getType(), MapKey); +} ConstantPtrAuth *ConstantPtrAuth::getWithSameSchema(Constant *Pointer) const { - return get(Pointer, getKey(), getDiscriminator(), getAddrDiscriminator(), - getDeactivationSymbol()); + SmallVector Schema; + for (Value *V :getSchema()) + Schema.push_back(cast(V)); + return get(Pointer, Schema, getDeactivationSymbol()); } -ConstantPtrAuth::ConstantPtrAuth(Constant *Ptr, ConstantInt *Key, - ConstantInt *Disc, Constant *AddrDisc, - Constant *DeactivationSymbol) - : Constant(Ptr->getType(), Value::ConstantPtrAuthVal, AllocMarker) { +ConstantPtrAuth::ConstantPtrAuth(Constant *Ptr, ArrayRef Schema, + Constant *DeactivationSymbol, + AllocInfo AllocInfo) + : Constant(Ptr->getType(), Value::ConstantPtrAuthVal, AllocInfo) { assert(Ptr->getType()->isPointerTy()); - assert(Key->getBitWidth() == 32); - assert(Disc->getBitWidth() == 64); - assert(AddrDisc->getType()->isPointerTy()); assert(DeactivationSymbol->getType()->isPointerTy()); setOperand(0, Ptr); - setOperand(1, Key); - setOperand(2, Disc); - setOperand(3, AddrDisc); - setOperand(4, DeactivationSymbol); + setOperand(1, DeactivationSymbol); + + assert(!Schema.empty()); + for (unsigned I = 0, N = Schema.size(); I < N; ++I) { + assert(Schema[I]->getType()->isIntegerTy(64)); + setOperand(2 + I, Schema[I]); + } } /// Remove the constant from the constant table. @@ -2119,17 +2130,16 @@ Value *ConstantPtrAuth::handleOperandChangeImpl(Value *From, Value *ToV) { assert(isa(ToV) && "Cannot make Constant refer to non-constant!"); Constant *To = cast(ToV); - SmallVector Values; + SmallVector Values; Values.reserve(getNumOperands()); unsigned NumUpdated = 0; - - Use *OperandList = getOperandList(); unsigned OperandNo = 0; - for (Use *O = OperandList, *E = OperandList + getNumOperands(); O != E; ++O) { - Constant *Val = cast(O->get()); + + for (unsigned I = 0, N = getNumOperands(); I < N; ++I) { + Constant *Val = cast(getOperand(I)); if (Val == From) { - OperandNo = (O - OperandList); + OperandNo = I; Val = To; ++NumUpdated; } @@ -2141,80 +2151,57 @@ Value *ConstantPtrAuth::handleOperandChangeImpl(Value *From, Value *ToV) { } bool ConstantPtrAuth::hasSpecialAddressDiscriminator(uint64_t Value) const { - const auto *CastV = dyn_cast(getAddrDiscriminator()); - if (!CastV || CastV->getOpcode() != Instruction::IntToPtr) - return false; - - const auto *IntVal = dyn_cast(CastV->getOperand(0)); + const auto *IntVal = dyn_cast(getAddrDiscriminator()); if (!IntVal) return false; return IntVal->getValue() == Value; } -bool ConstantPtrAuth::isKnownCompatibleWith(const Value *Key, - const Value *Discriminator, +bool ConstantPtrAuth::isKnownCompatibleWith(ArrayRef BundleOperands, const DataLayout &DL) const { // This function may only be validly called to analyze a ptrauth operation // with no deactivation symbol, so if we have one it isn't compatible. if (!getDeactivationSymbol()->isNullValue()) return false; - // If the keys are different, there's no chance for this to be compatible. - if (getKey() != Key) - return false; + auto CompatibleOperands = [&DL](Value *This, Value *Other) { + if (This == Other) + return true; - // We can have 3 kinds of discriminators: - // - simple, integer-only: `i64 x, ptr null` vs. `i64 x` - // - address-only: `i64 0, ptr p` vs. `ptr p` - // - blended address/integer: `i64 x, ptr p` vs. `@llvm.ptrauth.blend(p, x)` - - // If this constant has a simple discriminator (integer, no address), easy: - // it's compatible iff the provided full discriminator is also a simple - // discriminator, identical to our integer discriminator. - if (!hasAddressDiscriminator()) - return getDiscriminator() == Discriminator; - - // Otherwise, we can isolate address and integer discriminator components. - const Value *AddrDiscriminator = nullptr; - - // This constant may or may not have an integer discriminator (instead of 0). - if (!getDiscriminator()->isNullValue()) { - // If it does, there's an implicit blend. We need to have a matching blend - // intrinsic in the provided full discriminator. - if (!match(Discriminator, - m_Intrinsic( - m_Value(AddrDiscriminator), m_Specific(getDiscriminator())))) + // If This and Other are not trivially equal, try analyzing pointers. + if (!isa(This) || !isa(Other)) return false; - } else { - // Otherwise, interpret the provided full discriminator as address-only. - AddrDiscriminator = Discriminator; - } + This = cast(This)->getPointerOperand(); + Other = cast(Other)->getPointerOperand(); - // Either way, we can now focus on comparing the address discriminators. + // Reject incompatible pointer types (different address spaces). + if (This->getType() != Other->getType()) + return false; + unsigned AddressBitWidth = DL.getIndexTypeSizeInBits(This->getType()); - // Discriminators are i64, so the provided addr disc may be a ptrtoint. - if (auto *Cast = dyn_cast(AddrDiscriminator)) - AddrDiscriminator = Cast->getPointerOperand(); + // Check if two pointers are equivalent base+offset expressions. + APInt Off1(AddressBitWidth, 0); + auto *Base1 = This->stripAndAccumulateConstantOffsets( + DL, Off1, /*AllowNonInbounds=*/true); - // Beyond that, we're only interested in compatible pointers. - if (getAddrDiscriminator()->getType() != AddrDiscriminator->getType()) - return false; + APInt Off2(AddressBitWidth, 0); + auto *Base2 = Other->stripAndAccumulateConstantOffsets( + DL, Off2, /*AllowNonInbounds=*/true); - // These are often the same constant GEP, making them trivially equivalent. - if (getAddrDiscriminator() == AddrDiscriminator) - return true; + return Base1 == Base2 && Off1 == Off2; + }; - // Finally, they may be equivalent base+offset expressions. - APInt Off1(DL.getIndexTypeSizeInBits(getAddrDiscriminator()->getType()), 0); - auto *Base1 = getAddrDiscriminator()->stripAndAccumulateConstantOffsets( - DL, Off1, /*AllowNonInbounds=*/true); - APInt Off2(DL.getIndexTypeSizeInBits(AddrDiscriminator->getType()), 0); - auto *Base2 = AddrDiscriminator->stripAndAccumulateConstantOffsets( - DL, Off2, /*AllowNonInbounds=*/true); + if (getSchema().size() != BundleOperands.size()) + return false; - return Base1 == Base2 && Off1 == Off2; + for (unsigned I = 0, N = getSchema().size(); I < N; ++I) { + if (!CompatibleOperands(getSchema()[I], BundleOperands[I])) + return false; + } + + return true; } //---- ConstantExpr::get() implementations. diff --git a/llvm/lib/IR/ConstantsContext.h b/llvm/lib/IR/ConstantsContext.h index 2073e0d42d8e3..abdf535d0396e 100644 --- a/llvm/lib/IR/ConstantsContext.h +++ b/llvm/lib/IR/ConstantsContext.h @@ -505,42 +505,52 @@ struct ConstantExprKeyType { }; struct ConstantPtrAuthKeyType { - ArrayRef Operands; + Constant *Ptr; + ArrayRef Schema; + Constant *DeactivationSymbol; - ConstantPtrAuthKeyType(ArrayRef Operands) : Operands(Operands) {} + ConstantPtrAuthKeyType(Constant *Ptr, ArrayRef Schema, + Constant *DeactivationSymbol) + : Ptr(Ptr), Schema(Schema), DeactivationSymbol(DeactivationSymbol) {} ConstantPtrAuthKeyType(ArrayRef Operands, const ConstantPtrAuth *) - : Operands(Operands) {} + : Ptr(Operands[0]), Schema(Operands.drop_front(2)), + DeactivationSymbol(Operands[1]) {} ConstantPtrAuthKeyType(const ConstantPtrAuth *C, SmallVectorImpl &Storage) { assert(Storage.empty() && "Expected empty storage"); for (unsigned I = 0, E = C->getNumOperands(); I != E; ++I) Storage.push_back(cast(C->getOperand(I))); - Operands = Storage; + Ptr = Storage[0]; + DeactivationSymbol = Storage[1]; + Schema = ArrayRef(Storage).drop_front(2); } bool operator==(const ConstantPtrAuthKeyType &X) const { - return Operands == X.Operands; + return Ptr == X.Ptr && Schema == X.Schema && + DeactivationSymbol == X.DeactivationSymbol; } bool operator==(const ConstantPtrAuth *C) const { - if (Operands.size() != C->getNumOperands()) + if (Ptr != C->getPointer() || + Schema.size() != C->getSchema().size() || + DeactivationSymbol != C->getDeactivationSymbol()) return false; - for (unsigned I = 0, E = Operands.size(); I != E; ++I) - if (Operands[I] != C->getOperand(I)) + for (auto [A, B] : llvm::zip_equal(Schema, C->getSchema())) + if (A != B) return false; return true; } - unsigned getHash() const { return hash_combine_range(Operands); } + unsigned getHash() const { return hash_combine(Ptr, hash_combine_range(Schema), DeactivationSymbol); } using TypeClass = ConstantInfo::TypeClass; ConstantPtrAuth *create(TypeClass *Ty) const { - return new ConstantPtrAuth(Operands[0], cast(Operands[1]), - cast(Operands[2]), Operands[3], - Operands[4]); + unsigned NumVals = Schema.size() + 2; + User::IntrusiveOperandsAllocMarker AllocMarker{NumVals}; + return new (AllocMarker) ConstantPtrAuth(Ptr, Schema, DeactivationSymbol, AllocMarker); } }; diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index 26c4f4ec784cd..f32bd2ccd2951 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -920,6 +920,15 @@ LLVMValueRef LLVMGetConstantPtrAuthPointer(LLVMValueRef PtrAuth) { return wrap(unwrap(PtrAuth)->getPointer()); } +LLVM_C_ABI unsigned LLVMGetConstantPtrAuthSchemaSize(LLVMValueRef PtrAuth) { + return unwrap(PtrAuth)->getSchema().size(); +} + +LLVM_C_ABI LLVMValueRef +LLVMGetConstantPtrAuthSchemaOperand(LLVMValueRef PtrAuth, unsigned Idx) { + return wrap(unwrap(PtrAuth)->getSchema()[Idx]); +} + LLVMValueRef LLVMGetConstantPtrAuthKey(LLVMValueRef PtrAuth) { return wrap(unwrap(PtrAuth)->getKey()); } @@ -932,6 +941,11 @@ LLVMValueRef LLVMGetConstantPtrAuthAddrDiscriminator(LLVMValueRef PtrAuth) { return wrap(unwrap(PtrAuth)->getAddrDiscriminator()); } +LLVM_C_ABI LLVMValueRef +LLVMGetConstantPtrAuthDeactivationSymbol(LLVMValueRef PtrAuth) { + return wrap(unwrap(PtrAuth)->getDeactivationSymbol()); +} + /*--.. Operations on other types ...........................................--*/ LLVMTypeRef LLVMPointerTypeInContext(LLVMContextRef C, unsigned AddressSpace) { @@ -1695,13 +1709,16 @@ LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size) { ArrayRef(unwrap(ScalarConstantVals, Size), Size))); } -LLVMValueRef LLVMConstantPtrAuth(LLVMValueRef Ptr, LLVMValueRef Key, - LLVMValueRef Disc, LLVMValueRef AddrDisc) { +LLVMValueRef LLVMConstantPtrAuth(LLVMValueRef Ptr, LLVMValueRef *Schema, + unsigned SchemaSize, + LLVMValueRef DeactivationSymbol) { + SmallVector SchemaUnwrapped; + for (unsigned I = 0; I < SchemaSize; ++I) + SchemaUnwrapped.push_back(unwrap(Schema[I])); + return wrap(ConstantPtrAuth::get( - unwrap(Ptr), unwrap(Key), - unwrap(Disc), unwrap(AddrDisc), - ConstantPointerNull::get( - cast(unwrap(AddrDisc)->getType())))); + unwrap(Ptr), SchemaUnwrapped, + unwrap(DeactivationSymbol))); } /*-- Opcode mapping */ diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index a1e14d8f25bf7..431db9c4bbd2f 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -2719,27 +2719,24 @@ void Verifier::visitConstantExpr(const ConstantExpr *CE) { void Verifier::visitConstantPtrAuth(const ConstantPtrAuth *CPA) { Check(CPA->getPointer()->getType()->isPointerTy(), - "signed ptrauth constant base pointer must have pointer type"); + "ptrauth constant base pointer must have pointer type", CPA); Check(CPA->getType() == CPA->getPointer()->getType(), - "signed ptrauth constant must have same type as its base pointer"); + "ptrauth constant must have same type as its base pointer", CPA); - Check(CPA->getKey()->getBitWidth() == 32, - "signed ptrauth constant key must be i32 constant integer"); - - Check(CPA->getAddrDiscriminator()->getType()->isPointerTy(), - "signed ptrauth constant address discriminator must be a pointer"); - - Check(CPA->getDiscriminator()->getBitWidth() == 64, - "signed ptrauth constant discriminator must be i64 constant integer"); + Check(!CPA->getSchema().empty(), + "ptrauth constant must not have empty schema"); + for (Value *V : CPA->getSchema()) + Check(V->getType()->isIntegerTy(64), + "ptrauth constant schema must have i64 constant operands", CPA); Check(CPA->getDeactivationSymbol()->getType()->isPointerTy(), - "signed ptrauth constant deactivation symbol must be a pointer"); + "ptrauth constant deactivation symbol must be a pointer", CPA); Check(isa(CPA->getDeactivationSymbol()) || CPA->getDeactivationSymbol()->isNullValue(), - "signed ptrauth constant deactivation symbol must be a global value " - "or null"); + "ptrauth constant deactivation symbol must be a global value or null", + CPA); } bool Verifier::verifyAttributeCount(AttributeList Attrs, unsigned Params) { @@ -3971,8 +3968,8 @@ void Verifier::visitCallBase(CallBase &Call) { bool FoundDeoptBundle = false, FoundFuncletBundle = false, FoundGCTransitionBundle = false, FoundCFGuardTargetBundle = false, FoundPreallocatedBundle = false, FoundGCLiveBundle = false, - FoundPtrauthBundle = false, FoundKCFIBundle = false, - FoundAttachedCallBundle = false; + FoundKCFIBundle = false, FoundAttachedCallBundle = false; + unsigned NumPtrauthBundles = 0; for (unsigned i = 0, e = Call.getNumOperandBundles(); i < e; ++i) { OperandBundleUse BU = Call.getOperandBundleAt(i); uint32_t Tag = BU.getTagID(); @@ -3998,15 +3995,11 @@ void Verifier::visitCallBase(CallBase &Call) { Check(BU.Inputs.size() == 1, "Expected exactly one cfguardtarget bundle operand", Call); } else if (Tag == LLVMContext::OB_ptrauth) { - Check(!FoundPtrauthBundle, "Multiple ptrauth operand bundles", Call); - FoundPtrauthBundle = true; - Check(BU.Inputs.size() == 2, - "Expected exactly two ptrauth bundle operands", Call); - Check(isa(BU.Inputs[0]) && - BU.Inputs[0]->getType()->isIntegerTy(32), - "Ptrauth bundle key operand must be an i32 constant", Call); - Check(BU.Inputs[1]->getType()->isIntegerTy(64), - "Ptrauth bundle discriminator operand must be an i64", Call); + ++NumPtrauthBundles; + Check(!BU.Inputs.empty(), "Expected non-empty ptrauth bundle", Call); + for (Value *V : BU.Inputs) + Check(V->getType()->isIntegerTy(64), + "Ptrauth bundle must only contain i64 operands", Call); } else if (Tag == LLVMContext::OB_kcfi) { Check(!FoundKCFIBundle, "Multiple kcfi operand bundles", Call); FoundKCFIBundle = true; @@ -4039,8 +4032,25 @@ void Verifier::visitCallBase(CallBase &Call) { } // Verify that callee and callsite agree on whether to use pointer auth. - Check(!(Call.getCalledFunction() && FoundPtrauthBundle), - "Direct call cannot have a ptrauth bundle", Call); + switch (Call.getIntrinsicID()) { + case Intrinsic::not_intrinsic: + Check(!(Call.getCalledFunction() && NumPtrauthBundles), + "Direct call cannot have a ptrauth bundle", Call); + Check(NumPtrauthBundles <= 1, + "Multiple ptrauth operand bundles on a function call", Call); + break; + case Intrinsic::ptrauth_auth: + case Intrinsic::ptrauth_sign: + case Intrinsic::ptrauth_strip: + Check(NumPtrauthBundles == 1, "Expected exactly one ptrauth bundle", Call); + break; + case Intrinsic::ptrauth_resign: + Check(NumPtrauthBundles == 2, "Expected exactly two ptrauth bundles", Call); + break; + default: + Check(NumPtrauthBundles == 0, "Unexpected ptrauth bundle", Call); + break; + } // Verify that each inlinable callsite of a debug-info-bearing function in a // debug-info-bearing function has a debug location attached to it. Failure to diff --git a/llvm/lib/SandboxIR/Constant.cpp b/llvm/lib/SandboxIR/Constant.cpp index eb14797af081c..52e8b657ba9a0 100644 --- a/llvm/lib/SandboxIR/Constant.cpp +++ b/llvm/lib/SandboxIR/Constant.cpp @@ -411,12 +411,22 @@ PointerType *NoCFIValue::getType() const { return cast(Ctx.getType(cast(Val)->getType())); } -ConstantPtrAuth *ConstantPtrAuth::get(Constant *Ptr, ConstantInt *Key, - ConstantInt *Disc, Constant *AddrDisc, +ConstantPtrAuth *ConstantPtrAuth::get(Constant *Ptr, ConstantArray *Schema, Constant *DeactivationSymbol) { auto *LLVMC = llvm::ConstantPtrAuth::get( - cast(Ptr->Val), cast(Key->Val), - cast(Disc->Val), cast(AddrDisc->Val), + cast(Ptr->Val), cast(Schema->Val), + cast(DeactivationSymbol->Val)); + return cast(Ptr->getContext().getOrCreateConstant(LLVMC)); +} + +ConstantPtrAuth *ConstantPtrAuth::get(Constant *Ptr, + ArrayRef Schema, + Constant *DeactivationSymbol) { + SmallVector LLVMSchema; + for (Constant *C : Schema) + LLVMSchema.push_back(cast(C->Val)); + auto *LLVMC = llvm::ConstantPtrAuth::get( + cast(Ptr->Val), LLVMSchema, cast(DeactivationSymbol->Val)); return cast(Ptr->getContext().getOrCreateConstant(LLVMC)); } @@ -426,6 +436,11 @@ Constant *ConstantPtrAuth::getPointer() const { cast(Val)->getPointer()); } +// ConstantArray *ConstantPtrAuth::getSchema() const { + // return cast( + // Ctx.getOrCreateConstant(cast(Val)->getSchema())); +// } + ConstantInt *ConstantPtrAuth::getKey() const { return cast( Ctx.getOrCreateConstant(cast(Val)->getKey())); diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 8267414e78955..af7fc75154b6c 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -2280,8 +2280,6 @@ void AArch64AsmPrinter::emitPtrauthBranch(const MachineInstr *MI) { unsigned BrTarget = MI->getOperand(0).getReg(); auto Key = (AArch64PACKey::ID)MI->getOperand(1).getImm(); - assert((Key == AArch64PACKey::IA || Key == AArch64PACKey::IB) && - "Invalid auth call key"); uint64_t Disc = MI->getOperand(2).getImm(); assert(isUInt<16>(Disc)); @@ -2315,6 +2313,24 @@ void AArch64AsmPrinter::emitPtrauthBranch(const MachineInstr *MI) { AddrDiscIsImplicitDef); bool IsZeroDisc = DiscReg == AArch64::XZR; + if (Key == AArch64PACKey::DA || Key == AArch64PACKey::DB) { + emitMovXReg(AArch64::X16, BrTarget); + // Have to emit separate auth and branch instructions for D-key. + MCInst AUTInst; + AUTInst.setOpcode(getAUTOpcodeForKey(Key, IsZeroDisc)); + AUTInst.addOperand(MCOperand::createReg(AArch64::X16)); + AUTInst.addOperand(MCOperand::createReg(AArch64::X16)); + if (!IsZeroDisc) + AUTInst.addOperand(MCOperand::createReg(DiscReg)); + EmitToStreamer(AUTInst); + + MCInst BranchInst; + BranchInst.setOpcode(IsCall ? AArch64::BLR : AArch64::BR); + BranchInst.addOperand(MCOperand::createReg(AArch64::X16)); + EmitToStreamer(BranchInst); + return; + } + unsigned Opc; if (IsCall) { if (Key == AArch64PACKey::IA) @@ -3258,16 +3274,24 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { case AArch64::AUTH_TCRETURN: case AArch64::AUTH_TCRETURN_BTI: { Register Callee = MI->getOperand(0).getReg(); - const uint64_t Key = MI->getOperand(2).getImm(); - assert((Key == AArch64PACKey::IA || Key == AArch64PACKey::IB) && - "Invalid auth key for tail-call return"); + const auto Key = (AArch64PACKey::ID)MI->getOperand(2).getImm(); const uint64_t Disc = MI->getOperand(3).getImm(); assert(isUInt<16>(Disc) && "Integer discriminator is too wide"); Register AddrDisc = MI->getOperand(4).getReg(); - Register ScratchReg = Callee == AArch64::X16 ? AArch64::X17 : AArch64::X16; + // AUTH_TCRETURN[_BTI] pseudos are permitted to clobber both X16 and X17. + // At the same time, depending on the instruction either Callee or AddrDisc + // may be passed in X16 or X17. It is okay to have ScratchDiscReg equal to + // DiscReg and and/or ScratchCalleeCopyReg equal to Callee, as long as + // Callee != ScratchDiscReg (since Callee is read after the discriminator + // computation writes its result). + // FIXME: Come up with a cleaner approach. + Register ScratchDiscReg = AArch64::X16; + Register ScratchCalleeCopyReg = AArch64::X17; + if (Callee == ScratchDiscReg) + std::swap(ScratchDiscReg, ScratchCalleeCopyReg); emitPtrauthTailCallHardening(MI); @@ -3281,10 +3305,31 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { // restriction manually not to clobber an unexpected register. bool AddrDiscIsImplicitDef = AddrDisc == AArch64::X16 || AddrDisc == AArch64::X17; - Register DiscReg = emitPtrauthDiscriminator(Disc, AddrDisc, ScratchReg, + Register DiscReg = emitPtrauthDiscriminator(Disc, AddrDisc, ScratchDiscReg, AddrDiscIsImplicitDef); const bool IsZero = DiscReg == AArch64::XZR; + + if (Key == AArch64PACKey::DA || Key == AArch64PACKey::DB) { + // Have to emit separate auth and branch instructions for D-key. + if (Callee != ScratchCalleeCopyReg) + emitMovXReg(ScratchCalleeCopyReg, Callee); + + MCInst AUTInst; + AUTInst.setOpcode(getAUTOpcodeForKey(Key, IsZero)); + AUTInst.addOperand(MCOperand::createReg(ScratchCalleeCopyReg)); + AUTInst.addOperand(MCOperand::createReg(ScratchCalleeCopyReg)); + if (!IsZero) + AUTInst.addOperand(MCOperand::createReg(DiscReg)); + EmitToStreamer(AUTInst); + + MCInst BranchInst; + BranchInst.setOpcode(AArch64::BR); + BranchInst.addOperand(MCOperand::createReg(ScratchCalleeCopyReg)); + EmitToStreamer(BranchInst); + return; + } + const unsigned Opcodes[2][2] = {{AArch64::BRAA, AArch64::BRAAZ}, {AArch64::BRAB, AArch64::BRABZ}}; diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp index b721c1f533726..d002c307c6db9 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -1509,58 +1509,22 @@ void AArch64DAGToDAGISel::SelectTable(SDNode *N, unsigned NumVecs, unsigned Opc, ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, VT, Ops)); } -static std::tuple -extractPtrauthBlendDiscriminators(SDValue Disc, SelectionDAG *DAG) { - SDLoc DL(Disc); - SDValue AddrDisc; - SDValue ConstDisc; - - // If this is a blend, remember the constant and address discriminators. - // Otherwise, it's either a constant discriminator, or a non-blended - // address discriminator. - if (Disc->getOpcode() == ISD::INTRINSIC_WO_CHAIN && - Disc->getConstantOperandVal(0) == Intrinsic::ptrauth_blend) { - AddrDisc = Disc->getOperand(1); - ConstDisc = Disc->getOperand(2); - } else { - ConstDisc = Disc; - } - - // If the constant discriminator (either the blend RHS, or the entire - // discriminator value) isn't a 16-bit constant, bail out, and let the - // discriminator be computed separately. - auto *ConstDiscN = dyn_cast(ConstDisc); - if (!ConstDiscN || !isUInt<16>(ConstDiscN->getZExtValue())) - return std::make_tuple(DAG->getTargetConstant(0, DL, MVT::i64), Disc); - - // If there's no address discriminator, use XZR directly. - if (!AddrDisc) - AddrDisc = DAG->getRegister(AArch64::XZR, MVT::i64); - - return std::make_tuple( - DAG->getTargetConstant(ConstDiscN->getZExtValue(), DL, MVT::i64), - AddrDisc); -} - void AArch64DAGToDAGISel::SelectPtrauthAuth(SDNode *N) { + const AArch64SelectionDAGInfo *SDI = Subtarget->getSelectionDAGInfo(); SDLoc DL(N); - // IntrinsicID is operand #0 - SDValue Val = N->getOperand(1); - SDValue AUTKey = N->getOperand(2); - SDValue AUTDisc = N->getOperand(3); - unsigned AUTKeyC = cast(AUTKey)->getZExtValue(); - AUTKey = CurDAG->getTargetConstant(AUTKeyC, DL, MVT::i64); + assert(N->getOpcode() == ISD::PtrAuthAuth); + SDValue Val = N->getOperand(0); + SDValue AUTSchema = N->getOperand(1); - SDValue AUTAddrDisc, AUTConstDisc; - std::tie(AUTConstDisc, AUTAddrDisc) = - extractPtrauthBlendDiscriminators(AUTDisc, CurDAG); + auto [AUTKey, AUTConstDisc, AUTAddrDisc] = + SDI->extractPtrauthBlendDiscriminators(AUTSchema, CurDAG); if (!Subtarget->isX16X17Safer()) { std::vector Ops = {Val, AUTKey, AUTConstDisc, AUTAddrDisc}; // Copy deactivation symbol if present. - if (N->getNumOperands() > 4) - Ops.push_back(N->getOperand(4)); + if (N->getNumOperands() > 2) + Ops.push_back(N->getOperand(2)); SDNode *AUT = CurDAG->getMachineNode(AArch64::AUTxMxN, DL, MVT::i64, MVT::i64, Ops); @@ -1576,27 +1540,17 @@ void AArch64DAGToDAGISel::SelectPtrauthAuth(SDNode *N) { } void AArch64DAGToDAGISel::SelectPtrauthResign(SDNode *N) { + const AArch64SelectionDAGInfo *SDI = Subtarget->getSelectionDAGInfo(); SDLoc DL(N); - // IntrinsicID is operand #0 - SDValue Val = N->getOperand(1); - SDValue AUTKey = N->getOperand(2); - SDValue AUTDisc = N->getOperand(3); - SDValue PACKey = N->getOperand(4); - SDValue PACDisc = N->getOperand(5); - - unsigned AUTKeyC = cast(AUTKey)->getZExtValue(); - unsigned PACKeyC = cast(PACKey)->getZExtValue(); - - AUTKey = CurDAG->getTargetConstant(AUTKeyC, DL, MVT::i64); - PACKey = CurDAG->getTargetConstant(PACKeyC, DL, MVT::i64); + assert(N->getOpcode() == ISD::PtrAuthResign); + SDValue Val = N->getOperand(0); + SDValue AUTSchema = N->getOperand(1); + SDValue PACSchema = N->getOperand(2); - SDValue AUTAddrDisc, AUTConstDisc; - std::tie(AUTConstDisc, AUTAddrDisc) = - extractPtrauthBlendDiscriminators(AUTDisc, CurDAG); - - SDValue PACAddrDisc, PACConstDisc; - std::tie(PACConstDisc, PACAddrDisc) = - extractPtrauthBlendDiscriminators(PACDisc, CurDAG); + auto [AUTKey, AUTConstDisc, AUTAddrDisc] = + SDI->extractPtrauthBlendDiscriminators(AUTSchema, CurDAG); + auto [PACKey, PACConstDisc, PACAddrDisc] = + SDI->extractPtrauthBlendDiscriminators(PACSchema, CurDAG); SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(), DL, AArch64::X16, Val, SDValue()); @@ -4818,6 +4772,14 @@ void AArch64DAGToDAGISel::Select(SDNode *Node) { default: break; + case ISD::PtrAuthAuth: + SelectPtrauthAuth(Node); + return; + + case ISD::PtrAuthResign: + SelectPtrauthResign(Node); + return; + case ISD::ATOMIC_CMP_SWAP: if (SelectCMP_SWAP(Node)) return; @@ -5799,14 +5761,6 @@ void AArch64DAGToDAGISel::Select(SDNode *Node) { SelectTagP(Node); return; - case Intrinsic::ptrauth_auth: - SelectPtrauthAuth(Node); - return; - - case Intrinsic::ptrauth_resign: - SelectPtrauthResign(Node); - return; - case Intrinsic::aarch64_neon_tbl2: SelectTable(Node, 2, VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two, diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index a83185d6ade20..0aa634b015bd4 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -351,40 +351,6 @@ static bool isZeroingInactiveLanes(SDValue Op) { } } -static std::tuple -extractPtrauthBlendDiscriminators(SDValue Disc, SelectionDAG *DAG) { - SDLoc DL(Disc); - SDValue AddrDisc; - SDValue ConstDisc; - - // If this is a blend, remember the constant and address discriminators. - // Otherwise, it's either a constant discriminator, or a non-blended - // address discriminator. - if (Disc->getOpcode() == ISD::INTRINSIC_WO_CHAIN && - Disc->getConstantOperandVal(0) == Intrinsic::ptrauth_blend) { - AddrDisc = Disc->getOperand(1); - ConstDisc = Disc->getOperand(2); - } else { - ConstDisc = Disc; - } - - // If the constant discriminator (either the blend RHS, or the entire - // discriminator value) isn't a 16-bit constant, bail out, and let the - // discriminator be computed separately. - const auto *ConstDiscN = dyn_cast(ConstDisc); - if (!ConstDiscN || !isUInt<16>(ConstDiscN->getZExtValue())) - return std::make_tuple(DAG->getTargetConstant(0, DL, MVT::i64), Disc); - - // If there's no address discriminator, use NoRegister, which we'll later - // replace with XZR, or directly use a Z variant of the inst. when available. - if (!AddrDisc) - AddrDisc = DAG->getRegister(AArch64::NoRegister, MVT::i64); - - return std::make_tuple( - DAG->getTargetConstant(ConstDiscN->getZExtValue(), DL, MVT::i64), - AddrDisc); -} - AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM, const AArch64Subtarget &STI) : TargetLowering(TM, STI), Subtarget(&STI) { @@ -3295,6 +3261,8 @@ AArch64TargetLowering::EmitEntryPStateSM(MachineInstr &MI, return BB; } +// Used by https://github.com/llvm/llvm-project/pull/130809. +#if 0 // Helper function to find the instruction that defined a virtual register. // If unable to find such instruction, returns nullptr. static const MachineInstr *stripVRegCopies(const MachineRegisterInfo &MRI, @@ -3320,57 +3288,7 @@ static const MachineInstr *stripVRegCopies(const MachineRegisterInfo &MRI, } return nullptr; } - -void AArch64TargetLowering::fixupPtrauthDiscriminator( - MachineInstr &MI, MachineBasicBlock *BB, MachineOperand &IntDiscOp, - MachineOperand &AddrDiscOp, const TargetRegisterClass *AddrDiscRC) const { - const TargetInstrInfo *TII = Subtarget->getInstrInfo(); - MachineRegisterInfo &MRI = MI.getMF()->getRegInfo(); - const DebugLoc &DL = MI.getDebugLoc(); - - Register AddrDisc = AddrDiscOp.getReg(); - int64_t IntDisc = IntDiscOp.getImm(); - assert(IntDisc == 0 && "Blend components are already expanded"); - - const MachineInstr *DiscMI = stripVRegCopies(MRI, AddrDisc); - if (DiscMI) { - switch (DiscMI->getOpcode()) { - case AArch64::MOVKXi: - // blend(addr, imm) which is lowered as "MOVK addr, #imm, #48". - // #imm should be an immediate and not a global symbol, for example. - if (DiscMI->getOperand(2).isImm() && - DiscMI->getOperand(3).getImm() == 48) { - AddrDisc = DiscMI->getOperand(1).getReg(); - IntDisc = DiscMI->getOperand(2).getImm(); - } - break; - case AArch64::MOVi32imm: - case AArch64::MOVi64imm: - // Small immediate integer constant passed via VReg. - if (DiscMI->getOperand(1).isImm() && - isUInt<16>(DiscMI->getOperand(1).getImm())) { - AddrDisc = AArch64::NoRegister; - IntDisc = DiscMI->getOperand(1).getImm(); - } - break; - } - } - - // For uniformity, always use NoRegister, as XZR is not necessarily contained - // in the requested register class. - if (AddrDisc == AArch64::XZR) - AddrDisc = AArch64::NoRegister; - - // Make sure AddrDisc operand respects the register class imposed by MI. - if (AddrDisc && MRI.getRegClass(AddrDisc) != AddrDiscRC) { - Register TmpReg = MRI.createVirtualRegister(AddrDiscRC); - BuildMI(*BB, MI, DL, TII->get(AArch64::COPY), TmpReg).addReg(AddrDisc); - AddrDisc = TmpReg; - } - - AddrDiscOp.setReg(AddrDisc); - IntDiscOp.setImm(IntDisc); -} +#endif MachineBasicBlock *AArch64TargetLowering::EmitInstrWithCustomInserter( MachineInstr &MI, MachineBasicBlock *BB) const { @@ -3477,8 +3395,6 @@ MachineBasicBlock *AArch64TargetLowering::EmitInstrWithCustomInserter( return EmitZTInstr(MI, BB, AArch64::MOVT_TIZ, /*Op0IsDef=*/true); case AArch64::PAC: - fixupPtrauthDiscriminator(MI, BB, MI.getOperand(3), MI.getOperand(4), - &AArch64::GPR64noipRegClass); return BB; } } @@ -9562,6 +9478,7 @@ static bool shouldLowerTailCallStackArg(const MachineFunction &MF, SDValue AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI, SmallVectorImpl &InVals) const { + const AArch64SelectionDAGInfo *SDI = Subtarget->getSelectionDAGInfo(); SelectionDAG &DAG = CLI.DAG; SDLoc &DL = CLI.DL; SmallVector &Outs = CLI.Outs; @@ -10157,20 +10074,14 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI, } if (CLI.PAI) { - const uint64_t Key = CLI.PAI->Key; - assert((Key == AArch64PACKey::IA || Key == AArch64PACKey::IB) && - "Invalid auth call key"); - - // Split the discriminator into address/integer components. - SDValue AddrDisc, IntDisc; - std::tie(IntDisc, AddrDisc) = - extractPtrauthBlendDiscriminators(CLI.PAI->Discriminator, &DAG); + auto [Key, IntDisc, AddrDisc] = + SDI->extractPtrauthBlendDiscriminators(CLI.PAI->Operands, DL, &DAG); if (Opc == AArch64ISD::CALL_RVMARKER) Opc = AArch64ISD::AUTH_CALL_RVMARKER; else Opc = IsTailCall ? AArch64ISD::AUTH_TC_RETURN : AArch64ISD::AUTH_CALL; - Ops.push_back(DAG.getTargetConstant(Key, DL, MVT::i32)); + Ops.push_back(Key); Ops.push_back(IntDisc); Ops.push_back(AddrDisc); } @@ -10674,7 +10585,7 @@ AArch64TargetLowering::LowerDarwinGlobalTLSAddress(SDValue Op, // With ptrauth-calls, the tlv access thunk pointer is authenticated (IA, 0). if (DAG.getMachineFunction().getFunction().hasFnAttribute("ptrauth-calls")) { Opcode = AArch64ISD::AUTH_CALL; - Ops.push_back(DAG.getTargetConstant(AArch64PACKey::IA, DL, MVT::i32)); + Ops.push_back(DAG.getTargetConstant(AArch64PACKey::IA, DL, MVT::i64)); Ops.push_back(DAG.getTargetConstant(0, DL, MVT::i64)); // Integer Disc. Ops.push_back(DAG.getRegister(AArch64::NoRegister, MVT::i64)); // Addr Disc. } @@ -11032,8 +10943,8 @@ SDValue AArch64TargetLowering::LowerGlobalTLSAddress(SDValue Op, // checks. static SDValue LowerPtrAuthGlobalAddressStatically( - SDValue TGA, SDLoc DL, EVT VT, AArch64PACKey::ID KeyC, - SDValue Discriminator, SDValue AddrDiscriminator, SelectionDAG &DAG) { + SDValue TGA, SDLoc DL, EVT VT, SDValue Key, SDValue Discriminator, + SDValue AddrDiscriminator, SelectionDAG &DAG) { const auto *TGN = cast(TGA.getNode()); assert(TGN->getGlobal()->hasExternalWeakLinkage()); @@ -11045,10 +10956,10 @@ static SDValue LowerPtrAuthGlobalAddressStatically( report_fatal_error( "unsupported non-zero offset in weak ptrauth global reference"); - if (!isNullConstant(AddrDiscriminator)) + auto *AddrDiscReg = dyn_cast(AddrDiscriminator); + if (!AddrDiscReg || AddrDiscReg->getReg() != AArch64::NoRegister) report_fatal_error("unsupported weak addr-div ptrauth global"); - SDValue Key = DAG.getTargetConstant(KeyC, DL, MVT::i32); return SDValue(DAG.getMachineNode(AArch64::LOADauthptrstatic, DL, MVT::i64, {TGA, Key, Discriminator}), 0); @@ -11057,21 +10968,13 @@ static SDValue LowerPtrAuthGlobalAddressStatically( SDValue AArch64TargetLowering::LowerPtrAuthGlobalAddress(SDValue Op, SelectionDAG &DAG) const { + const AArch64SelectionDAGInfo *SDI = Subtarget->getSelectionDAGInfo(); SDValue Ptr = Op.getOperand(0); - uint64_t KeyC = Op.getConstantOperandVal(1); - SDValue AddrDiscriminator = Op.getOperand(2); - uint64_t DiscriminatorC = Op.getConstantOperandVal(3); EVT VT = Op.getValueType(); SDLoc DL(Op); - if (KeyC > AArch64PACKey::LAST) - report_fatal_error("key in ptrauth global out of range [0, " + - Twine((int)AArch64PACKey::LAST) + "]"); - - // Blend only works if the integer discriminator is 16-bit wide. - if (!isUInt<16>(DiscriminatorC)) - report_fatal_error( - "constant discriminator in ptrauth global out of range [0, 0xffff]"); + auto [Key, Discriminator, AddrDiscriminator] = + SDI->extractPtrauthBlendDiscriminators(Op.getOperand(1), &DAG); // Choosing between 3 lowering alternatives is target-specific. if (!Subtarget->isTargetELF() && !Subtarget->isTargetMachO()) @@ -11099,8 +11002,6 @@ AArch64TargetLowering::LowerPtrAuthGlobalAddress(SDValue Op, assert(PtrN->getTargetFlags() == 0 && "unsupported target flags on ptrauth global"); - SDValue Key = DAG.getTargetConstant(KeyC, DL, MVT::i32); - SDValue Discriminator = DAG.getTargetConstant(DiscriminatorC, DL, MVT::i64); SDValue TAddrDiscriminator = !isNullConstant(AddrDiscriminator) ? AddrDiscriminator : DAG.getRegister(AArch64::XZR, MVT::i64); @@ -11124,8 +11025,7 @@ AArch64TargetLowering::LowerPtrAuthGlobalAddress(SDValue Op, // extern_weak ref -> LOADauthptrstatic return LowerPtrAuthGlobalAddressStatically( - TPtr, DL, VT, (AArch64PACKey::ID)KeyC, Discriminator, AddrDiscriminator, - DAG); + TPtr, DL, VT, Key, Discriminator, AddrDiscriminator, DAG); } // Looks through \param Val to determine the bit that can be used to @@ -30034,6 +29934,59 @@ bool AArch64TargetLowering::preferSelectsOverBooleanArithmetic(EVT VT) const { return !VT.isFixedLengthVector(); } +std::optional +AArch64TargetLowering::validatePtrAuthSchema(const Value &V) const { + auto GetMsg = [&V](Twine Str) -> std::string { + if (auto *CB = dyn_cast(&V)) + return (CB->getFunction()->getName() + ": " + Str).str(); + return Str.str(); + }; + + auto ValidateSchema = [&](ArrayRef Schema, bool ExpectSingleElement) -> std::optional{ + unsigned NumOperands = Schema.size(); + if (ExpectSingleElement) { + if (NumOperands != 1) + return GetMsg("single-element ptrauth bundle expected"); + } else { + if (NumOperands != 3) + return GetMsg("three-element ptrauth bundle expected"); + } + + // The first operand is always the key ID. + auto *Key = dyn_cast(Schema[0]); + if (!Key || Key->getZExtValue() > AArch64PACKey::LAST) + return GetMsg("key must be constant in range [0, " + + Twine((int)AArch64PACKey::LAST) + "]"); + + // Done validating single-operand bundles. + if (NumOperands == 1) + return std::nullopt; + + auto *IntDisc = dyn_cast(Schema[1]); + if (!IntDisc || !isUInt<16>(IntDisc->getZExtValue())) + return GetMsg("constant modifier must be 16-bit unsigned constant"); + + return std::nullopt; + }; + + if (auto *CB = dyn_cast(&V)) { + for (unsigned I = 0, N = CB->getNumOperandBundles(); I < N; ++I) { + OperandBundleUse OB = CB->getOperandBundleAt(I); + if (OB.getTagID() != LLVMContext::OB_ptrauth) + continue; + + bool ExpectSingleElement = + CB->getIntrinsicID() == Intrinsic::ptrauth_strip; + if (auto Err = ValidateSchema(OB.Inputs, ExpectSingleElement)) + return Err; + } + return std::nullopt; + } + + auto &CPA = cast(V); + return ValidateSchema(CPA.getSchema(), /*ExpectSingleElement=*/false); +} + MachineInstr * AArch64TargetLowering::EmitKCFICheck(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator &MBBI, diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h index 1d4446d287462..34081ed2d5072 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -195,13 +195,6 @@ class AArch64TargetLowering : public TargetLowering { MachineBasicBlock *EmitEntryPStateSM(MachineInstr &MI, MachineBasicBlock *BB) const; - /// Replace (0, vreg) discriminator components with the operands of blend - /// or with (immediate, NoRegister) when possible. - void fixupPtrauthDiscriminator(MachineInstr &MI, MachineBasicBlock *BB, - MachineOperand &IntDiscOp, - MachineOperand &AddrDiscOp, - const TargetRegisterClass *AddrDiscRC) const; - MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override; @@ -472,7 +465,8 @@ class AArch64TargetLowering : public TargetLowering { return true; } - bool supportPtrAuthBundles() const override { return true; } + std::optional + validatePtrAuthSchema(const Value &V) const override; bool supportKCFIBundles() const override { return true; } diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index da93a2b13fc11..ad8a274f0a3fe 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -817,7 +817,7 @@ def AArch64call_arm64ec_to_x64 : SDNode<"AArch64ISD::CALL_ARM64EC_TO_X64", // AUTH_CALL chain, callee, auth key #, int disc, addr disc, operands. def AArch64authcall : SDNode<"AArch64ISD::AUTH_CALL", SDTypeProfile<0, -1, [SDTCisPtrTy<0>, - SDTCisVT<1, i32>, + SDTCisVT<1, i64>, SDTCisVT<2, i64>, SDTCisVT<3, i64>]>, [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, @@ -827,7 +827,7 @@ def AArch64authcall : SDNode<"AArch64ISD::AUTH_CALL", // operands. def AArch64authtcret: SDNode<"AArch64ISD::AUTH_TC_RETURN", SDTypeProfile<0, 5, [SDTCisPtrTy<0>, - SDTCisVT<2, i32>, + SDTCisVT<2, i64>, SDTCisVT<3, i64>, SDTCisVT<4, i64>]>, [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; @@ -837,7 +837,7 @@ def AArch64authcall_rvmarker : SDNode<"AArch64ISD::AUTH_CALL_RVMARKER", SDTypeProfile<0, -1, [SDTCisPtrTy<0>, SDTCisVT<1, i32>, SDTCisPtrTy<2>, - SDTCisVT<3, i32>, + SDTCisVT<3, i64>, SDTCisVT<4, i64>, SDTCisVT<5, i64>]>, [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, @@ -2091,12 +2091,12 @@ let Predicates = [HasPAuth] in { defm AUT : SignAuth<0b001, 0b011, "aut", null_frag>; def XPACI : ClearAuth<0, "xpaci">; - def : Pat<(int_ptrauth_strip GPR64:$Rd, 0), (XPACI GPR64:$Rd)>; - def : Pat<(int_ptrauth_strip GPR64:$Rd, 1), (XPACI GPR64:$Rd)>; + def : Pat<(ptrauth_strip GPR64:$Rd, (ptrauth_bundle (i64 0))), (XPACI GPR64:$Rd)>; + def : Pat<(ptrauth_strip GPR64:$Rd, (ptrauth_bundle (i64 1))), (XPACI GPR64:$Rd)>; def XPACD : ClearAuth<1, "xpacd">; - def : Pat<(int_ptrauth_strip GPR64:$Rd, 2), (XPACD GPR64:$Rd)>; - def : Pat<(int_ptrauth_strip GPR64:$Rd, 3), (XPACD GPR64:$Rd)>; + def : Pat<(ptrauth_strip GPR64:$Rd, (ptrauth_bundle (i64 2))), (XPACD GPR64:$Rd)>; + def : Pat<(ptrauth_strip GPR64:$Rd, (ptrauth_bundle (i64 3))), (XPACD GPR64:$Rd)>; def PACGA : SignAuthTwoOperand<0b1100, "pacga", int_ptrauth_sign_generic>; @@ -2125,7 +2125,7 @@ let Predicates = [HasPAuth] in { // operations (such as raw address manipulation or discriminator // materialization here), in part because they're handled in a safer way by // the kernel, notably on Darwin. - def BLRA : Pseudo<(outs), (ins GPR64noip:$Rn, i32imm:$Key, i64imm:$Disc, + def BLRA : Pseudo<(outs), (ins GPR64noip:$Rn, i64imm:$Key, i64imm:$Disc, GPR64:$AddrDisc), [(AArch64authcall GPR64noip:$Rn, timm:$Key, timm:$Disc, GPR64:$AddrDisc)]>, Sched<[]> { @@ -2134,14 +2134,14 @@ let Predicates = [HasPAuth] in { let mayStore = 0; let mayLoad = 0; let isCall = 1; - let Size = 12; // 4 fixed + 8 variable, to compute discriminator. + let Size = 20; // See AUTH_TCRETURN. let Defs = [X16,X17,LR]; let Uses = [SP]; } def BLRA_RVMARKER : Pseudo< (outs), (ins i64imm:$rvfunc, i32imm:$withmarker, GPR64noip:$Rn, - i32imm:$Key, i64imm:$Disc, GPR64:$AddrDisc), + i64imm:$Key, i64imm:$Disc, GPR64:$AddrDisc), [(AArch64authcall_rvmarker tglobaladdr:$rvfunc, timm:$withmarker, GPR64noip:$Rn, timm:$Key, timm:$Disc, GPR64:$AddrDisc)]>, Sched<[]> { @@ -2154,7 +2154,7 @@ let Predicates = [HasPAuth] in { // BRA pseudo, generalized version of BRAA/BRAB/Z. // This directly manipulates x16/x17, which are the only registers the OS // guarantees are safe to use for sensitive operations. - def BRA : Pseudo<(outs), (ins GPR64noip:$Rn, i32imm:$Key, i64imm:$Disc, + def BRA : Pseudo<(outs), (ins GPR64noip:$Rn, i64imm:$Key, i64imm:$Disc, GPR64noip:$AddrDisc), []>, Sched<[]> { let isCodeGenOnly = 1; let hasNoSchedulingInfo = 1; @@ -2165,8 +2165,8 @@ let Predicates = [HasPAuth] in { let isTerminator = 1; let isBarrier = 1; let isIndirectBranch = 1; - let Size = 12; // 4 fixed + 8 variable, to compute discriminator. - let Defs = [X17]; + let Size = 20; // See AUTH_TCRETURN. + let Defs = [X16, X17]; } let isReturn = 1, isTerminator = 1, isBarrier = 1 in { @@ -2182,7 +2182,7 @@ let Predicates = [HasPAuth] in { // AUT pseudo. // This directly manipulates x16/x17, which are the only registers that // certain OSs guarantee are safe to use for sensitive operations. - def AUTx16x17 : Pseudo<(outs), (ins i32imm:$Key, i64imm:$Disc, + def AUTx16x17 : Pseudo<(outs), (ins i64imm:$Key, i64imm:$Disc, GPR64noip:$AddrDisc), []>, Sched<[WriteI, ReadI]> { let isCodeGenOnly = 1; @@ -2195,9 +2195,9 @@ let Predicates = [HasPAuth] in { } def AUTxMxN : Pseudo<(outs GPR64:$AuthVal, GPR64common:$Scratch), - (ins GPR64:$Val, i32imm:$Key, + (ins GPR64:$Val, i64imm:$Key, i64imm:$Disc, GPR64:$AddrDisc), - [], "$AuthVal = $Val">, Sched<[WriteI, ReadI]> { + [], "$AuthVal = $Val,@earlyclobber $Scratch">, Sched<[WriteI, ReadI]> { let isCodeGenOnly = 1; let hasSideEffects = 1; let mayStore = 0; @@ -2212,7 +2212,7 @@ let Predicates = [HasPAuth] in { // This enforces the expected immediate modifier is used for signing, even // if an attacker is able to substitute AddrDisc. def PAC : Pseudo<(outs GPR64:$SignedVal), - (ins GPR64:$Val, i32imm:$Key, i64imm:$Disc, GPR64noip:$AddrDisc), + (ins GPR64:$Val, i64imm:$Key, i64imm:$Disc, GPR64noip:$AddrDisc), [], "$SignedVal = $Val">, Sched<[WriteI, ReadI]> { let isCodeGenOnly = 1; let hasSideEffects = 0; @@ -2224,17 +2224,22 @@ let Predicates = [HasPAuth] in { let supportsDeactivationSymbol = true; } - // A standalone pattern is used, so that literal 0 can be passed as $Disc. - def : Pat<(int_ptrauth_sign GPR64:$Val, timm:$Key, GPR64noip:$AddrDisc), - (PAC GPR64:$Val, $Key, 0, GPR64noip:$AddrDisc)>; + def : Pat<(ptrauth_sign GPR64:$Val, (ptrauth_bundle (i64 imm:$Key), + (i64 imm:$Disc), + (i64 0))), + (PAC GPR64:$Val, imm:$Key, imm:$Disc, zero_reg)>; + def : Pat<(ptrauth_sign GPR64:$Val, (ptrauth_bundle (i64 imm:$Key), + (i64 imm:$Disc), + GPR64noip:$AddrDisc)), + (PAC GPR64:$Val, imm:$Key, imm:$Disc, GPR64noip:$AddrDisc)>; // AUT and re-PAC a value, using different keys/data. // This directly manipulates x16/x17, which are the only registers that // certain OSs guarantee are safe to use for sensitive operations. def AUTPAC : Pseudo<(outs), - (ins i32imm:$AUTKey, i64imm:$AUTDisc, GPR64noip:$AUTAddrDisc, - i32imm:$PACKey, i64imm:$PACDisc, GPR64noip:$PACAddrDisc), + (ins i64imm:$AUTKey, i64imm:$AUTDisc, GPR64noip:$AUTAddrDisc, + i64imm:$PACKey, i64imm:$PACDisc, GPR64noip:$PACAddrDisc), []>, Sched<[WriteI, ReadI]> { let isCodeGenOnly = 1; let hasSideEffects = 1; @@ -2247,7 +2252,7 @@ let Predicates = [HasPAuth] in { // Materialize a signed global address, with adrp+add and PAC. def MOVaddrPAC : Pseudo<(outs), - (ins i64imm:$Addr, i32imm:$Key, + (ins i64imm:$Addr, i64imm:$Key, GPR64noip:$AddrDisc, i64imm:$Disc), []>, Sched<[WriteI, ReadI]> { let isReMaterializable = 1; @@ -2258,7 +2263,7 @@ let Predicates = [HasPAuth] in { // Materialize a signed global address, using a GOT load and PAC. def LOADgotPAC : Pseudo<(outs), - (ins i64imm:$Addr, i32imm:$Key, + (ins i64imm:$Addr, i64imm:$Key, GPR64noip:$AddrDisc, i64imm:$Disc), []>, Sched<[WriteI, ReadI]> { let isReMaterializable = 1; @@ -2276,7 +2281,7 @@ let Predicates = [HasPAuth] in { // Load a signed global address from a special $auth_ptr$ stub slot. def LOADauthptrstatic : Pseudo<(outs GPR64:$dst), - (ins i64imm:$Addr, i32imm:$Key, + (ins i64imm:$Addr, i64imm:$Key, i64imm:$Disc), []>, Sched<[WriteI, ReadI]> { let isReMaterializable = 1; @@ -2284,34 +2289,35 @@ let Predicates = [HasPAuth] in { let Size = 8; } - // Size 16: 4 fixed + 8 variable, to compute discriminator. + // Size 20: up to 8 to compute discriminator and up to 12 to MOV, AUTD(A|B) + // and branch. // The size returned by getInstSizeInBytes() is incremented according // to the variant of LR check. // As the check requires either x16 or x17 as a scratch register and // authenticated tail call instructions have two register operands, // make sure at least one register is usable as a scratch one - for that // purpose, use tcGPRnotx16x17 register class for one of the operands. - let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Size = 16, + let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Size = 20, Defs = [X16,X17], Uses = [SP] in { def AUTH_TCRETURN - : Pseudo<(outs), (ins tcGPRnotx16x17:$dst, i32imm:$FPDiff, i32imm:$Key, + : Pseudo<(outs), (ins tcGPRnotx16x17:$dst, i32imm:$FPDiff, i64imm:$Key, i64imm:$Disc, tcGPR64:$AddrDisc), []>, Sched<[WriteBrReg]>; def AUTH_TCRETURN_BTI - : Pseudo<(outs), (ins tcGPRx16x17:$dst, i32imm:$FPDiff, i32imm:$Key, + : Pseudo<(outs), (ins tcGPRx16x17:$dst, i32imm:$FPDiff, i64imm:$Key, i64imm:$Disc, tcGPRnotx16x17:$AddrDisc), []>, Sched<[WriteBrReg]>; } let Predicates = [TailCallAny] in - def : Pat<(AArch64authtcret tcGPRnotx16x17:$dst, (i32 timm:$FPDiff), (i32 timm:$Key), + def : Pat<(AArch64authtcret tcGPRnotx16x17:$dst, (i32 timm:$FPDiff), (i64 timm:$Key), (i64 timm:$Disc), tcGPR64:$AddrDisc), (AUTH_TCRETURN tcGPRnotx16x17:$dst, imm:$FPDiff, imm:$Key, imm:$Disc, tcGPR64:$AddrDisc)>; let Predicates = [TailCallX16X17] in def : Pat<(AArch64authtcret tcGPRx16x17:$dst, (i32 timm:$FPDiff), - (i32 timm:$Key), (i64 timm:$Disc), + (i64 timm:$Key), (i64 timm:$Disc), tcGPRnotx16x17:$AddrDisc), (AUTH_TCRETURN_BTI tcGPRx16x17:$dst, imm:$FPDiff, imm:$Key, imm:$Disc, tcGPRnotx16x17:$AddrDisc)>; @@ -10903,14 +10909,6 @@ let Predicates = [HasMOPS_GO, HasMTE] in { defm SETGOE : MOPSGoMemorySetTaggingInsns<0b10, "setgoe">; } -//----------------------------------------------------------------------------- -// v8.3 Pointer Authentication late patterns - -def : Pat<(int_ptrauth_blend GPR64:$Rd, imm64_0_65535:$imm), - (MOVKXi GPR64:$Rd, (trunc_imm imm64_0_65535:$imm), 48)>; -def : Pat<(int_ptrauth_blend GPR64:$Rd, GPR64:$Rn), - (BFMXri GPR64:$Rd, GPR64:$Rn, 16, 15)>; - //----------------------------------------------------------------------------- // This gets lowered into an instruction sequence of 20 bytes diff --git a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp index 48e03ad853d26..0916bf632f39e 100644 --- a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.cpp @@ -12,6 +12,7 @@ #include "AArch64SelectionDAGInfo.h" #include "AArch64MachineFunctionInfo.h" +#include "llvm/CodeGen/SDPatternMatch.h" #define GET_SDNODE_DESC #include "AArch64GenSDNodeInfo.inc" @@ -341,3 +342,33 @@ SDValue AArch64SelectionDAGInfo::EmitTargetCodeForSetTag( DAG.setNodeMemRefs(cast(St), {BaseMemOperand}); return SDValue(St, 2); } + +std::tuple +AArch64SelectionDAGInfo::extractPtrauthBlendDiscriminators( + ArrayRef Operands, const SDLoc &DL, SelectionDAG *DAG) const { + using namespace SDPatternMatch; + + assert(Operands.size() == 3); + + auto *KeyN = cast(Operands[0]); + auto *ConstDiscN = cast(Operands[1]); + + SDValue AddrDisc = Operands[2]; + if (sd_match(AddrDisc, m_SpecificInt(0))) + AddrDisc = DAG->getRegister(AArch64::NoRegister, MVT::i64); + + return std::make_tuple( + DAG->getTargetConstant(KeyN->getZExtValue(), DL, MVT::i64), + DAG->getTargetConstant(ConstDiscN->getZExtValue(), DL, MVT::i64), + AddrDisc); +} + +std::tuple +AArch64SelectionDAGInfo::extractPtrauthBlendDiscriminators( + SDValue Bundle, SelectionDAG *DAG) const { + assert(Bundle->getOpcode() == ISD::PtrAuthBundle); + SDLoc DL(Bundle); + SmallVector Operands(Bundle->ops()); + + return extractPtrauthBlendDiscriminators(Operands, DL, DAG); +} diff --git a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.h b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.h index 42c2797ebdd17..42287350cd793 100644 --- a/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.h +++ b/llvm/lib/Target/AArch64/AArch64SelectionDAGInfo.h @@ -62,6 +62,13 @@ class AArch64SelectionDAGInfo : public SelectionDAGGenTargetInfo { SDValue Chain, SDValue Dst, SDValue Src, SDValue Size, RTLIB::Libcall LC) const; + + std::tuple + extractPtrauthBlendDiscriminators(ArrayRef Operands, const SDLoc &DL, + SelectionDAG *DAG) const; + + std::tuple + extractPtrauthBlendDiscriminators(SDValue Bundle, SelectionDAG *DAG) const; }; } // namespace llvm diff --git a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp index 7907a3c283624..a339d2c161b8c 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp @@ -1079,8 +1079,6 @@ static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, return IsIndirect ? getBLRCallOpcode(CallerF) : (unsigned)AArch64::BL; assert(IsIndirect && "Direct call should not be authenticated"); - assert((PAI->Key == AArch64PACKey::IA || PAI->Key == AArch64PACKey::IB) && - "Invalid auth call key"); return AArch64::BLRA; } @@ -1165,16 +1163,10 @@ bool AArch64CallLowering::lowerTailCall( // Authenticated tail calls always take key/discriminator arguments. if (Opc == AArch64::AUTH_TCRETURN || Opc == AArch64::AUTH_TCRETURN_BTI) { - assert((Info.PAI->Key == AArch64PACKey::IA || - Info.PAI->Key == AArch64PACKey::IB) && - "Invalid auth call key"); - MIB.addImm(Info.PAI->Key); - - Register AddrDisc = 0; - uint16_t IntDisc = 0; - std::tie(IntDisc, AddrDisc) = - extractPtrauthBlendDiscriminators(Info.PAI->Discriminator, MRI); + auto [Key, IntDisc, AddrDisc] = + extractPtrauthBlendDiscriminators(Info.PAI->Operands, MRI); + MIB.addImm(Key); MIB.addImm(IntDisc); MIB.addUse(AddrDisc); if (AddrDisc != AArch64::NoRegister) { @@ -1440,16 +1432,9 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, Mask = getMaskForArgs(OutArgs, Info, *TRI, MF); if (Opc == AArch64::BLRA || Opc == AArch64::BLRA_RVMARKER) { - assert((Info.PAI->Key == AArch64PACKey::IA || - Info.PAI->Key == AArch64PACKey::IB) && - "Invalid auth call key"); - MIB.addImm(Info.PAI->Key); - - Register AddrDisc = 0; - uint16_t IntDisc = 0; - std::tie(IntDisc, AddrDisc) = - extractPtrauthBlendDiscriminators(Info.PAI->Discriminator, MRI); - + auto [Key, IntDisc, AddrDisc] = + extractPtrauthBlendDiscriminators(Info.PAI->Operands, MRI); + MIB.addImm(Key); MIB.addImm(IntDisc); MIB.addUse(AddrDisc); if (AddrDisc != AArch64::NoRegister) { diff --git a/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.cpp b/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.cpp index 1a1507512c899..3785c994836bd 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.cpp @@ -96,33 +96,33 @@ bool AArch64GISelUtils::tryEmitBZero(MachineInstr &MI, return true; } -std::tuple -AArch64GISelUtils::extractPtrauthBlendDiscriminators(Register Disc, - MachineRegisterInfo &MRI) { - Register AddrDisc = Disc; - uint16_t ConstDisc = 0; +std::tuple +AArch64GISelUtils::extractPtrauthBlendDiscriminators( + SmallVector Operands, MachineRegisterInfo &MRI) { + assert(Operands.size() == 3); - if (auto ConstDiscVal = getIConstantVRegVal(Disc, MRI)) { - if (isUInt<16>(ConstDiscVal->getZExtValue())) { - ConstDisc = ConstDiscVal->getZExtValue(); - AddrDisc = AArch64::NoRegister; - } - return std::make_tuple(ConstDisc, AddrDisc); - } + uint64_t KeyVal = getIConstantVRegVal(Operands[0], MRI)->getZExtValue(); + uint64_t ConstDiscVal = getIConstantVRegVal(Operands[1], MRI)->getZExtValue(); + assert(isUInt<16>(ConstDiscVal)); - const MachineInstr *DiscMI = MRI.getVRegDef(Disc); - if (!DiscMI || DiscMI->getOpcode() != TargetOpcode::G_INTRINSIC || - DiscMI->getOperand(1).getIntrinsicID() != Intrinsic::ptrauth_blend) - return std::make_tuple(ConstDisc, AddrDisc); + Register AddrDisc = Operands[2]; + std::optional AddrDiscVal = getIConstantVRegVal(AddrDisc, MRI); + if (AddrDiscVal && AddrDiscVal->isZero()) + AddrDisc = AArch64::NoRegister; - if (auto ConstDiscVal = - getIConstantVRegVal(DiscMI->getOperand(3).getReg(), MRI)) { - if (isUInt<16>(ConstDiscVal->getZExtValue())) { - ConstDisc = ConstDiscVal->getZExtValue(); - AddrDisc = DiscMI->getOperand(2).getReg(); - } - } - return std::make_tuple(ConstDisc, AddrDisc); + return { KeyVal, ConstDiscVal, AddrDisc }; +} + +std::tuple +AArch64GISelUtils::extractPtrauthBlendDiscriminators(Register BundleToken, + MachineRegisterInfo &MRI) { + assert(MRI.getType(BundleToken).isToken()); + const MachineInstr *Bundle = MRI.getVRegDef(BundleToken); + assert(Bundle->getOpcode() == TargetOpcode::G_PTRAUTH_BUNDLE); + SmallVector Ops; + for (auto &Op : Bundle->uses()) + Ops.push_back(Op.getReg()); + return extractPtrauthBlendDiscriminators(Ops, MRI); } void AArch64GISelUtils::changeFCMPPredToAArch64CC( diff --git a/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.h b/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.h index 9ef833f0fc0ca..f77dbccf5b309 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.h +++ b/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.h @@ -53,11 +53,15 @@ bool isCMN(const MachineInstr *MaybeSub, const CmpInst::Predicate &Pred, /// \returns true if \p MI was replaced with a G_BZERO. bool tryEmitBZero(MachineInstr &MI, MachineIRBuilder &MIRBuilder, bool MinSize); -/// Analyze a ptrauth discriminator value to try to find the constant integer -/// and address parts, cracking a ptrauth_blend intrinsic if there is one. -/// \returns integer/address disc. parts, with NoRegister if no address disc. -std::tuple -extractPtrauthBlendDiscriminators(Register Disc, MachineRegisterInfo &MRI); +/// Analyze a ptrauth bundle and return the key ID, constant integer and +/// address parts. +/// \returns (Key, IntDisc, AddrDisc), with NoRegister if no address disc. +std::tuple +extractPtrauthBlendDiscriminators(SmallVector Operands, + MachineRegisterInfo &MRI); +std::tuple +extractPtrauthBlendDiscriminators(Register BundleToken, + MachineRegisterInfo &MRI); /// Find the AArch64 condition codes necessary to represent \p P for a scalar /// floating point comparison. diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp index f9db39e5f8622..612059267d346 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp @@ -2593,6 +2593,67 @@ bool AArch64InstructionSelector::select(MachineInstr &I) { I.getOperand(0).isReg() ? MRI.getType(I.getOperand(0).getReg()) : LLT{}; switch (Opcode) { + case TargetOpcode::G_PTRAUTH_AUTH: { + Register DstReg = I.getOperand(0).getReg(); + Register ValReg = I.getOperand(1).getReg(); + Register Schema = I.getOperand(2).getReg(); + + auto [AUTKey, AUTConstDiscC, AUTAddrDisc] = + extractPtrauthBlendDiscriminators(Schema, MRI); + + if (STI.isX16X17Safer()) { + MIB.buildCopy({AArch64::X16}, {ValReg}); + MIB.buildInstr(TargetOpcode::IMPLICIT_DEF, {AArch64::X17}, {}); + MIB.buildInstr(AArch64::AUTx16x17) + .addImm(AUTKey) + .addImm(AUTConstDiscC) + .addUse(AUTAddrDisc) + .constrainAllUses(TII, TRI, RBI); + MIB.buildCopy({DstReg}, Register(AArch64::X16)); + } else { + Register ScratchReg = + MRI.createVirtualRegister(&AArch64::GPR64commonRegClass); + MIB.buildInstr(AArch64::AUTxMxN) + .addDef(DstReg) + .addDef(ScratchReg) + .addUse(ValReg) + .addImm(AUTKey) + .addImm(AUTConstDiscC) + .addUse(AUTAddrDisc) + .constrainAllUses(TII, TRI, RBI); + } + + RBI.constrainGenericRegister(DstReg, AArch64::GPR64RegClass, MRI); + I.eraseFromParent(); + return true; + } + case TargetOpcode::G_PTRAUTH_RESIGN: { + Register DstReg = I.getOperand(0).getReg(); + Register ValReg = I.getOperand(1).getReg(); + Register AUTSchema = I.getOperand(2).getReg(); + Register PACSchema = I.getOperand(3).getReg(); + + auto [AUTKey, AUTConstDiscC, AUTAddrDisc] = + extractPtrauthBlendDiscriminators(AUTSchema, MRI); + auto [PACKey, PACConstDiscC, PACAddrDisc] = + extractPtrauthBlendDiscriminators(PACSchema, MRI); + + MIB.buildCopy({AArch64::X16}, {ValReg}); + MIB.buildInstr(TargetOpcode::IMPLICIT_DEF, {AArch64::X17}, {}); + MIB.buildInstr(AArch64::AUTPAC) + .addImm(AUTKey) + .addImm(AUTConstDiscC) + .addUse(AUTAddrDisc) + .addImm(PACKey) + .addImm(PACConstDiscC) + .addUse(PACAddrDisc) + .constrainAllUses(TII, TRI, RBI); + MIB.buildCopy({DstReg}, Register(AArch64::X16)); + + RBI.constrainGenericRegister(DstReg, AArch64::GPR64RegClass, MRI); + I.eraseFromParent(); + return true; + } case TargetOpcode::G_SBFX: case TargetOpcode::G_UBFX: { static const unsigned OpcTable[2][2] = { @@ -6615,77 +6676,6 @@ bool AArch64InstructionSelector::selectIntrinsic(MachineInstr &I, switch (IntrinID) { default: break; - case Intrinsic::ptrauth_resign: { - Register DstReg = I.getOperand(0).getReg(); - Register ValReg = I.getOperand(2).getReg(); - uint64_t AUTKey = I.getOperand(3).getImm(); - Register AUTDisc = I.getOperand(4).getReg(); - uint64_t PACKey = I.getOperand(5).getImm(); - Register PACDisc = I.getOperand(6).getReg(); - - Register AUTAddrDisc = AUTDisc; - uint16_t AUTConstDiscC = 0; - std::tie(AUTConstDiscC, AUTAddrDisc) = - extractPtrauthBlendDiscriminators(AUTDisc, MRI); - - Register PACAddrDisc = PACDisc; - uint16_t PACConstDiscC = 0; - std::tie(PACConstDiscC, PACAddrDisc) = - extractPtrauthBlendDiscriminators(PACDisc, MRI); - - MIB.buildCopy({AArch64::X16}, {ValReg}); - MIB.buildInstr(TargetOpcode::IMPLICIT_DEF, {AArch64::X17}, {}); - MIB.buildInstr(AArch64::AUTPAC) - .addImm(AUTKey) - .addImm(AUTConstDiscC) - .addUse(AUTAddrDisc) - .addImm(PACKey) - .addImm(PACConstDiscC) - .addUse(PACAddrDisc) - .constrainAllUses(TII, TRI, RBI); - MIB.buildCopy({DstReg}, Register(AArch64::X16)); - - RBI.constrainGenericRegister(DstReg, AArch64::GPR64RegClass, MRI); - I.eraseFromParent(); - return true; - } - case Intrinsic::ptrauth_auth: { - Register DstReg = I.getOperand(0).getReg(); - Register ValReg = I.getOperand(2).getReg(); - uint64_t AUTKey = I.getOperand(3).getImm(); - Register AUTDisc = I.getOperand(4).getReg(); - - Register AUTAddrDisc = AUTDisc; - uint16_t AUTConstDiscC = 0; - std::tie(AUTConstDiscC, AUTAddrDisc) = - extractPtrauthBlendDiscriminators(AUTDisc, MRI); - - if (STI.isX16X17Safer()) { - MIB.buildCopy({AArch64::X16}, {ValReg}); - MIB.buildInstr(TargetOpcode::IMPLICIT_DEF, {AArch64::X17}, {}); - MIB.buildInstr(AArch64::AUTx16x17) - .addImm(AUTKey) - .addImm(AUTConstDiscC) - .addUse(AUTAddrDisc) - .constrainAllUses(TII, TRI, RBI); - MIB.buildCopy({DstReg}, Register(AArch64::X16)); - } else { - Register ScratchReg = - MRI.createVirtualRegister(&AArch64::GPR64commonRegClass); - MIB.buildInstr(AArch64::AUTxMxN) - .addDef(DstReg) - .addDef(ScratchReg) - .addUse(ValReg) - .addImm(AUTKey) - .addImm(AUTConstDiscC) - .addUse(AUTAddrDisc) - .constrainAllUses(TII, TRI, RBI); - } - - RBI.constrainGenericRegister(DstReg, AArch64::GPR64RegClass, MRI); - I.eraseFromParent(); - return true; - } case Intrinsic::frameaddress: case Intrinsic::returnaddress: { MachineFunction &MF = *I.getParent()->getParent(); @@ -6813,19 +6803,11 @@ bool AArch64InstructionSelector::selectPtrAuthGlobalValue( MachineInstr &I, MachineRegisterInfo &MRI) const { Register DefReg = I.getOperand(0).getReg(); Register Addr = I.getOperand(1).getReg(); - uint64_t Key = I.getOperand(2).getImm(); - Register AddrDisc = I.getOperand(3).getReg(); - uint64_t Disc = I.getOperand(4).getImm(); + Register Schema = I.getOperand(2).getReg(); int64_t Offset = 0; - if (Key > AArch64PACKey::LAST) - report_fatal_error("key in ptrauth global out of range [0, " + - Twine((int)AArch64PACKey::LAST) + "]"); - - // Blend only works if the integer discriminator is 16-bit wide. - if (!isUInt<16>(Disc)) - report_fatal_error( - "constant discriminator in ptrauth global out of range [0, 0xffff]"); + auto [Key, Disc, AddrDisc] = + extractPtrauthBlendDiscriminators(Schema, MRI); // Choosing between 3 lowering alternatives is target-specific. if (!STI.isTargetELF() && !STI.isTargetMachO()) @@ -6874,8 +6856,7 @@ bool AArch64InstructionSelector::selectPtrAuthGlobalValue( assert((!GV->hasExternalWeakLinkage() || NeedsGOTLoad) && "unsupported non-GOT reference to weak ptrauth global"); - std::optional AddrDiscVal = getIConstantVRegVal(AddrDisc, MRI); - bool HasAddrDisc = !AddrDiscVal || *AddrDiscVal != 0; + bool HasAddrDisc = AddrDisc != AArch64::NoRegister; // Non-extern_weak: // - No GOT load needed -> MOVaddrPAC @@ -6887,7 +6868,7 @@ bool AArch64InstructionSelector::selectPtrAuthGlobalValue( MIB.buildInstr(NeedsGOTLoad ? AArch64::LOADgotPAC : AArch64::MOVaddrPAC) .addGlobalAddress(GV, Offset) .addImm(Key) - .addReg(HasAddrDisc ? AddrDisc : AArch64::XZR) + .addReg(HasAddrDisc ? AddrDisc : AArch64::XZR) // FIXME Use NoRegister instead? .addImm(Disc) .constrainAllUses(TII, TRI, RBI); MIB.buildCopy(DefReg, Register(AArch64::X16)); diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp index 1025b2502211a..d56f803167e97 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp @@ -1018,7 +1018,13 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) getActionDefinitionsBuilder(G_GLOBAL_VALUE).legalFor({p0}); getActionDefinitionsBuilder(G_PTRAUTH_GLOBAL_VALUE) - .legalIf(all(typeIs(0, p0), typeIs(1, p0))); + .legalForTypeWithAnyImm({p0}); + + getActionDefinitionsBuilder(G_PTRAUTH_BUNDLE).legalForTypeWithAnyImm({s64}); + getActionDefinitionsBuilder(G_PTRAUTH_AUTH).legalForTypeWithAnyImm({s64}); + getActionDefinitionsBuilder(G_PTRAUTH_SIGN).legalForTypeWithAnyImm({s64}); + getActionDefinitionsBuilder(G_PTRAUTH_RESIGN).legalForTypeWithAnyImm({s64}); + getActionDefinitionsBuilder(G_PTRAUTH_STRIP).legalForTypeWithAnyImm({s64}); getActionDefinitionsBuilder(G_PTRTOINT) .legalFor({{s64, p0}, {v2s64, v2p0}}) @@ -2506,4 +2512,4 @@ bool AArch64LegalizerInfo::legalizeFptrunc(MachineInstr &MI, MRI.replaceRegWith(Dst, Fin); MI.eraseFromParent(); return true; -} \ No newline at end of file +} diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 743c4f574e131..647b635b38464 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -3079,54 +3079,59 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { case Intrinsic::ptrauth_resign: { // We don't support this optimization on intrinsic calls with deactivation // symbols, which are represented using operand bundles. - if (II->hasOperandBundles()) + if (II->countOperandBundlesOfType(LLVMContext::OB_deactivation_symbol)) break; // (sign|resign) + (auth|resign) can be folded by omitting the middle // sign+auth component if the key and discriminator match. bool NeedSign = II->getIntrinsicID() == Intrinsic::ptrauth_resign; Value *Ptr = II->getArgOperand(0); - Value *Key = II->getArgOperand(1); - Value *Disc = II->getArgOperand(2); + auto ThisAutSchema = II->getOperandBundleAt(0); // AuthKey will be the key we need to end up authenticating against in // whatever we replace this sequence with. - Value *AuthKey = nullptr, *AuthDisc = nullptr, *BasePtr; + std::optional NewAutSchema; + Value *BasePtr = nullptr; if (const auto *CI = dyn_cast(Ptr)) { // We don't support this optimization on intrinsic calls with deactivation // symbols, which are represented using operand bundles. - if (CI->hasOperandBundles()) + if (CI->countOperandBundlesOfType(LLVMContext::OB_deactivation_symbol)) break; BasePtr = CI->getArgOperand(0); if (CI->getIntrinsicID() == Intrinsic::ptrauth_sign) { - if (CI->getArgOperand(1) != Key || CI->getArgOperand(2) != Disc) + if (ThisAutSchema.Inputs != CI->getOperandBundleAt(0).Inputs) break; } else if (CI->getIntrinsicID() == Intrinsic::ptrauth_resign) { - if (CI->getArgOperand(3) != Key || CI->getArgOperand(4) != Disc) + if (ThisAutSchema.Inputs != CI->getOperandBundleAt(1).Inputs) break; - AuthKey = CI->getArgOperand(1); - AuthDisc = CI->getArgOperand(2); + NewAutSchema = CI->getOperandBundleAt(0); } else break; } else if (const auto *PtrToInt = dyn_cast(Ptr)) { // ptrauth constants are equivalent to a call to @llvm.ptrauth.sign for // our purposes, so check for that too. const auto *CPA = dyn_cast(PtrToInt->getOperand(0)); - if (!CPA || !CPA->isKnownCompatibleWith(Key, Disc, DL)) + SmallVector Operands; + llvm::append_range(Operands, ThisAutSchema.Inputs); + if (!CPA || !CPA->isKnownCompatibleWith(Operands, DL)) break; - // resign(ptrauth(p,ks,ds),ks,ds,kr,dr) -> ptrauth(p,kr,dr) - if (NeedSign && isa(II->getArgOperand(4))) { - auto *SignKey = cast(II->getArgOperand(3)); - auto *SignDisc = cast(II->getArgOperand(4)); - auto *Null = ConstantPointerNull::get(Builder.getPtrTy()); - auto *NewCPA = ConstantPtrAuth::get(CPA->getPointer(), SignKey, - SignDisc, /*AddrDisc=*/Null, - /*DeactivationSymbol=*/Null); - replaceInstUsesWith( - *II, ConstantExpr::getPointerCast(NewCPA, II->getType())); - return eraseInstFromFunction(*II); + if (NeedSign) { + auto ThisSignSchema = II->getOperandBundleAt(1); + // resign(ptrauth(p,ks,ds),ks,ds,kr,dr) -> ptrauth(p,kr,dr) + auto IsConstant = [](Value *V) { return isa(V); }; + if (llvm::all_of(ThisSignSchema.Inputs, IsConstant)) { + auto *Null = ConstantPointerNull::get(Builder.getPtrTy()); + SmallVector Ops; + for (Value *V : ThisSignSchema.Inputs) + Ops.push_back(cast(V)); + auto *NewCPA = ConstantPtrAuth::get(CPA->getPointer(), Ops, + /*DeactivationSymbol=*/Null); + replaceInstUsesWith( + *II, ConstantExpr::getPointerCast(NewCPA, II->getType())); + return eraseInstFromFunction(*II); + } } // auth(ptrauth(p,k,d),k,d) -> p @@ -3135,10 +3140,10 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { break; unsigned NewIntrin; - if (AuthKey && NeedSign) { + if (NewAutSchema && NeedSign) { // resign(0,1) + resign(1,2) = resign(0, 2) NewIntrin = Intrinsic::ptrauth_resign; - } else if (AuthKey) { + } else if (NewAutSchema) { // resign(0,1) + auth(1) = auth(0) NewIntrin = Intrinsic::ptrauth_auth; } else if (NeedSign) { @@ -3150,21 +3155,15 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { return eraseInstFromFunction(*II); } - SmallVector CallArgs; - CallArgs.push_back(BasePtr); - if (AuthKey) { - CallArgs.push_back(AuthKey); - CallArgs.push_back(AuthDisc); - } - - if (NeedSign) { - CallArgs.push_back(II->getArgOperand(3)); - CallArgs.push_back(II->getArgOperand(4)); - } + SmallVector OBs; + if (NewAutSchema) + OBs.emplace_back(*NewAutSchema); + if (NeedSign) + OBs.emplace_back(II->getOperandBundleAt(1)); Function *NewFn = Intrinsic::getOrInsertDeclaration(II->getModule(), NewIntrin); - return CallInst::Create(NewFn, CallArgs); + return CallInst::Create(NewFn, {BasePtr}, OBs); } case Intrinsic::arm_neon_vtbl1: case Intrinsic::aarch64_neon_tbl1: @@ -4294,6 +4293,10 @@ static IntrinsicInst *findInitTrampoline(Value *Callee) { } Instruction *InstCombinerImpl::foldPtrAuthIntrinsicCallee(CallBase &Call) { + // "ptrauth" bundles have different semantic on intrinsics. + if (isa(Call)) + return nullptr; + const Value *Callee = Call.getCalledOperand(); const auto *IPC = dyn_cast(Callee); if (!IPC || !IPC->isNoopCast(DL)) @@ -4326,20 +4329,10 @@ Instruction *InstCombinerImpl::foldPtrAuthIntrinsicCallee(CallBase &Call) { // call(ptrauth.resign(p)), ["ptrauth"()] -> call p, ["ptrauth"()] // assuming the call bundle and the sign operands match. case Intrinsic::ptrauth_resign: { - // Resign result key should match bundle. - if (II->getOperand(3) != PtrAuthBundleOrNone->Inputs[0]) - return nullptr; - // Resign result discriminator should match bundle. - if (II->getOperand(4) != PtrAuthBundleOrNone->Inputs[1]) + if (II->getOperandBundleAt(1).Inputs != PtrAuthBundleOrNone->Inputs) return nullptr; - // Resign input (auth) key should also match: we can't change the key on - // the new call we're generating, because we don't know what keys are valid. - if (II->getOperand(1) != PtrAuthBundleOrNone->Inputs[0]) - return nullptr; - - Value *NewBundleOps[] = {II->getOperand(1), II->getOperand(2)}; - NewBundles.emplace_back("ptrauth", NewBundleOps); + NewBundles.emplace_back(II->getOperandBundleAt(0)); NewCallee = II->getOperand(0); break; } @@ -4348,11 +4341,7 @@ Instruction *InstCombinerImpl::foldPtrAuthIntrinsicCallee(CallBase &Call) { // assuming the call bundle and the sign operands match. // Non-ptrauth indirect calls are undesirable, but so is ptrauth.sign. case Intrinsic::ptrauth_sign: { - // Sign key should match bundle. - if (II->getOperand(1) != PtrAuthBundleOrNone->Inputs[0]) - return nullptr; - // Sign discriminator should match bundle. - if (II->getOperand(2) != PtrAuthBundleOrNone->Inputs[1]) + if (II->getOperandBundleAt(0).Inputs != PtrAuthBundleOrNone->Inputs) return nullptr; NewCallee = II->getOperand(0); break; @@ -4385,11 +4374,11 @@ Instruction *InstCombinerImpl::foldPtrAuthConstantCallee(CallBase &Call) { if (!PAB) return nullptr; - auto *Key = cast(PAB->Inputs[0]); - Value *Discriminator = PAB->Inputs[1]; + SmallVector Operands; + llvm::append_range(Operands, PAB->Inputs); // If the bundle doesn't match, this is probably going to fail to auth. - if (!CPA->isKnownCompatibleWith(Key, Discriminator, DL)) + if (!CPA->isKnownCompatibleWith(Operands, DL)) return nullptr; // If the bundle matches the constant, proceed in making this a direct call. diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp index 6e36006890df4..b6fa5a00b0bae 100644 --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -527,8 +527,8 @@ Value *Mapper::mapValue(const Value *V) { return getVM()[V] = ConstantVector::get(Ops); if (isa(C)) return getVM()[V] = - ConstantPtrAuth::get(Ops[0], cast(Ops[1]), - cast(Ops[2]), Ops[3], Ops[4]); + ConstantPtrAuth::get(Ops[0], ArrayRef(Ops).drop_front(2), + Ops[1]); // If this is a no-operand constant, it must be because the type was remapped. if (isa(C)) return getVM()[V] = PoisonValue::get(NewTy); diff --git a/llvm/test/Assembler/invalid-ptrauth-const1.ll b/llvm/test/Assembler/invalid-ptrauth-const1.ll index fba2e23078238..7ab292eec11c8 100644 --- a/llvm/test/Assembler/invalid-ptrauth-const1.ll +++ b/llvm/test/Assembler/invalid-ptrauth-const1.ll @@ -2,5 +2,5 @@ @var = global i32 0 -; CHECK: error: constant ptrauth base pointer must be a pointer -@auth_var = global ptr ptrauth (i32 42, i32 0) +; CHECK: error: base pointer of ptrauth constant must be a pointer +@auth_var = global ptr ptrauth (i32 42, [i64 0, i64 0, i64 0]) diff --git a/llvm/test/Assembler/invalid-ptrauth-const2.ll b/llvm/test/Assembler/invalid-ptrauth-const2.ll index 4499c42601c99..985d36d54c7d6 100644 --- a/llvm/test/Assembler/invalid-ptrauth-const2.ll +++ b/llvm/test/Assembler/invalid-ptrauth-const2.ll @@ -2,5 +2,5 @@ @var = global i32 0 -; CHECK: error: constant ptrauth key must be i32 constant -@auth_var = global ptr ptrauth (ptr @var, i32 ptrtoint (ptr @var to i32)) +; CHECK: error: schema of ptrauth constant must be a tuple of i64 +@auth_var = global ptr ptrauth (ptr @var, [i32 0, i64 0, i64 0]) diff --git a/llvm/test/Assembler/invalid-ptrauth-const3.ll b/llvm/test/Assembler/invalid-ptrauth-const3.ll index 3f2688d92a001..fc82ac90d2585 100644 --- a/llvm/test/Assembler/invalid-ptrauth-const3.ll +++ b/llvm/test/Assembler/invalid-ptrauth-const3.ll @@ -2,5 +2,5 @@ @var = global i32 0 -; CHECK: error: constant ptrauth address discriminator must be a pointer -@auth_var = global ptr ptrauth (ptr @var, i32 2, i64 65535, i8 0) +; CHECK: error: schema of ptrauth constant must be a tuple of i64 +@auth_var = global ptr ptrauth (ptr @var, [i64 0, i64 0, ptr null]) diff --git a/llvm/test/Assembler/invalid-ptrauth-const4.ll b/llvm/test/Assembler/invalid-ptrauth-const4.ll index 843a220458a61..b4fa2dc157cc3 100644 --- a/llvm/test/Assembler/invalid-ptrauth-const4.ll +++ b/llvm/test/Assembler/invalid-ptrauth-const4.ll @@ -2,5 +2,5 @@ @var = global i32 0 -; CHECK: error: constant ptrauth integer discriminator must be i64 constant -@auth_var = global ptr ptrauth (ptr @var, i32 2, ptr null, i64 ptrtoint (ptr @var to i64)) +; CHECK: error: schema of ptrauth constant must not be empty +@auth_var = global ptr ptrauth (ptr @var, []) diff --git a/llvm/test/Assembler/invalid-ptrauth-const5.ll b/llvm/test/Assembler/invalid-ptrauth-const5.ll deleted file mode 100644 index 9b47f6f5f423f..0000000000000 --- a/llvm/test/Assembler/invalid-ptrauth-const5.ll +++ /dev/null @@ -1,6 +0,0 @@ -; RUN: not llvm-as < %s 2>&1 | FileCheck %s - -@var = global i32 0 - -; CHECK: error: constant ptrauth integer discriminator must be i64 constant -@auth_var = global ptr ptrauth (ptr @var, i32 2, ptr @var)) diff --git a/llvm/test/Assembler/invalid-ptrauth-const6.ll b/llvm/test/Assembler/invalid-ptrauth-const6.ll index 6e8e1d386acc8..b9e17fc61481a 100644 --- a/llvm/test/Assembler/invalid-ptrauth-const6.ll +++ b/llvm/test/Assembler/invalid-ptrauth-const6.ll @@ -3,4 +3,4 @@ @var = global i32 0 ; CHECK: error: constant ptrauth deactivation symbol must be a pointer -@ptr = global ptr ptrauth (ptr @var, i32 0, i64 65535, ptr null, i64 0) +@ptr = global ptr ptrauth (ptr @var, [i64 0, i64 65535, i64 0], i64 0) diff --git a/llvm/test/Assembler/ptrauth-const.ll b/llvm/test/Assembler/ptrauth-const.ll index 94d35146d5927..1425db573ba98 100644 --- a/llvm/test/Assembler/ptrauth-const.ll +++ b/llvm/test/Assembler/ptrauth-const.ll @@ -2,23 +2,23 @@ @var = global i32 0 -; CHECK: @basic = global ptr ptrauth (ptr @var, i32 0) -@basic = global ptr ptrauth (ptr @var, i32 0) +; CHECK: @basic = global ptr ptrauth (ptr @var, [i64 0, i64 0, i64 0]) +@basic = global ptr ptrauth (ptr @var, [i64 0, i64 0, i64 0]) -; CHECK: @keyed = global ptr ptrauth (ptr @var, i32 3) -@keyed = global ptr ptrauth (ptr @var, i32 3) +; CHECK: @keyed = global ptr ptrauth (ptr @var, [i64 3, i64 0, i64 0]) +@keyed = global ptr ptrauth (ptr @var, [i64 3, i64 0, i64 0]) -; CHECK: @intdisc = global ptr ptrauth (ptr @var, i32 0, i64 -1) -@intdisc = global ptr ptrauth (ptr @var, i32 0, i64 -1) +; CHECK: @intdisc = global ptr ptrauth (ptr @var, [i64 0, i64 -1, i64 0]) +@intdisc = global ptr ptrauth (ptr @var, [i64 0, i64 -1, i64 0]) -; CHECK: @addrdisc = global ptr ptrauth (ptr @var, i32 2, i64 1234, ptr @addrdisc) -@addrdisc = global ptr ptrauth (ptr @var, i32 2, i64 1234, ptr @addrdisc) +; CHECK: @addrdisc = global ptr ptrauth (ptr @var, [i64 2, i64 1234, i64 ptrtoint (ptr @addrdisc to i64)]) +@addrdisc = global ptr ptrauth (ptr @var, [i64 2, i64 1234, i64 ptrtoint (ptr @addrdisc to i64)]) @var1 = addrspace(1) global i32 0 -; CHECK: @addrspace = global ptr addrspace(1) ptrauth (ptr addrspace(1) @var1, i32 0) -@addrspace = global ptr addrspace(1) ptrauth (ptr addrspace(1) @var1, i32 0) +; CHECK: @addrspace = global ptr addrspace(1) ptrauth (ptr addrspace(1) @var1, [i64 0, i64 0, i64 0]) +@addrspace = global ptr addrspace(1) ptrauth (ptr addrspace(1) @var1, [i64 0, i64 0, i64 0]) -; CHECK: @addrspace_addrdisc = addrspace(2) global ptr addrspace(1) ptrauth (ptr addrspace(1) @var1, i32 2, i64 1234, ptr addrspace(2) @addrspace_addrdisc) -@addrspace_addrdisc = addrspace(2) global ptr addrspace(1) ptrauth (ptr addrspace(1) @var1, i32 2, i64 1234, ptr addrspace(2) @addrspace_addrdisc) +; CHECK: @addrspace_addrdisc = addrspace(2) global ptr addrspace(1) ptrauth (ptr addrspace(1) @var1, [i64 2, i64 1234, i64 ptrtoint (ptr addrspace(2) @addrspace_addrdisc to i64)]) +@addrspace_addrdisc = addrspace(2) global ptr addrspace(1) ptrauth (ptr addrspace(1) @var1, [i64 2, i64 1234, i64 ptrtoint (ptr addrspace(2) @addrspace_addrdisc to i64)]) diff --git a/llvm/test/Bindings/llvm-c/echo.ll b/llvm/test/Bindings/llvm-c/echo.ll index ab1771d1f879f..c5dea6dbfeee3 100644 --- a/llvm/test/Bindings/llvm-c/echo.ll +++ b/llvm/test/Bindings/llvm-c/echo.ll @@ -40,8 +40,8 @@ module asm "classical GAS" @ptrauth_addr_disc = global i32 0 @ptrauth_data = global i32 0 -@ptrauth_ptr_01 = global ptr ptrauth (ptr @ptrauth_data, i32 77, i64 1001, ptr @ptrauth_addr_disc) -@ptrauth_ptr_02 = global ptr ptrauth (ptr @ptrauth_data, i32 11, i64 99, ptr null) +@ptrauth_ptr_01 = global ptr ptrauth (ptr @ptrauth_data, [i64 77, i64 1001, i64 ptrtoint (ptr @ptrauth_addr_disc to i64)]) +@ptrauth_ptr_02 = global ptr ptrauth (ptr @ptrauth_data, [i64 11, i64 99, i64 0]) define ptr @ifunc_resolver() { entry: diff --git a/llvm/test/Bitcode/compatibility.ll b/llvm/test/Bitcode/compatibility.ll index 53cbe2d6ffd37..84046c24c272b 100644 --- a/llvm/test/Bitcode/compatibility.ll +++ b/llvm/test/Bitcode/compatibility.ll @@ -220,10 +220,10 @@ declare void @g.f1() @ds = external global i32 ; ptrauth constant -@auth_var = global ptr ptrauth (ptr @g1, i32 0, i64 65535, ptr null) -; CHECK: @auth_var = global ptr ptrauth (ptr @g1, i32 0, i64 65535) -@auth_var.ds = global ptr ptrauth (ptr @g1, i32 0, i64 65535, ptr null, ptr @ds) -; CHECK: @auth_var.ds = global ptr ptrauth (ptr @g1, i32 0, i64 65535, ptr null, ptr @ds) +@auth_var = global ptr ptrauth (ptr @g1, [i64 0, i64 65535, i64 0]) +; CHECK: @auth_var = global ptr ptrauth (ptr @g1, [i64 0, i64 65535, i64 0]) +@auth_var.ds = global ptr ptrauth (ptr @g1, [i64 0, i64 65535, i64 0], ptr @ds) +; CHECK: @auth_var.ds = global ptr ptrauth (ptr @g1, [i64 0, i64 65535, i64 0], ptr @ds) ;; Aliases ; Format: @ = [Linkage] [Visibility] [DLLStorageClass] [ThreadLocal] diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir index e68278dadc4b8..dd85fec0297e6 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir @@ -115,7 +115,27 @@ # DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected # DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected # -# DEBUG-NEXT: G_PTRAUTH_GLOBAL_VALUE (opcode {{[0-9]+}}): 2 type indices, 0 imm indices +# DEBUG-NEXT: G_PTRAUTH_GLOBAL_VALUE (opcode {{[0-9]+}}): 1 type index, 1 imm index +# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected +# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected +# +# DEBUG-NEXT: G_PTRAUTH_BUNDLE (opcode {{[0-9]+}}): 1 type index, 1 imm index +# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected +# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected +# +# DEBUG-NEXT: G_PTRAUTH_AUTH (opcode {{[0-9]+}}): 1 type index, 1 imm index +# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected +# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected +# +# DEBUG-NEXT: G_PTRAUTH_SIGN (opcode {{[0-9]+}}): 1 type index, 1 imm index +# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected +# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected +# +# DEBUG-NEXT: G_PTRAUTH_RESIGN (opcode {{[0-9]+}}): 1 type index, 1 imm index +# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected +# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected +# +# DEBUG-NEXT: G_PTRAUTH_STRIP (opcode {{[0-9]+}}): 1 type index, 1 imm index # DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected # DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected # diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll b/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll index 12a3448111fcb..5852c885ad4b5 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-constant-in-code.ll @@ -2,34 +2,38 @@ ;--- err1.ll -; RUN: not --crash llc < err1.ll -mtriple aarch64-elf -mattr=+pauth \ +; RUN: not llc < err1.ll -mtriple aarch64-elf -mattr=+pauth \ ; RUN: -global-isel=1 -verify-machineinstrs -global-isel-abort=1 2>&1 | \ ; RUN: FileCheck --check-prefix=ERR1 %s -; RUN: not --crash llc < err1.ll -mtriple arm64-apple-ios -mattr=+pauth \ +; RUN: not llc < err1.ll -mtriple arm64-apple-ios -mattr=+pauth \ ; RUN: -global-isel=1 -verify-machineinstrs -global-isel-abort=1 2>&1 | \ ; RUN: FileCheck --check-prefix=ERR1 %s @g = external global i32 define ptr @foo() { -; ERR1: LLVM ERROR: key in ptrauth global out of range [0, 3] - ret ptr ptrauth (ptr @g, i32 4) +; ERR1: Ptrauth schema violates target-specific constraints: +; ERR1: ptr ptrauth (ptr @g, [i64 4, i64 0, i64 0]) +; ERR1: LLVM ERROR: Invalid ptrauth schema: key must be constant in range [0, 3] + ret ptr ptrauth (ptr @g, [i64 4, i64 0, i64 0]) } ;--- err2.ll -; RUN: not --crash llc < err2.ll -mtriple aarch64-elf -mattr=+pauth \ +; RUN: not llc < err2.ll -mtriple aarch64-elf -mattr=+pauth \ ; RUN: -global-isel=1 -verify-machineinstrs -global-isel-abort=1 2>&1 | \ ; RUN: FileCheck --check-prefix=ERR2 %s -; RUN: not --crash llc < err2.ll -mtriple arm64-apple-ios -mattr=+pauth \ +; RUN: not llc < err2.ll -mtriple arm64-apple-ios -mattr=+pauth \ ; RUN: -global-isel=1 -verify-machineinstrs -global-isel-abort=1 2>&1 | \ ; RUN: FileCheck --check-prefix=ERR2 %s @g = external global i32 define ptr @foo() { -; ERR2: LLVM ERROR: constant discriminator in ptrauth global out of range [0, 0xffff] - ret ptr ptrauth (ptr @g, i32 2, i64 65536) +; ERR2: Ptrauth schema violates target-specific constraints: +; ERR2: ptr ptrauth (ptr @g, [i64 2, i64 65536, i64 0]) +; ERR2: LLVM ERROR: Invalid ptrauth schema: constant modifier must be 16-bit unsigned constant + ret ptr ptrauth (ptr @g, [i64 2, i64 65536, i64 0]) } ;--- err3.ll @@ -45,7 +49,7 @@ define ptr @foo() { define ptr @foo() { ; ERR3: LLVM ERROR: unsupported non-zero offset in weak ptrauth global reference - ret ptr ptrauth (ptr getelementptr (i8, ptr @g_weak, i64 16), i32 2, i64 42) + ret ptr ptrauth (ptr getelementptr (i8, ptr @g_weak, i64 16), [i64 2, i64 42, i64 0]) } ;--- err4.ll @@ -58,11 +62,11 @@ define ptr @foo() { ; RUN: FileCheck --check-prefix=ERR4 %s @g_weak = extern_weak global i32 -@g_weak.ref.da.42.addr = dso_local constant ptr ptrauth (ptr @g_weak, i32 2, i64 42, ptr @g_weak.ref.da.42.addr) +@g_weak.ref.da.42.addr = dso_local constant ptr ptrauth (ptr @g_weak, [i64 2, i64 42, i64 ptrtoint (ptr @g_weak.ref.da.42.addr to i64)]) define ptr @foo() { ; ERR4: LLVM ERROR: unsupported weak addr-div ptrauth global - ret ptr ptrauth (ptr @g_weak, i32 0, i64 42, ptr @g_weak.ref.da.42.addr) + ret ptr ptrauth (ptr @g_weak, [i64 0, i64 42, i64 ptrtoint (ptr @g_weak.ref.da.42.addr to i64)]) } ;--- err5.ll @@ -75,7 +79,7 @@ define ptr @foo() { define ptr @foo() { ; ERR5: LLVM ERROR: ptrauth global lowering only supported on MachO/ELF - ret ptr ptrauth (ptr @g, i32 0) + ret ptr ptrauth (ptr @g, [i64 0, i64 0, i64 0]) } ;--- ok.ll @@ -113,7 +117,7 @@ define ptr @test_global_zero_disc() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr @g, i32 0) + ret ptr ptrauth (ptr @g, [i64 0, i64 0, i64 0]) } define ptr @test_global_offset_zero_disc() { @@ -135,7 +139,7 @@ define ptr @test_global_offset_zero_disc() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 16), i32 2) + ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 16), [i64 2, i64 0, i64 0]) } define ptr @test_global_neg_offset_zero_disc() { @@ -159,7 +163,7 @@ define ptr @test_global_neg_offset_zero_disc() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -123456), i32 2) + ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -123456), [i64 2, i64 0, i64 0]) } define ptr @test_global_big_offset_zero_disc() { @@ -185,7 +189,7 @@ define ptr @test_global_big_offset_zero_disc() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 add (i64 2147483648, i64 65537)), i32 2) + ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 add (i64 2147483648, i64 65537)), [i64 2, i64 0, i64 0]) } define ptr @test_global_big_neg_offset_zero_disc() { @@ -211,7 +215,7 @@ define ptr @test_global_big_neg_offset_zero_disc() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -123456789), i32 2) + ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -123456789), [i64 2, i64 0, i64 0]) } define ptr @test_global_huge_neg_offset_zero_disc() { @@ -241,7 +245,7 @@ define ptr @test_global_huge_neg_offset_zero_disc() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -9223372036854775808), i32 2) + ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -9223372036854775808), [i64 2, i64 0, i64 0]) } define ptr @test_global_disc() { @@ -263,10 +267,10 @@ define ptr @test_global_disc() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr @g, i32 0, i64 42) + ret ptr ptrauth (ptr @g, [i64 0, i64 42, i64 0]) } -@g.ref.da.42.addr = dso_local constant ptr ptrauth (ptr @g, i32 2, i64 42, ptr @g.ref.da.42.addr) +@g.ref.da.42.addr = dso_local constant ptr ptrauth (ptr @g, [i64 2, i64 42, i64 ptrtoint (ptr @g.ref.da.42.addr to i64)]) define ptr @test_global_addr_disc() { ; ELF-LABEL: test_global_addr_disc: @@ -295,7 +299,7 @@ define ptr @test_global_addr_disc() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr @g, i32 2, i64 42, ptr @g.ref.da.42.addr) + ret ptr ptrauth (ptr @g, [i64 2, i64 42, i64 ptrtoint (ptr @g.ref.da.42.addr to i64)]) } define ptr @test_global_process_specific() { @@ -315,7 +319,7 @@ define ptr @test_global_process_specific() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr @g, i32 1) + ret ptr ptrauth (ptr @g, [i64 1, i64 0, i64 0]) } ; Non-external symbols don't need to be accessed through the GOT. @@ -337,7 +341,7 @@ define ptr @test_global_strong_def() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr @g_strong_def, i32 2) + ret ptr ptrauth (ptr @g_strong_def, [i64 2, i64 0, i64 0]) } ; weak symbols can't be assumed to be non-nil. Use $auth_ptr$ stub slot always. @@ -357,7 +361,7 @@ define ptr @test_global_weak() { ; MACHO-NEXT: ldr x0, [x0, l_g_weak$auth_ptr$ia$42@PAGEOFF] ; MACHO-NEXT: ret - ret ptr ptrauth (ptr @g_weak, i32 0, i64 42) + ret ptr ptrauth (ptr @g_weak, [i64 0, i64 42, i64 0]) } ; Test another weak symbol to check that stubs are emitted in a stable order. @@ -377,7 +381,7 @@ define ptr @test_global_weak_2() { ; MACHO-NEXT: ldr x0, [x0, l_g_weak_2$auth_ptr$ia$42@PAGEOFF] ; MACHO-NEXT: ret - ret ptr ptrauth (ptr @g_weak_2, i32 0, i64 42) + ret ptr ptrauth (ptr @g_weak_2, [i64 0, i64 42, i64 0]) } ; ELF-LABEL: g_weak$auth_ptr$ia$42: diff --git a/llvm/test/CodeGen/AArch64/deactivation-symbols.ll b/llvm/test/CodeGen/AArch64/deactivation-symbols.ll index 571b1067134b8..dcd0f0b1085aa 100644 --- a/llvm/test/CodeGen/AArch64/deactivation-symbols.ll +++ b/llvm/test/CodeGen/AArch64/deactivation-symbols.ll @@ -1,5 +1,7 @@ -; RUN: llc < %s -O0 -mtriple=aarch64-none-linux-gnu -mattr=+pauth | FileCheck --check-prefixes=CHECK,O0 %s -; RUN: llc < %s -O2 -mtriple=aarch64-none-linux-gnu -mattr=+pauth | FileCheck --check-prefixes=CHECK,O2 %s +; RUN: llc < %s -O0 -mtriple=aarch64-none-linux-gnu -mattr=+pauth -global-isel=0 | FileCheck %s +; RUN: llc < %s -O2 -mtriple=aarch64-none-linux-gnu -mattr=+pauth -global-isel=0 | FileCheck %s +; RUN: llc < %s -O0 -mtriple=aarch64-none-linux-gnu -mattr=+pauth -global-isel=1 -global-isel-abort=1 | FileCheck %s +; RUN: llc < %s -O2 -mtriple=aarch64-none-linux-gnu -mattr=+pauth -global-isel=1 -global-isel-abort=1 | FileCheck %s @ds = external global i8 @@ -16,12 +18,10 @@ define void @call(ptr %p) { ; CHECK: pauth_sign_zero: define i64 @pauth_sign_zero(i64 %p) { - ; O0: mov x8, xzr ; CHECK: [[LABEL:.L.*]]: ; CHECK-NEXT: .reloc [[LABEL]], R_AARCH64_PATCHINST, ds - ; O0-NEXT: pacia x0, x8 - ; O2-NEXT: paciza x0 - %signed = call i64 @llvm.ptrauth.sign(i64 %p, i32 0, i64 0) [ "deactivation-symbol"(ptr @ds) ] + ; CHECK-NEXT: paciza x0 + %signed = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0), "deactivation-symbol"(ptr @ds) ] ret i64 %signed } @@ -31,7 +31,7 @@ define i64 @pauth_sign_const(i64 %p) { ; CHECK-NEXT: [[LABEL:.L.*]]: ; CHECK-NEXT: .reloc [[LABEL]], R_AARCH64_PATCHINST, ds ; CHECK-NEXT: pacia x0, x16 - %signed = call i64 @llvm.ptrauth.sign(i64 %p, i32 0, i64 12345) [ "deactivation-symbol"(ptr @ds) ] + %signed = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 12345, i64 0), "deactivation-symbol"(ptr @ds) ] ret i64 %signed } @@ -40,7 +40,7 @@ define i64 @pauth_sign(i64 %p, i64 %d) { ; CHECK: [[LABEL:.L.*]]: ; CHECK-NEXT: .reloc [[LABEL]], R_AARCH64_PATCHINST, ds ; CHECK-NEXT: pacia x0, x1 - %signed = call i64 @llvm.ptrauth.sign(i64 %p, i32 0, i64 %d) [ "deactivation-symbol"(ptr @ds) ] + %signed = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 %d), "deactivation-symbol"(ptr @ds) ] ret i64 %signed } @@ -49,7 +49,7 @@ define i64 @pauth_auth_zero(i64 %p) { ; CHECK: [[LABEL:.L.*]]: ; CHECK-NEXT: .reloc [[LABEL]], R_AARCH64_PATCHINST, ds ; CHECK-NEXT: autiza x0 - %authed = call i64 @llvm.ptrauth.auth(i64 %p, i32 0, i64 0) [ "deactivation-symbol"(ptr @ds) ] + %authed = call i64 @llvm.ptrauth.auth(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0), "deactivation-symbol"(ptr @ds) ] ret i64 %authed } @@ -59,7 +59,7 @@ define i64 @pauth_auth_const(i64 %p) { ; CHECK-NEXT: [[LABEL:.L.*]]: ; CHECK-NEXT: .reloc [[LABEL]], R_AARCH64_PATCHINST, ds ; CHECK-NEXT: autia x0, x8 - %authed = call i64 @llvm.ptrauth.auth(i64 %p, i32 0, i64 12345) [ "deactivation-symbol"(ptr @ds) ] + %authed = call i64 @llvm.ptrauth.auth(i64 %p) [ "ptrauth"(i64 0, i64 12345, i64 0), "deactivation-symbol"(ptr @ds) ] ret i64 %authed } @@ -68,6 +68,6 @@ define i64 @pauth_auth(i64 %p, i64 %d) { ; CHECK: [[LABEL:.L.*]]: ; CHECK-NEXT: .reloc [[LABEL]], R_AARCH64_PATCHINST, ds ; CHECK-NEXT: autia x0, x1 - %authed = call i64 @llvm.ptrauth.auth(i64 %p, i32 0, i64 %d) [ "deactivation-symbol"(ptr @ds) ] + %authed = call i64 @llvm.ptrauth.auth(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 %d), "deactivation-symbol"(ptr @ds) ] ret i64 %authed } diff --git a/llvm/test/CodeGen/AArch64/ptrauth-basic-pic.ll b/llvm/test/CodeGen/AArch64/ptrauth-basic-pic.ll index 517a0a86ef14b..e54661e388338 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-basic-pic.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-basic-pic.ll @@ -79,7 +79,7 @@ define ptr @resign_globalfunc() { ; CHECK-NEXT: mov x0, x16 ; CHECK-NEXT: ret - ret ptr ptrauth (ptr @foo, i32 0, i64 42) + ret ptr ptrauth (ptr @foo, [i64 0, i64 42, i64 0]) } define ptr @resign_globalvar() { @@ -99,7 +99,7 @@ define ptr @resign_globalvar() { ; CHECK-NEXT: mov x0, x16 ; CHECK-NEXT: ret - ret ptr ptrauth (ptr @var, i32 3, i64 43) + ret ptr ptrauth (ptr @var, [i64 3, i64 43, i64 0]) } define ptr @resign_globalvar_offset() { @@ -120,7 +120,7 @@ define ptr @resign_globalvar_offset() { ; CHECK-NEXT: mov x0, x16 ; CHECK-NEXT: ret - ret ptr ptrauth (ptr getelementptr (i8, ptr @var, i64 16), i32 2, i64 44) + ret ptr ptrauth (ptr getelementptr (i8, ptr @var, i64 16), [i64 2, i64 44, i64 0]) } !llvm.module.flags = !{!0} diff --git a/llvm/test/CodeGen/AArch64/ptrauth-bti-call.ll b/llvm/test/CodeGen/AArch64/ptrauth-bti-call.ll index df5e1a9f1ee10..f556b399a7199 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-bti-call.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-bti-call.ll @@ -18,7 +18,7 @@ ; CHECK-NEXT: mov x16, x0 ; CHECK-NEXT: braaz x16 define i32 @test_tailcall_ia_0(ptr %arg0) #0 { - %tmp0 = tail call i32 %arg0() [ "ptrauth"(i32 0, i64 0) ] + %tmp0 = tail call i32 %arg0() [ "ptrauth"(i64 0, i64 0, i64 0) ] ret i32 %tmp0 } @@ -27,7 +27,7 @@ define i32 @test_tailcall_ia_0(ptr %arg0) #0 { ; CHECK-NEXT: mov x16, x0 ; CHECK-NEXT: brabz x16 define i32 @test_tailcall_ib_0(ptr %arg0) #0 { - %tmp0 = tail call i32 %arg0() [ "ptrauth"(i32 1, i64 0) ] + %tmp0 = tail call i32 %arg0() [ "ptrauth"(i64 1, i64 0, i64 0) ] ret i32 %tmp0 } @@ -37,7 +37,7 @@ define i32 @test_tailcall_ib_0(ptr %arg0) #0 { ; CHECK-NEXT: mov x17, #42 ; CHECK-NEXT: braa x16, x17 define i32 @test_tailcall_ia_imm(ptr %arg0) #0 { - %tmp0 = tail call i32 %arg0() [ "ptrauth"(i32 0, i64 42) ] + %tmp0 = tail call i32 %arg0() [ "ptrauth"(i64 0, i64 42, i64 0) ] ret i32 %tmp0 } @@ -47,7 +47,7 @@ define i32 @test_tailcall_ia_imm(ptr %arg0) #0 { ; CHECK-NEXT: mov x17, #42 ; CHECK-NEXT: brab x16, x17 define i32 @test_tailcall_ib_imm(ptr %arg0) #0 { - %tmp0 = tail call i32 %arg0() [ "ptrauth"(i32 1, i64 42) ] + %tmp0 = tail call i32 %arg0() [ "ptrauth"(i64 1, i64 42, i64 0) ] ret i32 %tmp0 } @@ -62,7 +62,7 @@ define i32 @test_tailcall_ib_imm(ptr %arg0) #0 { ; ELF-NEXT: braa x16, x1 define i32 @test_tailcall_ia_var(ptr %arg0, ptr %arg1) #0 { %tmp0 = load i64, ptr %arg1 - %tmp1 = tail call i32 %arg0() [ "ptrauth"(i32 0, i64 %tmp0) ] + %tmp1 = tail call i32 %arg0() [ "ptrauth"(i64 0, i64 0, i64 %tmp0) ] ret i32 %tmp1 } @@ -77,7 +77,7 @@ define i32 @test_tailcall_ia_var(ptr %arg0, ptr %arg1) #0 { ; ELF-NEXT: brab x16, x1 define i32 @test_tailcall_ib_var(ptr %arg0, ptr %arg1) #0 { %tmp0 = load i64, ptr %arg1 - %tmp1 = tail call i32 %arg0() [ "ptrauth"(i32 1, i64 %tmp0) ] + %tmp1 = tail call i32 %arg0() [ "ptrauth"(i64 1, i64 0, i64 %tmp0) ] ret i32 %tmp1 } @@ -86,7 +86,7 @@ define i32 @test_tailcall_ib_var(ptr %arg0, ptr %arg1) #0 { ; CHECK-NEXT: mov x16, x0 ; CHECK-NEXT: braa x16, x1 define i32 @test_tailcall_ia_arg(ptr %arg0, i64 %arg1) #0 { - %tmp0 = tail call i32 %arg0() [ "ptrauth"(i32 0, i64 %arg1) ] + %tmp0 = tail call i32 %arg0() [ "ptrauth"(i64 0, i64 0, i64 %arg1) ] ret i32 %tmp0 } @@ -95,7 +95,7 @@ define i32 @test_tailcall_ia_arg(ptr %arg0, i64 %arg1) #0 { ; CHECK-NEXT: mov x16, x0 ; CHECK-NEXT: brab x16, x1 define i32 @test_tailcall_ib_arg(ptr %arg0, i64 %arg1) #0 { - %tmp0 = tail call i32 %arg0() [ "ptrauth"(i32 1, i64 %arg1) ] + %tmp0 = tail call i32 %arg0() [ "ptrauth"(i64 1, i64 0, i64 %arg1) ] ret i32 %tmp0 } @@ -105,7 +105,7 @@ define i32 @test_tailcall_ib_arg(ptr %arg0, i64 %arg1) #0 { ; CHECK-NEXT: braa x16, x1 define i32 @test_tailcall_ia_arg_ind(ptr %arg0, i64 %arg1) #0 { %tmp0 = load ptr, ptr %arg0 - %tmp1 = tail call i32 %tmp0() [ "ptrauth"(i32 0, i64 %arg1) ] + %tmp1 = tail call i32 %tmp0() [ "ptrauth"(i64 0, i64 0, i64 %arg1) ] ret i32 %tmp1 } @@ -115,7 +115,7 @@ define i32 @test_tailcall_ia_arg_ind(ptr %arg0, i64 %arg1) #0 { ; CHECK-NEXT: brab x16, x1 define i32 @test_tailcall_ib_arg_ind(ptr %arg0, i64 %arg1) #0 { %tmp0 = load ptr, ptr %arg0 - %tmp1 = tail call i32 %tmp0() [ "ptrauth"(i32 1, i64 %arg1) ] + %tmp1 = tail call i32 %tmp0() [ "ptrauth"(i64 1, i64 0, i64 %arg1) ] ret i32 %tmp1 } diff --git a/llvm/test/CodeGen/AArch64/ptrauth-call-rv-marker.ll b/llvm/test/CodeGen/AArch64/ptrauth-call-rv-marker.ll index 950db5fd6381f..7d008552e4a93 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-call-rv-marker.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-call-rv-marker.ll @@ -24,7 +24,7 @@ define void @rv_marker_ptrauth_blraa(ptr %arg0, i64 %arg1) { ; entry: %tmp0 = load ptr, ptr %arg0 - %call0 = call ptr %tmp0() [ "ptrauth"(i32 0, i64 %arg1), "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] + %call0 = call ptr %tmp0() [ "ptrauth"(i64 0, i64 0, i64 %arg1), "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] tail call void @foo2(ptr %call0) tail call void @llvm.objc.release(ptr %call0) ret void @@ -39,7 +39,7 @@ define void @rv_marker_ptrauth_blraa_unsafeClaim(ptr %arg0, i64 %arg1) { ; entry: %tmp0 = load ptr, ptr %arg0 - %call0 = call ptr %tmp0() [ "ptrauth"(i32 0, i64 %arg1), "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] + %call0 = call ptr %tmp0() [ "ptrauth"(i64 0, i64 0, i64 %arg1), "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] tail call void @foo2(ptr %call0) tail call void @llvm.objc.release(ptr %call0) ret void @@ -54,7 +54,7 @@ define void @rv_marker_ptrauth_blraa_disc_imm16(ptr %arg0) { ; CHECK-NEXT: bl objc_retainAutoreleasedReturnValue ; %tmp0 = load ptr, ptr %arg0 - %call0 = call ptr %tmp0() [ "ptrauth"(i32 1, i64 45431), "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] + %call0 = call ptr %tmp0() [ "ptrauth"(i64 1, i64 45431, i64 0), "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] tail call void @foo2(ptr %call0) tail call void @llvm.objc.release(ptr %call0) ret void @@ -72,7 +72,7 @@ define void @rv_marker_ptrauth_blraa_multiarg(ptr %arg0, i64 %arg1, i64 %a, i64 ; entry: %tmp0 = load ptr, ptr %arg0 - %call0 = call ptr %tmp0(i64 %c, i64 %b, i64 %a) [ "ptrauth"(i32 0, i64 %arg1), "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] + %call0 = call ptr %tmp0(i64 %c, i64 %b, i64 %a) [ "ptrauth"(i64 0, i64 0, i64 %arg1), "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] tail call void @foo2(ptr %call0) tail call void @llvm.objc.release(ptr %call0) ret void @@ -86,7 +86,7 @@ define void @rv_marker_ptrauth_blrab(ptr %arg0, i64 %arg1) { ; CHECK-NEXT: bl objc_retainAutoreleasedReturnValue ; %tmp0 = load ptr, ptr %arg0 - %call0 = call ptr %tmp0() [ "ptrauth"(i32 1, i64 %arg1), "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] + %call0 = call ptr %tmp0() [ "ptrauth"(i64 1, i64 0, i64 %arg1), "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] tail call void @foo2(ptr %call0) tail call void @llvm.objc.release(ptr %call0) ret void @@ -101,7 +101,7 @@ define void @rv_marker_ptrauth_blrab_disc_imm16(ptr %arg0) { ; CHECK-NEXT: bl objc_retainAutoreleasedReturnValue ; %tmp0 = load ptr, ptr %arg0 - %call0 = call ptr %tmp0() [ "ptrauth"(i32 1, i64 256), "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] + %call0 = call ptr %tmp0() [ "ptrauth"(i64 1, i64 256, i64 0), "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] tail call void @foo2(ptr %call0) tail call void @llvm.objc.release(ptr %call0) ret void @@ -115,7 +115,7 @@ define void @rv_marker_ptrauth_blraaz(ptr %arg0) { ; CHECK-NEXT: bl objc_retainAutoreleasedReturnValue ; %tmp0 = load ptr, ptr %arg0 - %call0 = call ptr %tmp0() [ "ptrauth"(i32 0, i64 0), "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] + %call0 = call ptr %tmp0() [ "ptrauth"(i64 0, i64 0, i64 0), "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] tail call void @foo2(ptr %call0) tail call void @llvm.objc.release(ptr %call0) ret void @@ -129,7 +129,7 @@ define void @rv_marker_ptrauth_blrabz(ptr %arg0) { ; CHECK-NEXT: bl objc_retainAutoreleasedReturnValue ; %tmp0 = load ptr, ptr %arg0 - %call0 = call ptr %tmp0() [ "ptrauth"(i32 1, i64 0), "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] + %call0 = call ptr %tmp0() [ "ptrauth"(i64 1, i64 0, i64 0), "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] tail call void @foo2(ptr %call0) tail call void @llvm.objc.release(ptr %call0) ret void @@ -147,7 +147,7 @@ define void @rv_marker_ptrauth_blrabz_multiarg(ptr %arg0, i64 %a, i64 %b, i64 %c ; CHECK-NEXT: bl objc_retainAutoreleasedReturnValue ; %tmp0 = load ptr, ptr %arg0 - %call0 = call ptr %tmp0(i64 %c, i64 %b, i64 %a) [ "ptrauth"(i32 1, i64 0), "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] + %call0 = call ptr %tmp0(i64 %c, i64 %b, i64 %a) [ "ptrauth"(i64 1, i64 0, i64 0), "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] tail call void @foo2(ptr %call0) tail call void @llvm.objc.release(ptr %call0) ret void diff --git a/llvm/test/CodeGen/AArch64/ptrauth-call-upgrade.ll b/llvm/test/CodeGen/AArch64/ptrauth-call-upgrade.ll new file mode 100644 index 0000000000000..6103c64cc2bb8 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/ptrauth-call-upgrade.ll @@ -0,0 +1,33 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -S | FileCheck %s +; RUN: llvm-as < %s | opt -S | FileCheck %s + +define void @test_call_imm_disc(ptr %fn) { +; CHECK-LABEL: @test_call_imm_disc( +; CHECK-NEXT: call void [[FN:%.*]]() [ "ptrauth"(i64 1, i64 0, i64 0) ] +; CHECK-NEXT: call void [[FN]]() [ "ptrauth"(i64 1, i64 42, i64 0) ] +; CHECK-NEXT: ret void +; + call void %fn() [ "ptrauth"(i32 1, i64 0) ] + call void %fn() [ "ptrauth"(i32 1, i64 42) ] + ret void +} + +define void @test_call_addr_disc(ptr %fn, i64 %addr) { +; CHECK-LABEL: @test_call_addr_disc( +; CHECK-NEXT: call void [[FN:%.*]]() [ "ptrauth"(i64 1, i64 0, i64 [[ADDR:%.*]]) ] +; CHECK-NEXT: ret void +; + call void %fn() [ "ptrauth"(i32 1, i64 %addr) ] + ret void +} + +define void @test_call_blended_disc(ptr %fn, i64 %addr) { +; CHECK-LABEL: @test_call_blended_disc( +; CHECK-NEXT: call void [[FN:%.*]]() [ "ptrauth"(i64 1, i64 42, i64 [[ADDR:%.*]]) ] +; CHECK-NEXT: ret void +; + %disc = call i64 @llvm.ptrauth.blend(i64 %addr, i64 42) + call void %fn() [ "ptrauth"(i32 1, i64 %disc) ] + ret void +} diff --git a/llvm/test/CodeGen/AArch64/ptrauth-call.ll b/llvm/test/CodeGen/AArch64/ptrauth-call.ll index fc555a882be2c..8430777352ddd 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-call.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-call.ll @@ -25,7 +25,7 @@ define i32 @test_call_ia_0(ptr %arg0) #0 { ; ELF-NEXT: blraaz x0 ; ELF-NEXT: ldr x30, [sp], #16 ; ELF-NEXT: ret - %tmp0 = call i32 %arg0() [ "ptrauth"(i32 0, i64 0) ] + %tmp0 = call i32 %arg0() [ "ptrauth"(i64 0, i64 0, i64 0) ] ret i32 %tmp0 } @@ -41,21 +41,21 @@ define i32 @test_call_ib_0(ptr %arg0) #0 { ; ELF-NEXT: blrabz x0 ; ELF-NEXT: ldr x30, [sp], #16 ; ELF-NEXT: ret - %tmp0 = call i32 %arg0() [ "ptrauth"(i32 1, i64 0) ] + %tmp0 = call i32 %arg0() [ "ptrauth"(i64 1, i64 0, i64 0) ] ret i32 %tmp0 } define i32 @test_tailcall_ia_0(ptr %arg0) #0 { ; CHECK-LABEL: test_tailcall_ia_0: ; CHECK-NEXT: braaz x0 - %tmp0 = tail call i32 %arg0() [ "ptrauth"(i32 0, i64 0) ] + %tmp0 = tail call i32 %arg0() [ "ptrauth"(i64 0, i64 0, i64 0) ] ret i32 %tmp0 } define i32 @test_tailcall_ib_0(ptr %arg0) #0 { ; CHECK-LABEL: test_tailcall_ib_0: ; CHECK-NEXT: brabz x0 - %tmp0 = tail call i32 %arg0() [ "ptrauth"(i32 1, i64 0) ] + %tmp0 = tail call i32 %arg0() [ "ptrauth"(i64 1, i64 0, i64 0) ] ret i32 %tmp0 } @@ -73,7 +73,7 @@ define i32 @test_call_ia_imm(ptr %arg0) #0 { ; ELF-NEXT: blraa x0, x17 ; ELF-NEXT: ldr x30, [sp], #16 ; ELF-NEXT: ret - %tmp0 = call i32 %arg0() [ "ptrauth"(i32 0, i64 42) ] + %tmp0 = call i32 %arg0() [ "ptrauth"(i64 0, i64 42, i64 0) ] ret i32 %tmp0 } @@ -91,7 +91,7 @@ define i32 @test_call_ib_imm(ptr %arg0) #0 { ; ELF-NEXT: blrab x0, x17 ; ELF-NEXT: ldr x30, [sp], #16 ; ELF-NEXT: ret - %tmp0 = call i32 %arg0() [ "ptrauth"(i32 1, i64 42) ] + %tmp0 = call i32 %arg0() [ "ptrauth"(i64 1, i64 42, i64 0) ] ret i32 %tmp0 } @@ -99,7 +99,7 @@ define i32 @test_tailcall_ia_imm(ptr %arg0) #0 { ; CHECK-LABEL: test_tailcall_ia_imm: ; CHECK-NEXT: mov x16, #42 ; CHECK-NEXT: braa x0, x16 - %tmp0 = tail call i32 %arg0() [ "ptrauth"(i32 0, i64 42) ] + %tmp0 = tail call i32 %arg0() [ "ptrauth"(i64 0, i64 42, i64 0) ] ret i32 %tmp0 } @@ -107,7 +107,7 @@ define i32 @test_tailcall_ib_imm(ptr %arg0) #0 { ; CHECK-LABEL: test_tailcall_ib_imm: ; CHECK-NEXT: mov x16, #42 ; CHECK-NEXT: brab x0, x16 - %tmp0 = tail call i32 %arg0() [ "ptrauth"(i32 1, i64 42) ] + %tmp0 = tail call i32 %arg0() [ "ptrauth"(i64 1, i64 42, i64 0) ] ret i32 %tmp0 } @@ -126,7 +126,7 @@ define i32 @test_call_ia_var(ptr %arg0, ptr %arg1) #0 { ; ELF-NEXT: ldr x30, [sp], #16 ; ELF-NEXT: ret %tmp0 = load i64, ptr %arg1 - %tmp1 = call i32 %arg0() [ "ptrauth"(i32 0, i64 %tmp0) ] + %tmp1 = call i32 %arg0() [ "ptrauth"(i64 0, i64 0, i64 %tmp0) ] ret i32 %tmp1 } @@ -145,7 +145,7 @@ define i32 @test_call_ib_var(ptr %arg0, ptr %arg1) #0 { ; ELF-NEXT: ldr x30, [sp], #16 ; ELF-NEXT: ret %tmp0 = load i64, ptr %arg1 - %tmp1 = call i32 %arg0() [ "ptrauth"(i32 1, i64 %tmp0) ] + %tmp1 = call i32 %arg0() [ "ptrauth"(i64 1, i64 0, i64 %tmp0) ] ret i32 %tmp1 } @@ -154,7 +154,7 @@ define i32 @test_tailcall_ia_var(ptr %arg0, ptr %arg1) #0 { ; CHECK: ldr x1, [x1] ; CHECK: braa x0, x1 %tmp0 = load i64, ptr %arg1 - %tmp1 = tail call i32 %arg0() [ "ptrauth"(i32 0, i64 %tmp0) ] + %tmp1 = tail call i32 %arg0() [ "ptrauth"(i64 0, i64 0, i64 %tmp0) ] ret i32 %tmp1 } @@ -163,10 +163,132 @@ define i32 @test_tailcall_ib_var(ptr %arg0, ptr %arg1) #0 { ; CHECK: ldr x1, [x1] ; CHECK: brab x0, x1 %tmp0 = load i64, ptr %arg1 - %tmp1 = tail call i32 %arg0() [ "ptrauth"(i32 1, i64 %tmp0) ] + %tmp1 = tail call i32 %arg0() [ "ptrauth"(i64 1, i64 0, i64 %tmp0) ] ret i32 %tmp1 } +define i32 @test_call_da_0(ptr %arg0) #0 { +; DARWIN-LABEL: test_call_da_0: +; DARWIN-NEXT: stp x29, x30, [sp, #-16]! +; DARWIN-NEXT: mov x16, x0 +; DARWIN-NEXT: autdza x16 +; DARWIN-NEXT: blr x16 +; DARWIN-NEXT: ldp x29, x30, [sp], #16 +; DARWIN-NEXT: ret +; +; ELF-LABEL: test_call_da_0: +; ELF-NEXT: str x30, [sp, #-16]! +; ELF-NEXT: mov x16, x0 +; ELF-NEXT: autdza x16 +; ELF-NEXT: blr x16 +; ELF-NEXT: ldr x30, [sp], #16 +; ELF-NEXT: ret + %tmp0 = call i32 %arg0() [ "ptrauth"(i64 2, i64 0, i64 0) ] + ret i32 %tmp0 +} + +define i32 @test_call_db_0(ptr %arg0) #0 { +; DARWIN-LABEL: test_call_db_0: +; DARWIN-NEXT: stp x29, x30, [sp, #-16]! +; DARWIN-NEXT: mov x16, x0 +; DARWIN-NEXT: autdzb x16 +; DARWIN-NEXT: blr x16 +; DARWIN-NEXT: ldp x29, x30, [sp], #16 +; DARWIN-NEXT: ret +; +; ELF-LABEL: test_call_db_0: +; ELF-NEXT: str x30, [sp, #-16]! +; ELF-NEXT: mov x16, x0 +; ELF-NEXT: autdzb x16 +; ELF-NEXT: blr x16 +; ELF-NEXT: ldr x30, [sp], #16 +; ELF-NEXT: ret + %tmp0 = call i32 %arg0() [ "ptrauth"(i64 3, i64 0, i64 0) ] + ret i32 %tmp0 +} + +define i32 @test_call_da_imm(ptr %arg0) #0 { +; DARWIN-LABEL: test_call_da_imm: +; DARWIN-NEXT: stp x29, x30, [sp, #-16]! +; DARWIN-NEXT: mov x17, #42 +; DARWIN-NEXT: mov x16, x0 +; DARWIN-NEXT: autda x16, x17 +; DARWIN-NEXT: blr x16 +; DARWIN-NEXT: ldp x29, x30, [sp], #16 +; DARWIN-NEXT: ret +; +; ELF-LABEL: test_call_da_imm: +; ELF-NEXT: str x30, [sp, #-16]! +; ELF-NEXT: mov x17, #42 +; ELF-NEXT: mov x16, x0 +; ELF-NEXT: autda x16, x17 +; ELF-NEXT: blr x16 +; ELF-NEXT: ldr x30, [sp], #16 +; ELF-NEXT: ret + %tmp0 = call i32 %arg0() [ "ptrauth"(i64 2, i64 42, i64 0) ] + ret i32 %tmp0 +} + +define i32 @test_call_db_imm(ptr %arg0) #0 { +; DARWIN-LABEL: test_call_db_imm: +; DARWIN-NEXT: stp x29, x30, [sp, #-16]! +; DARWIN-NEXT: mov x17, #42 +; DARWIN-NEXT: mov x16, x0 +; DARWIN-NEXT: autdb x16, x17 +; DARWIN-NEXT: blr x16 +; DARWIN-NEXT: ldp x29, x30, [sp], #16 +; DARWIN-NEXT: ret +; +; ELF-LABEL: test_call_db_imm: +; ELF-NEXT: str x30, [sp, #-16]! +; ELF-NEXT: mov x17, #42 +; ELF-NEXT: mov x16, x0 +; ELF-NEXT: autdb x16, x17 +; ELF-NEXT: blr x16 +; ELF-NEXT: ldr x30, [sp], #16 +; ELF-NEXT: ret + %tmp0 = call i32 %arg0() [ "ptrauth"(i64 3, i64 42, i64 0) ] + ret i32 %tmp0 +} + +define i32 @test_tailcall_da_0(ptr %arg0) #0 { +; CHECK-LABEL: test_tailcall_da_0: +; CHECK-NEXT: mov x17, x0 +; CHECK-NEXT: autdza x17 +; CHECK-NEXT: br x17 + %tmp0 = tail call i32 %arg0() [ "ptrauth"(i64 2, i64 0, i64 0) ] + ret i32 %tmp0 +} + +define i32 @test_tailcall_db_0(ptr %arg0) #0 { +; CHECK-LABEL: test_tailcall_db_0: +; CHECK-NEXT: mov x17, x0 +; CHECK-NEXT: autdzb x17 +; CHECK-NEXT: br x17 + %tmp0 = tail call i32 %arg0() [ "ptrauth"(i64 3, i64 0, i64 0) ] + ret i32 %tmp0 +} + +define i32 @test_tailcall_da_imm(ptr %arg0) #0 { +; CHECK-LABEL: test_tailcall_da_imm: +; CHECK-NEXT: mov x16, #42 +; CHECK-NEXT: mov x17, x0 +; CHECK-NEXT: autda x17, x16 +; CHECK-NEXT: br x17 + %tmp0 = tail call i32 %arg0() [ "ptrauth"(i64 2, i64 42, i64 0) ] + ret i32 %tmp0 +} + +define i32 @test_tailcall_db_imm(ptr %arg0) #0 { +; CHECK-LABEL: test_tailcall_db_imm: +; CHECK-NEXT: mov x16, #42 +; CHECK-NEXT: mov x17, x0 +; CHECK-NEXT: autdb x17, x16 +; CHECK-NEXT: br x17 + %tmp0 = tail call i32 %arg0() [ "ptrauth"(i64 3, i64 42, i64 0) ] + ret i32 %tmp0 +} + define void @test_tailcall_omit_mov_x16_x16(ptr %objptr) #0 { ; CHECK-LABEL: test_tailcall_omit_mov_x16_x16: ; DARWIN-NEXT: ldr x16, [x0] @@ -186,13 +308,11 @@ define void @test_tailcall_omit_mov_x16_x16(ptr %objptr) #0 { ; ELF-NEXT: braa x2, x16 %vtable.signed = load ptr, ptr %objptr, align 8 %objptr.int = ptrtoint ptr %objptr to i64 - %vtable.discr = tail call i64 @llvm.ptrauth.blend(i64 %objptr.int, i64 6503) %vtable.signed.int = ptrtoint ptr %vtable.signed to i64 - %vtable.unsigned.int = tail call i64 @llvm.ptrauth.auth(i64 %vtable.signed.int, i32 2, i64 %vtable.discr) + %vtable.unsigned.int = tail call i64 @llvm.ptrauth.auth(i64 %vtable.signed.int) [ "ptrauth"(i64 2, i64 6503, i64 %objptr.int) ] %vtable.unsigned = inttoptr i64 %vtable.unsigned.int to ptr %virt.func.signed = load ptr, ptr %vtable.unsigned, align 8 - %virt.func.discr = tail call i64 @llvm.ptrauth.blend(i64 %vtable.unsigned.int, i64 54167) - tail call void %virt.func.signed(ptr %objptr) [ "ptrauth"(i32 0, i64 %virt.func.discr) ] + tail call void %virt.func.signed(ptr %objptr) [ "ptrauth"(i64 0, i64 54167, i64 %vtable.unsigned.int) ] ret void } @@ -222,13 +342,11 @@ define i32 @test_call_omit_extra_moves(ptr %objptr) #0 { ; CHECK-NEXT: ret %vtable.signed = load ptr, ptr %objptr %objptr.int = ptrtoint ptr %objptr to i64 - %vtable.discr = tail call i64 @llvm.ptrauth.blend(i64 %objptr.int, i64 6503) %vtable.signed.int = ptrtoint ptr %vtable.signed to i64 - %vtable.int = tail call i64 @llvm.ptrauth.auth(i64 %vtable.signed.int, i32 2, i64 %vtable.discr) + %vtable.int = tail call i64 @llvm.ptrauth.auth(i64 %vtable.signed.int) [ "ptrauth"(i64 2, i64 6503, i64 %objptr.int) ] %vtable = inttoptr i64 %vtable.int to ptr %callee.signed = load ptr, ptr %vtable - %callee.discr = tail call i64 @llvm.ptrauth.blend(i64 %vtable.int, i64 34646) - %call.result = tail call i32 %callee.signed(ptr %objptr) [ "ptrauth"(i32 0, i64 %callee.discr) ] + %call.result = tail call i32 %callee.signed(ptr %objptr) [ "ptrauth"(i64 0, i64 34646, i64 %vtable.int) ] ret i32 42 } @@ -249,9 +367,8 @@ define i64 @test_call_discr_csr_live(ptr %fnptr, i64 %addr.discr) #0 { ; ELF-NEXT: ldp x20, x19, [sp, #16] ; ELF-NEXT: ldr x30, [sp], #32 ; ELF-NEXT: ret - %discr = tail call i64 @llvm.ptrauth.blend(i64 %addr.discr, i64 6503) - tail call void %fnptr() [ "ptrauth"(i32 0, i64 %discr) ] - tail call void %fnptr() [ "ptrauth"(i32 0, i64 %discr) ] + tail call void %fnptr() [ "ptrauth"(i64 0, i64 6503, i64 %addr.discr) ] + tail call void %fnptr() [ "ptrauth"(i64 0, i64 6503, i64 %addr.discr) ] ret i64 %addr.discr } @@ -272,9 +389,8 @@ define i64 @test_call_discr_csr_killed(ptr %fnptr, i64 %addr.discr) #0 { ; ELF-NEXT: mov w0, #42 ; ELF-NEXT: ldr x30, [sp], #32 ; ELF-NEXT: ret - %discr = tail call i64 @llvm.ptrauth.blend(i64 %addr.discr, i64 6503) - tail call void %fnptr() [ "ptrauth"(i32 0, i64 %discr) ] - tail call void %fnptr() [ "ptrauth"(i32 0, i64 %discr) ] + tail call void %fnptr() [ "ptrauth"(i64 0, i64 6503, i64 %addr.discr) ] + tail call void %fnptr() [ "ptrauth"(i64 0, i64 6503, i64 %addr.discr) ] ret i64 42 } @@ -290,8 +406,7 @@ define i64 @test_call_discr_arg(ptr %fnptr, i64 %addr.discr) #0 { ; ELF-NEXT: mov w0, #42 ; ELF-NEXT: ldr x30, [sp], #16 ; ELF-NEXT: ret - %discr = tail call i64 @llvm.ptrauth.blend(i64 %addr.discr, i64 6503) - tail call void %fnptr(ptr null, i64 %addr.discr) [ "ptrauth"(i32 0, i64 %discr) ] + tail call void %fnptr(ptr null, i64 %addr.discr) [ "ptrauth"(i64 0, i64 6503, i64 %addr.discr) ] ret i64 42 } @@ -305,8 +420,7 @@ define i64 @test_call_discr_non_arg(ptr %fnptr, i64 %addr.discr) #0 { ; ELF-NEXT: mov w0, #42 ; ELF-NEXT: ldr x30, [sp], #16 ; ELF-NEXT: ret - %discr = tail call i64 @llvm.ptrauth.blend(i64 %addr.discr, i64 6503) - tail call void %fnptr() [ "ptrauth"(i32 0, i64 %discr) ] + tail call void %fnptr() [ "ptrauth"(i64 0, i64 6503, i64 %addr.discr) ] ret i64 42 } @@ -318,8 +432,7 @@ define i64 @test_tailcall_discr_arg(ptr %fnptr, i64 %addr.discr) #0 { ; ELF-NEXT: mov x16, x1 ; ELF-NEXT: movk x16, #6503, lsl #48 ; ELF-NEXT: braa x2, x16 - %discr = tail call i64 @llvm.ptrauth.blend(i64 %addr.discr, i64 6503) - %result = tail call i64 %fnptr(ptr null, i64 %addr.discr) [ "ptrauth"(i32 0, i64 %discr) ] + %result = tail call i64 %fnptr(ptr null, i64 %addr.discr) [ "ptrauth"(i64 0, i64 6503, i64 %addr.discr) ] ret i64 %result } @@ -335,7 +448,7 @@ define i32 @test_call_ia_arg(ptr %arg0, i64 %arg1) #0 { ; ELF-NEXT: blraa x0, x1 ; ELF-NEXT: ldr x30, [sp], #16 ; ELF-NEXT: ret - %tmp0 = call i32 %arg0() [ "ptrauth"(i32 0, i64 %arg1) ] + %tmp0 = call i32 %arg0() [ "ptrauth"(i64 0, i64 0, i64 %arg1) ] ret i32 %tmp0 } @@ -351,21 +464,21 @@ define i32 @test_call_ib_arg(ptr %arg0, i64 %arg1) #0 { ; ELF-NEXT: blrab x0, x1 ; ELF-NEXT: ldr x30, [sp], #16 ; ELF-NEXT: ret - %tmp0 = call i32 %arg0() [ "ptrauth"(i32 1, i64 %arg1) ] + %tmp0 = call i32 %arg0() [ "ptrauth"(i64 1, i64 0, i64 %arg1) ] ret i32 %tmp0 } define i32 @test_tailcall_ia_arg(ptr %arg0, i64 %arg1) #0 { ; CHECK-LABEL: test_tailcall_ia_arg: ; CHECK: braa x0, x1 - %tmp0 = tail call i32 %arg0() [ "ptrauth"(i32 0, i64 %arg1) ] + %tmp0 = tail call i32 %arg0() [ "ptrauth"(i64 0, i64 0, i64 %arg1) ] ret i32 %tmp0 } define i32 @test_tailcall_ib_arg(ptr %arg0, i64 %arg1) #0 { ; CHECK-LABEL: test_tailcall_ib_arg: ; CHECK: brab x0, x1 - %tmp0 = tail call i32 %arg0() [ "ptrauth"(i32 1, i64 %arg1) ] + %tmp0 = tail call i32 %arg0() [ "ptrauth"(i64 1, i64 0, i64 %arg1) ] ret i32 %tmp0 } @@ -384,7 +497,7 @@ define i32 @test_call_ia_arg_ind(ptr %arg0, i64 %arg1) #0 { ; ELF-NEXT: ldr x30, [sp], #16 ; ELF-NEXT: ret %tmp0 = load ptr, ptr %arg0 - %tmp1 = call i32 %tmp0() [ "ptrauth"(i32 0, i64 %arg1) ] + %tmp1 = call i32 %tmp0() [ "ptrauth"(i64 0, i64 0, i64 %arg1) ] ret i32 %tmp1 } @@ -403,7 +516,7 @@ define i32 @test_call_ib_arg_ind(ptr %arg0, i64 %arg1) #0 { ; ELF-NEXT: ldr x30, [sp], #16 ; ELF-NEXT: ret %tmp0 = load ptr, ptr %arg0 - %tmp1 = call i32 %tmp0() [ "ptrauth"(i32 1, i64 %arg1) ] + %tmp1 = call i32 %tmp0() [ "ptrauth"(i64 1, i64 0, i64 %arg1) ] ret i32 %tmp1 } @@ -412,7 +525,7 @@ define i32 @test_tailcall_ia_arg_ind(ptr %arg0, i64 %arg1) #0 { ; CHECK: ldr x0, [x0] ; CHECK: braa x0, x1 %tmp0 = load ptr, ptr %arg0 - %tmp1 = tail call i32 %tmp0() [ "ptrauth"(i32 0, i64 %arg1) ] + %tmp1 = tail call i32 %tmp0() [ "ptrauth"(i64 0, i64 0, i64 %arg1) ] ret i32 %tmp1 } @@ -421,7 +534,7 @@ define i32 @test_tailcall_ib_arg_ind(ptr %arg0, i64 %arg1) #0 { ; CHECK: ldr x0, [x0] ; CHECK: brab x0, x1 %tmp0 = load ptr, ptr %arg0 - %tmp1 = tail call i32 %tmp0() [ "ptrauth"(i32 1, i64 %arg1) ] + %tmp1 = tail call i32 %tmp0() [ "ptrauth"(i64 1, i64 0, i64 %arg1) ] ret i32 %tmp1 } @@ -439,7 +552,7 @@ define i32 @test_direct_call() #0 { ; ELF-NEXT: bl f ; ELF-NEXT: ldr x30, [sp], #16 ; ELF-NEXT: ret - %tmp0 = call i32 ptrauth(ptr @f, i32 0, i64 42)() [ "ptrauth"(i32 0, i64 42) ] + %tmp0 = call i32 ptrauth(ptr @f, [i64 0, i64 42, i64 0])() [ "ptrauth"(i64 0, i64 42, i64 0) ] ret i32 %tmp0 } @@ -449,7 +562,7 @@ define i32 @test_direct_tailcall(ptr %arg0) #0 { ; ; ELF-LABEL: test_direct_tailcall: ; ELF-NEXT: b f - %tmp0 = tail call i32 ptrauth(ptr @f, i32 0, i64 42)() [ "ptrauth"(i32 0, i64 42) ] + %tmp0 = tail call i32 ptrauth(ptr @f, [i64 0, i64 42, i64 0])() [ "ptrauth"(i64 0, i64 42, i64 0) ] ret i32 %tmp0 } @@ -477,7 +590,7 @@ define i32 @test_direct_call_mismatch() #0 { ; ELF-NEXT: blrab x8, x17 ; ELF-NEXT: ldr x30, [sp], #16 ; ELF-NEXT: ret - %tmp0 = call i32 ptrauth(ptr @f, i32 0, i64 42)() [ "ptrauth"(i32 1, i64 42) ] + %tmp0 = call i32 ptrauth(ptr @f, [i64 0, i64 42, i64 0])() [ "ptrauth"(i64 1, i64 42, i64 0) ] ret i32 %tmp0 } @@ -493,7 +606,7 @@ define i32 @test_direct_call_addr() #0 { ; ELF-NEXT: bl f ; ELF-NEXT: ldr x30, [sp], #16 ; ELF-NEXT: ret - %tmp0 = call i32 ptrauth(ptr @f, i32 1, i64 0, ptr @f.ref.ib.0.addr)() [ "ptrauth"(i32 1, i64 ptrtoint (ptr @f.ref.ib.0.addr to i64)) ] + %tmp0 = call i32 ptrauth(ptr @f, [i64 1, i64 0, i64 ptrtoint (ptr @f.ref.ib.0.addr to i64)])() [ "ptrauth"(i64 1, i64 0, i64 ptrtoint (ptr @f.ref.ib.0.addr to i64)) ] ret i32 %tmp0 } @@ -509,8 +622,7 @@ define i32 @test_direct_call_addr_blend() #0 { ; ELF-NEXT: bl f ; ELF-NEXT: ldr x30, [sp], #16 ; ELF-NEXT: ret - %tmp0 = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @f.ref.ib.42.addr to i64), i64 42) - %tmp1 = call i32 ptrauth(ptr @f, i32 1, i64 42, ptr @f.ref.ib.42.addr)() [ "ptrauth"(i32 1, i64 %tmp0) ] + %tmp1 = call i32 ptrauth(ptr @f, [i64 1, i64 42, i64 ptrtoint (ptr @f.ref.ib.42.addr to i64)])() [ "ptrauth"(i64 1, i64 42, i64 ptrtoint (ptr @f.ref.ib.42.addr to i64)) ] ret i32 %tmp1 } @@ -526,7 +638,7 @@ define i32 @test_direct_call_addr_gep_different_index_types() #0 { ; ELF-NEXT: bl f ; ELF-NEXT: ldr x30, [sp], #16 ; ELF-NEXT: ret - %tmp0 = call i32 ptrauth(ptr @f, i32 1, i64 0, ptr getelementptr ({ ptr }, ptr @f_struct.ref.ib.0.addr, i64 0, i32 0))() [ "ptrauth"(i32 1, i64 ptrtoint (ptr getelementptr ({ ptr }, ptr @f_struct.ref.ib.0.addr, i32 0, i32 0) to i64)) ] + %tmp0 = call i32 ptrauth(ptr @f, [i64 1, i64 0, i64 ptrtoint (ptr getelementptr ({ ptr }, ptr @f_struct.ref.ib.0.addr, i64 0, i32 0) to i64)])() [ "ptrauth"(i64 1, i64 0, i64 ptrtoint (ptr getelementptr ({ ptr }, ptr @f_struct.ref.ib.0.addr, i32 0, i32 0) to i64)) ] ret i32 %tmp0 } @@ -542,8 +654,7 @@ define i32 @test_direct_call_addr_blend_gep_different_index_types() #0 { ; ELF-NEXT: bl f ; ELF-NEXT: ldr x30, [sp], #16 ; ELF-NEXT: ret - %tmp0 = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr getelementptr ({ ptr }, ptr @f_struct.ref.ib.123.addr, i32 0, i32 0) to i64), i64 123) - %tmp1 = call i32 ptrauth(ptr @f, i32 1, i64 123, ptr getelementptr ({ ptr }, ptr @f_struct.ref.ib.123.addr, i64 0, i32 0))() [ "ptrauth"(i32 1, i64 %tmp0) ] + %tmp1 = call i32 ptrauth(ptr @f, [i64 1, i64 123, i64 ptrtoint (ptr getelementptr ({ ptr }, ptr @f_struct.ref.ib.123.addr, i64 0, i32 0) to i64)])() [ "ptrauth"(i64 1, i64 123, i64 ptrtoint (ptr getelementptr ({ ptr }, ptr @f_struct.ref.ib.123.addr, i32 0, i32 0) to i64)) ] ret i32 %tmp1 } @@ -554,7 +665,4 @@ define i32 @test_direct_call_addr_blend_gep_different_index_types() #0 { declare void @f() -declare i64 @llvm.ptrauth.auth(i64, i32, i64) -declare i64 @llvm.ptrauth.blend(i64, i64) - attributes #0 = { nounwind } diff --git a/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll b/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll index 76339a7cc5791..e0b2600102658 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-constant-in-code.ll @@ -2,30 +2,34 @@ ;--- err1.ll -; RUN: not --crash llc < err1.ll -mtriple aarch64-elf -mattr=+pauth \ +; RUN: not llc < err1.ll -mtriple aarch64-elf -mattr=+pauth \ ; RUN: -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR1 %s -; RUN: not --crash llc < err1.ll -mtriple arm64-apple-ios -mattr=+pauth \ +; RUN: not llc < err1.ll -mtriple arm64-apple-ios -mattr=+pauth \ ; RUN: -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR1 %s @g = external global i32 define ptr @foo() { -; ERR1: LLVM ERROR: key in ptrauth global out of range [0, 3] - ret ptr ptrauth (ptr @g, i32 4) +; ERR1: Ptrauth schema violates target-specific constraints: +; ERR1: ptr ptrauth (ptr @g, [i64 4, i64 0, i64 0]) +; ERR1: LLVM ERROR: Invalid ptrauth schema: key must be constant in range [0, 3] + ret ptr ptrauth (ptr @g, [i64 4, i64 0, i64 0]) } ;--- err2.ll -; RUN: not --crash llc < err2.ll -mtriple aarch64-elf -mattr=+pauth \ +; RUN: not llc < err2.ll -mtriple aarch64-elf -mattr=+pauth \ ; RUN: -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR2 %s -; RUN: not --crash llc < err2.ll -mtriple arm64-apple-ios -mattr=+pauth \ +; RUN: not llc < err2.ll -mtriple arm64-apple-ios -mattr=+pauth \ ; RUN: -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR2 %s @g = external global i32 define ptr @foo() { -; ERR2: LLVM ERROR: constant discriminator in ptrauth global out of range [0, 0xffff] - ret ptr ptrauth (ptr @g, i32 2, i64 65536) +; ERR2: Ptrauth schema violates target-specific constraints: +; ERR2: ptr ptrauth (ptr @g, [i64 2, i64 65536, i64 0]) +; ERR2: LLVM ERROR: Invalid ptrauth schema: constant modifier must be 16-bit unsigned constant + ret ptr ptrauth (ptr @g, [i64 2, i64 65536, i64 0]) } ;--- err3.ll @@ -39,7 +43,7 @@ define ptr @foo() { define ptr @foo() { ; ERR3: LLVM ERROR: unsupported non-zero offset in weak ptrauth global reference - ret ptr ptrauth (ptr getelementptr (i8, ptr @g_weak, i64 16), i32 2, i64 42) + ret ptr ptrauth (ptr getelementptr (i8, ptr @g_weak, i64 16), [i64 2, i64 42, i64 0]) } ;--- err4.ll @@ -50,11 +54,11 @@ define ptr @foo() { ; RUN: -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR4 %s @g_weak = extern_weak global i32 -@g_weak.ref.da.42.addr = dso_local constant ptr ptrauth (ptr @g_weak, i32 2, i64 42, ptr @g_weak.ref.da.42.addr) +@g_weak.ref.da.42.addr = dso_local constant ptr ptrauth (ptr @g_weak, [i64 2, i64 42, i64 ptrtoint (ptr @g_weak.ref.da.42.addr to i64)]) define ptr @foo() { ; ERR4: LLVM ERROR: unsupported weak addr-div ptrauth global - ret ptr ptrauth (ptr @g_weak, i32 0, i64 42, ptr @g_weak.ref.da.42.addr) + ret ptr ptrauth (ptr @g_weak, [i64 0, i64 42, i64 ptrtoint (ptr @g_weak.ref.da.42.addr to i64)]) } ;--- err5.ll @@ -66,7 +70,7 @@ define ptr @foo() { define ptr @foo() { ; ERR5: LLVM ERROR: ptrauth global lowering only supported on MachO/ELF - ret ptr ptrauth (ptr @g, i32 0) + ret ptr ptrauth (ptr @g, [i64 0, i64 0, i64 0]) } ;--- ok.ll @@ -102,7 +106,7 @@ define ptr @test_global_zero_disc() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr @g, i32 0) + ret ptr ptrauth (ptr @g, [i64 0, i64 0, i64 0]) } define ptr @test_global_offset_zero_disc() { @@ -124,7 +128,7 @@ define ptr @test_global_offset_zero_disc() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 16), i32 2) + ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 16), [i64 2, i64 0, i64 0]) } define ptr @test_global_neg_offset_zero_disc() { @@ -148,7 +152,7 @@ define ptr @test_global_neg_offset_zero_disc() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -123456), i32 2) + ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -123456), [i64 2, i64 0, i64 0]) } define ptr @test_global_big_offset_zero_disc() { @@ -174,7 +178,7 @@ define ptr @test_global_big_offset_zero_disc() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 add (i64 2147483648, i64 65537)), i32 2) + ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 add (i64 2147483648, i64 65537)), [i64 2, i64 0, i64 0]) } define ptr @test_global_big_neg_offset_zero_disc() { @@ -200,7 +204,7 @@ define ptr @test_global_big_neg_offset_zero_disc() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -123456789), i32 2) + ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -123456789), [i64 2, i64 0, i64 0]) } define ptr @test_global_huge_neg_offset_zero_disc() { @@ -230,7 +234,7 @@ define ptr @test_global_huge_neg_offset_zero_disc() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -9223372036854775808), i32 2) + ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -9223372036854775808), [i64 2, i64 0, i64 0]) } define ptr @test_global_disc() { @@ -252,10 +256,10 @@ define ptr @test_global_disc() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr @g, i32 0, i64 42) + ret ptr ptrauth (ptr @g, [i64 0, i64 42, i64 0]) } -@g.ref.da.42.addr = dso_local constant ptr ptrauth (ptr @g, i32 2, i64 42, ptr @g.ref.da.42.addr) +@g.ref.da.42.addr = dso_local constant ptr ptrauth (ptr @g, [i64 2, i64 42, i64 ptrtoint (ptr @g.ref.da.42.addr to i64)]) define ptr @test_global_addr_disc() { ; ELF-LABEL: test_global_addr_disc: @@ -284,7 +288,7 @@ define ptr @test_global_addr_disc() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr @g, i32 2, i64 42, ptr @g.ref.da.42.addr) + ret ptr ptrauth (ptr @g, [i64 2, i64 42, i64 ptrtoint (ptr @g.ref.da.42.addr to i64)]) } define ptr @test_global_process_specific() { @@ -304,7 +308,7 @@ define ptr @test_global_process_specific() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr @g, i32 1) + ret ptr ptrauth (ptr @g, [i64 1, i64 0, i64 0]) } ; Non-external symbols don't need to be accessed through the GOT. @@ -326,7 +330,7 @@ define ptr @test_global_strong_def() { ; MACHO-NEXT: mov x0, x16 ; MACHO-NEXT: ret - ret ptr ptrauth (ptr @g_strong_def, i32 2) + ret ptr ptrauth (ptr @g_strong_def, [i64 2, i64 0, i64 0]) } ; weak symbols can't be assumed to be non-nil. Use $auth_ptr$ stub slot always. @@ -346,7 +350,7 @@ define ptr @test_global_weak() { ; MACHO-NEXT: ldr x0, [x0, l_g_weak$auth_ptr$ia$42@PAGEOFF] ; MACHO-NEXT: ret - ret ptr ptrauth (ptr @g_weak, i32 0, i64 42) + ret ptr ptrauth (ptr @g_weak, [i64 0, i64 42, i64 0]) } ; Test another weak symbol to check that stubs are emitted in a stable order. @@ -366,7 +370,7 @@ define ptr @test_global_weak_2() { ; MACHO-NEXT: ldr x0, [x0, l_g_weak_2$auth_ptr$ia$42@PAGEOFF] ; MACHO-NEXT: ret - ret ptr ptrauth (ptr @g_weak_2, i32 0, i64 42) + ret ptr ptrauth (ptr @g_weak_2, [i64 0, i64 42, i64 0]) } ; ELF-LABEL: g_weak$auth_ptr$ia$42: diff --git a/llvm/test/CodeGen/AArch64/ptrauth-elf-got-function-symbols.ll b/llvm/test/CodeGen/AArch64/ptrauth-elf-got-function-symbols.ll index e75acceaa0d12..5d39cf343cbaa 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-elf-got-function-symbols.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-elf-got-function-symbols.ll @@ -31,7 +31,7 @@ @fptr = private global ptr null define void @foo() { - store ptr ptrauth (ptr @bar, i32 0), ptr @fptr + store ptr ptrauth (ptr @bar, [i64 0, i64 0, i64 0]), ptr @fptr ret void } diff --git a/llvm/test/CodeGen/AArch64/ptrauth-fpac.ll b/llvm/test/CodeGen/AArch64/ptrauth-fpac.ll index 787b8886c917b..dafb23697ffe3 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-fpac.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-fpac.ll @@ -18,7 +18,7 @@ define i64 @test_auth_ia(i64 %arg, i64 %arg1) { ; ELF: // %bb.0: ; ELF-NEXT: autia x0, x1 ; ELF-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 0, i64 %arg1) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 0, i64 0, i64 %arg1) ] ret i64 %tmp } @@ -34,7 +34,7 @@ define i64 @test_auth_ia_zero(i64 %arg) { ; ELF: // %bb.0: ; ELF-NEXT: autiza x0 ; ELF-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 0, i64 0) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 0, i64 0, i64 0) ] ret i64 %tmp } @@ -50,7 +50,7 @@ define i64 @test_auth_ib(i64 %arg, i64 %arg1) { ; ELF: // %bb.0: ; ELF-NEXT: autib x0, x1 ; ELF-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 1, i64 %arg1) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 1, i64 0, i64 %arg1) ] ret i64 %tmp } @@ -66,7 +66,7 @@ define i64 @test_auth_ib_zero(i64 %arg) { ; ELF: // %bb.0: ; ELF-NEXT: autizb x0 ; ELF-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 1, i64 0) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 1, i64 0, i64 0) ] ret i64 %tmp } @@ -82,7 +82,7 @@ define i64 @test_auth_da(i64 %arg, i64 %arg1) { ; ELF: // %bb.0: ; ELF-NEXT: autda x0, x1 ; ELF-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 2, i64 %arg1) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 2, i64 0, i64 %arg1) ] ret i64 %tmp } @@ -98,7 +98,7 @@ define i64 @test_auth_da_zero(i64 %arg) { ; ELF: // %bb.0: ; ELF-NEXT: autdza x0 ; ELF-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 2, i64 0) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 2, i64 0, i64 0) ] ret i64 %tmp } @@ -114,7 +114,7 @@ define i64 @test_auth_db(i64 %arg, i64 %arg1) { ; ELF: // %bb.0: ; ELF-NEXT: autdb x0, x1 ; ELF-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 3, i64 %arg1) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 3, i64 0, i64 %arg1) ] ret i64 %tmp } @@ -130,7 +130,7 @@ define i64 @test_auth_db_zero(i64 %arg) { ; ELF: // %bb.0: ; ELF-NEXT: autdzb x0 ; ELF-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 3, i64 0) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 3, i64 0, i64 0) ] ret i64 %tmp } @@ -160,7 +160,7 @@ define i64 @test_resign_ia_ia(i64 %arg, i64 %arg1, i64 %arg2) { ; FPAC-NEXT: pacia x16, x2 ; FPAC-NEXT: mov x0, x16 ; FPAC-NEXT: ret - %tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 0, i64 %arg1, i32 0, i64 %arg2) + %tmp = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 0, i64 0, i64 %arg1), "ptrauth"(i64 0, i64 0, i64 %arg2) ] ret i64 %tmp } @@ -188,7 +188,7 @@ define i64 @test_resign_ib_ia(i64 %arg, i64 %arg1, i64 %arg2) { ; FPAC-NEXT: pacia x16, x2 ; FPAC-NEXT: mov x0, x16 ; FPAC-NEXT: ret - %tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 1, i64 %arg1, i32 0, i64 %arg2) + %tmp = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 1, i64 0, i64 %arg1), "ptrauth"(i64 0, i64 0, i64 %arg2) ] ret i64 %tmp } @@ -216,7 +216,7 @@ define i64 @test_resign_da_ia(i64 %arg, i64 %arg1, i64 %arg2) { ; FPAC-NEXT: pacia x16, x2 ; FPAC-NEXT: mov x0, x16 ; FPAC-NEXT: ret - %tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 2, i64 %arg1, i32 0, i64 %arg2) + %tmp = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 2, i64 0, i64 %arg1), "ptrauth"(i64 0, i64 0, i64 %arg2) ] ret i64 %tmp } @@ -244,7 +244,7 @@ define i64 @test_resign_db_ia(i64 %arg, i64 %arg1, i64 %arg2) { ; FPAC-NEXT: pacia x16, x2 ; FPAC-NEXT: mov x0, x16 ; FPAC-NEXT: ret - %tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 3, i64 %arg1, i32 0, i64 %arg2) + %tmp = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 3, i64 0, i64 %arg1), "ptrauth"(i64 0, i64 0, i64 %arg2) ] ret i64 %tmp } @@ -272,7 +272,7 @@ define i64 @test_resign_db_ib(i64 %arg, i64 %arg1, i64 %arg2) { ; FPAC-NEXT: pacib x16, x2 ; FPAC-NEXT: mov x0, x16 ; FPAC-NEXT: ret - %tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 3, i64 %arg1, i32 1, i64 %arg2) + %tmp = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 3, i64 0, i64 %arg1), "ptrauth"(i64 1, i64 0, i64 %arg2) ] ret i64 %tmp } @@ -300,7 +300,7 @@ define i64 @test_resign_db_da(i64 %arg, i64 %arg1, i64 %arg2) { ; FPAC-NEXT: pacda x16, x2 ; FPAC-NEXT: mov x0, x16 ; FPAC-NEXT: ret - %tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 3, i64 %arg1, i32 2, i64 %arg2) + %tmp = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 3, i64 0, i64 %arg1), "ptrauth"(i64 2, i64 0, i64 %arg2) ] ret i64 %tmp } @@ -328,7 +328,7 @@ define i64 @test_resign_db_db(i64 %arg, i64 %arg1, i64 %arg2) { ; FPAC-NEXT: pacdb x16, x2 ; FPAC-NEXT: mov x0, x16 ; FPAC-NEXT: ret - %tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 3, i64 %arg1, i32 3, i64 %arg2) + %tmp = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 3, i64 0, i64 %arg1), "ptrauth"(i64 3, i64 0, i64 %arg2) ] ret i64 %tmp } @@ -356,7 +356,7 @@ define i64 @test_resign_iza_db(i64 %arg, i64 %arg1, i64 %arg2) { ; FPAC-NEXT: pacdb x16, x2 ; FPAC-NEXT: mov x0, x16 ; FPAC-NEXT: ret - %tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 0, i64 0, i32 3, i64 %arg2) + %tmp = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 3, i64 0, i64 %arg2) ] ret i64 %tmp } @@ -384,7 +384,7 @@ define i64 @test_resign_da_dzb(i64 %arg, i64 %arg1, i64 %arg2) { ; FPAC-NEXT: pacdzb x16 ; FPAC-NEXT: mov x0, x16 ; FPAC-NEXT: ret - %tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 2, i64 %arg1, i32 3, i64 0) + %tmp = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 2, i64 0, i64 %arg1), "ptrauth"(i64 3, i64 0, i64 0) ] ret i64 %tmp } @@ -421,9 +421,6 @@ define i64 @test_auth_trap_attribute(i64 %arg, i64 %arg1) "ptrauth-auth-traps" { ; ELF-FPAC: %bb.0: ; ELF-FPAC-NEXT: autia x0, x1 ; ELF-FPAC-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 0, i64 %arg1) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 0, i64 0, i64 %arg1) ] ret i64 %tmp } - -declare i64 @llvm.ptrauth.auth(i64, i32, i64) -declare i64 @llvm.ptrauth.resign(i64, i32, i64, i32, i64) diff --git a/llvm/test/CodeGen/AArch64/ptrauth-init-fini.ll b/llvm/test/CodeGen/AArch64/ptrauth-init-fini.ll index 186a31c63ba10..75bd6226cc3f3 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-init-fini.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-init-fini.ll @@ -27,8 +27,8 @@ ;; ^^^^ 0xD9D4: constant discriminator = 55764 ;; ^^ 0x80: bits 61..60 key = IA; bit 63 addr disc = false -@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @foo, i32 0, i64 55764), ptr null }] -@llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @bar, i32 0, i64 55764), ptr null }] +@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @foo, [i64 0, i64 55764, i64 0]), ptr null }] +@llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @bar, [i64 0, i64 55764, i64 0]), ptr null }] define void @foo() { ret void @@ -65,8 +65,8 @@ define void @bar() { ;; ^^^^ 0xD9D4: constant discriminator = 55764 ;; ^^ 0x80: bits 61..60 key = IA; bit 63 addr disc = true -@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @foo, i32 0, i64 55764, ptr inttoptr (i64 1 to ptr)), ptr null }] -@llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @bar, i32 0, i64 55764, ptr inttoptr (i64 1 to ptr)), ptr null }] +@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @foo, [i64 0, i64 55764, i64 1]), ptr null }] +@llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @bar, [i64 0, i64 55764, i64 1]), ptr null }] define void @foo() { ret void @@ -83,7 +83,7 @@ define void @bar() { ; ERR1: LLVM ERROR: unexpected address discrimination value for ctors/dtors entry, only 'ptr inttoptr (i64 1 to ptr)' is allowed -@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @foo, i32 0, i64 55764, ptr inttoptr (i64 2 to ptr)), ptr null }] +@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @foo, [i64 0, i64 55764, i64 2]), ptr null }] define void @foo() { ret void @@ -97,7 +97,7 @@ define void @foo() { ; ERR2: LLVM ERROR: unexpected address discrimination value for ctors/dtors entry, only 'ptr inttoptr (i64 1 to ptr)' is allowed @g = external global ptr -@llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @bar, i32 0, i64 55764, ptr @g), ptr null }] +@llvm.global_dtors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr ptrauth (ptr @bar, [i64 0, i64 55764, i64 ptrtoint (ptr @g to i64)]), ptr null }] define void @bar() { ret void diff --git a/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-auth-resign-with-blend.ll b/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-auth-resign-with-blend.ll index e2aea6df78250..8ece0a529ab64 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-auth-resign-with-blend.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-auth-resign-with-blend.ll @@ -73,8 +73,7 @@ define i64 @test_auth_blend(i64 %arg, i64 %arg1) { ; TRAP-NEXT: Lauth_success_0: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp0 = call i64 @llvm.ptrauth.blend(i64 %arg1, i64 65535) - %tmp1 = call i64 @llvm.ptrauth.auth(i64 %arg, i32 2, i64 %tmp0) + %tmp1 = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 2, i64 65535, i64 %arg1) ] ret i64 %tmp1 } @@ -134,9 +133,7 @@ define i64 @test_resign_blend(i64 %arg, i64 %arg1, i64 %arg2) { ; TRAP-NEXT: pacdb x16, x17 ; TRAP-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp0 = call i64 @llvm.ptrauth.blend(i64 %arg1, i64 12345) - %tmp1 = call i64 @llvm.ptrauth.blend(i64 %arg2, i64 56789) - %tmp2 = call i64 @llvm.ptrauth.resign(i64 %arg, i32 2, i64 %tmp0, i32 3, i64 %tmp1) + %tmp2 = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 2, i64 12345, i64 %arg1), "ptrauth"(i64 3, i64 56789, i64 %arg2) ] ret i64 %tmp2 } @@ -193,8 +190,7 @@ define i64 @test_resign_blend_and_const(i64 %arg, i64 %arg1) { ; TRAP-NEXT: pacdb x16, x17 ; TRAP-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp0 = call i64 @llvm.ptrauth.blend(i64 %arg1, i64 12345) - %tmp1 = call i64 @llvm.ptrauth.resign(i64 %arg, i32 2, i64 %tmp0, i32 3, i64 56789) + %tmp1 = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 2, i64 12345, i64 %arg1), "ptrauth"(i64 3, i64 56789, i64 0) ] ret i64 %tmp1 } @@ -248,57 +244,7 @@ define i64 @test_resign_blend_and_addr(i64 %arg, i64 %arg1, i64 %arg2) { ; TRAP-NEXT: pacdb x16, x2 ; TRAP-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp0 = call i64 @llvm.ptrauth.blend(i64 %arg1, i64 12345) - %tmp1 = call i64 @llvm.ptrauth.resign(i64 %arg, i32 2, i64 %tmp0, i32 3, i64 %arg2) + %tmp1 = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 2, i64 12345, i64 %arg1), "ptrauth"(i64 3, i64 0, i64 %arg2) ] ret i64 %tmp1 } -define i64 @test_auth_too_large_discriminator(i64 %arg, i64 %arg1) { -; UNCHECKED-LABEL: test_auth_too_large_discriminator: -; UNCHECKED: %bb.0: -; UNCHECKED-NEXT: mov w8, #65536 -; UNCHECKED-DARWIN-NEXT: bfi x1, x8, #48, #16 -; UNCHECKED-DARWIN-NEXT: mov x16, x0 -; UNCHECKED-DARWIN-NEXT: autda x16, x1 -; UNCHECKED-DARWIN-NEXT: mov x0, x16 -; UNCHECKED-ELF-NEXT: bfi x1, x8, #48, #16 -; UNCHECKED-ELF-NEXT: autda x0, x1 -; UNCHECKED-NEXT: ret -; -; CHECKED-LABEL: test_auth_too_large_discriminator: -; CHECKED: %bb.0: -; CHECKED-NEXT: mov w8, #65536 -; CHECKED-DARWIN-NEXT: bfi x1, x8, #48, #16 -; CHECKED-DARWIN-NEXT: mov x16, x0 -; CHECKED-DARWIN-NEXT: autda x16, x1 -; CHECKED-DARWIN-NEXT: mov x0, x16 -; CHECKED-ELF-NEXT: bfi x1, x8, #48, #16 -; CHECKED-ELF-NEXT: autda x0, x1 -; CHECKED-NEXT: ret -; -; TRAP-LABEL: test_auth_too_large_discriminator: -; TRAP: %bb.0: -; TRAP-NEXT: mov w8, #65536 -; TRAP-NEXT: bfi x1, x8, #48, #16 -; TRAP-DARWIN-NEXT: mov x16, x0 -; TRAP-DARWIN-NEXT: autda x16, x1 -; TRAP-DARWIN-NEXT: mov x17, x16 -; TRAP-DARWIN-NEXT: xpacd x17 -; TRAP-DARWIN-NEXT: cmp x16, x17 -; TRAP-ELF-NEXT: autda x0, x1 -; TRAP-ELF-NEXT: mov x8, x0 -; TRAP-ELF-NEXT: xpacd x8 -; TRAP-ELF-NEXT: cmp x0, x8 -; TRAP-NEXT: b.eq [[L]]auth_success_4 -; TRAP-NEXT: brk #0xc472 -; TRAP-NEXT: Lauth_success_4: -; TRAP-DARWIN-NEXT: mov x0, x16 -; TRAP-NEXT: ret - %tmp0 = call i64 @llvm.ptrauth.blend(i64 %arg1, i64 65536) - %tmp1 = call i64 @llvm.ptrauth.auth(i64 %arg, i32 2, i64 %tmp0) - ret i64 %tmp1 -} - -declare i64 @llvm.ptrauth.auth(i64, i32, i64) -declare i64 @llvm.ptrauth.resign(i64, i32, i64, i32, i64) -declare i64 @llvm.ptrauth.blend(i64, i64) diff --git a/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-auth-resign.ll b/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-auth-resign.ll index 52b38a5632005..9523250540a96 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-auth-resign.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-auth-resign.ll @@ -64,7 +64,7 @@ define i64 @test_auth_ia(i64 %arg, i64 %arg1) { ; TRAP-NEXT: Lauth_success_0: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 0, i64 %arg1) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 0, i64 0, i64 %arg1) ] ret i64 %tmp } @@ -101,7 +101,7 @@ define i64 @test_auth_ia_zero(i64 %arg) { ; TRAP-NEXT: Lauth_success_1: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 0, i64 0) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 0, i64 0, i64 0) ] ret i64 %tmp } @@ -138,7 +138,7 @@ define i64 @test_auth_ib(i64 %arg, i64 %arg1) { ; TRAP-NEXT: Lauth_success_2: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 1, i64 %arg1) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 1, i64 0, i64 %arg1) ] ret i64 %tmp } @@ -175,7 +175,7 @@ define i64 @test_auth_ib_zero(i64 %arg) { ; TRAP-NEXT: Lauth_success_3: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 1, i64 0) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 1, i64 0, i64 0) ] ret i64 %tmp } @@ -212,7 +212,7 @@ define i64 @test_auth_da(i64 %arg, i64 %arg1) { ; TRAP-NEXT: Lauth_success_4: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 2, i64 %arg1) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 2, i64 0, i64 %arg1) ] ret i64 %tmp } @@ -249,7 +249,7 @@ define i64 @test_auth_da_zero(i64 %arg) { ; TRAP-NEXT: Lauth_success_5: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 2, i64 0) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 2, i64 0, i64 0) ] ret i64 %tmp } @@ -286,7 +286,7 @@ define i64 @test_auth_db(i64 %arg, i64 %arg1) { ; TRAP-NEXT: Lauth_success_6: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 3, i64 %arg1) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 3, i64 0, i64 %arg1) ] ret i64 %tmp } @@ -323,7 +323,7 @@ define i64 @test_auth_db_zero(i64 %arg) { ; TRAP-NEXT: Lauth_success_7: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 3, i64 0) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 3, i64 0, i64 0) ] ret i64 %tmp } @@ -367,7 +367,7 @@ define i64 @test_resign_ia_ia(i64 %arg, i64 %arg1, i64 %arg2) { ; TRAP-NEXT: pacia x16, x2 ; TRAP-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 0, i64 %arg1, i32 0, i64 %arg2) + %tmp = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 0, i64 0, i64 %arg1), "ptrauth"(i64 0, i64 0, i64 %arg2) ] ret i64 %tmp } @@ -409,7 +409,7 @@ define i64 @test_resign_ib_ia(i64 %arg, i64 %arg1, i64 %arg2) { ; TRAP-NEXT: pacia x16, x2 ; TRAP-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 1, i64 %arg1, i32 0, i64 %arg2) + %tmp = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 1, i64 0, i64 %arg1), "ptrauth"(i64 0, i64 0, i64 %arg2) ] ret i64 %tmp } @@ -451,7 +451,7 @@ define i64 @test_resign_da_ia(i64 %arg, i64 %arg1, i64 %arg2) { ; TRAP-NEXT: pacia x16, x2 ; TRAP-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 2, i64 %arg1, i32 0, i64 %arg2) + %tmp = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 2, i64 0, i64 %arg1), "ptrauth"(i64 0, i64 0, i64 %arg2) ] ret i64 %tmp } @@ -493,7 +493,7 @@ define i64 @test_resign_db_da(i64 %arg, i64 %arg1, i64 %arg2) { ; TRAP-NEXT: pacda x16, x2 ; TRAP-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 3, i64 %arg1, i32 2, i64 %arg2) + %tmp = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 3, i64 0, i64 %arg1), "ptrauth"(i64 2, i64 0, i64 %arg2) ] ret i64 %tmp } @@ -535,7 +535,7 @@ define i64 @test_resign_iza_db(i64 %arg, i64 %arg1, i64 %arg2) { ; TRAP-NEXT: pacdb x16, x2 ; TRAP-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 0, i64 0, i32 3, i64 %arg2) + %tmp = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 3, i64 0, i64 %arg2) ] ret i64 %tmp } @@ -577,7 +577,7 @@ define i64 @test_resign_da_dzb(i64 %arg, i64 %arg1, i64 %arg2) { ; TRAP-NEXT: pacdzb x16 ; TRAP-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 2, i64 %arg1, i32 3, i64 0) + %tmp = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 2, i64 0, i64 %arg1), "ptrauth"(i64 3, i64 0, i64 0) ] ret i64 %tmp } @@ -623,7 +623,7 @@ define i64 @test_auth_trap_attribute(i64 %arg, i64 %arg1) "ptrauth-auth-traps" { ; TRAP-NEXT: Lauth_success_14: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 0, i64 %arg1) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 0, i64 0, i64 %arg1) ] ret i64 %tmp } @@ -666,7 +666,7 @@ define i64 @test_auth_ia_constdisc(i64 %arg) { ; TRAP-NEXT: Lauth_success_15: ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg, i32 0, i64 256) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg) [ "ptrauth"(i64 0, i64 256, i64 0) ] ret i64 %tmp } @@ -711,7 +711,7 @@ define i64 @test_resign_da_constdisc(i64 %arg, i64 %arg1) { ; TRAP-NEXT: pacda x16, x17 ; TRAP-NEXT: mov x0, x16 ; TRAP-NEXT: ret - %tmp = call i64 @llvm.ptrauth.resign(i64 %arg, i32 2, i64 %arg1, i32 2, i64 256) + %tmp = call i64 @llvm.ptrauth.resign(i64 %arg) [ "ptrauth"(i64 2, i64 0, i64 %arg1), "ptrauth"(i64 2, i64 256, i64 0) ] ret i64 %tmp } @@ -751,7 +751,7 @@ define i64 @test_auth_ia_swapped(i64 %arg, i64 %arg1) { ; TRAP-DARWIN-NEXT: mov x0, x16 ; TRAP-ELF-NEXT: mov x0, x1 ; TRAP-NEXT: ret - %tmp = call i64 @llvm.ptrauth.auth(i64 %arg1, i32 0, i64 %arg) + %tmp = call i64 @llvm.ptrauth.auth(i64 %arg1) [ "ptrauth"(i64 0, i64 0, i64 %arg) ] ret i64 %tmp } @@ -858,11 +858,11 @@ entry: br i1 %cond, label %if.then, label %if.else if.then: - %auted.then = tail call i64 @llvm.ptrauth.auth(i64 %signed, i32 2, i64 0) + %auted.then = tail call i64 @llvm.ptrauth.auth(i64 %signed) [ "ptrauth"(i64 2, i64 0, i64 0) ] br label %return if.else: - %auted.else = tail call i64 @llvm.ptrauth.auth(i64 %signed, i32 3, i64 0) + %auted.else = tail call i64 @llvm.ptrauth.auth(i64 %signed) [ "ptrauth"(i64 3, i64 0, i64 0) ] br label %return return: @@ -877,6 +877,3 @@ return: %ptr.4 = load ptr, ptr %ptr.3 ret ptr %ptr.4 } - -declare i64 @llvm.ptrauth.auth(i64, i32, i64) -declare i64 @llvm.ptrauth.resign(i64, i32, i64, i32, i64) diff --git a/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-blend.ll b/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-blend.ll deleted file mode 100644 index 2dc8a4cdb06dd..0000000000000 --- a/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-blend.ll +++ /dev/null @@ -1,48 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc < %s -mtriple arm64e-apple-darwin -verify-machineinstrs -global-isel=0 | FileCheck %s -; RUN: llc < %s -mtriple arm64e-apple-darwin -verify-machineinstrs -global-isel=1 -global-isel-abort=1 | FileCheck %s -; RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -verify-machineinstrs -global-isel=0 | FileCheck %s -; RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -verify-machineinstrs -global-isel=1 -global-isel-abort=1 | FileCheck %s - -define i64 @test_blend(i64 %arg, i64 %arg1) { -; CHECK-LABEL: test_blend: -; CHECK: %bb.0: -; CHECK-NEXT: bfi x0, x1, #48, #16 -; CHECK-NEXT: ret - %tmp = call i64 @llvm.ptrauth.blend(i64 %arg, i64 %arg1) - ret i64 %tmp -} - -define i64 @test_blend_constant(i64 %arg) { -; CHECK-LABEL: test_blend_constant: -; CHECK: %bb.0: -; CHECK-NEXT: movk x0, #12345, lsl #48 -; CHECK-NEXT: ret - %tmp = call i64 @llvm.ptrauth.blend(i64 %arg, i64 12345) - ret i64 %tmp -} - -; Blend isn't commutative. -define i64 @test_blend_constant_swapped(i64 %arg) { -; CHECK-LABEL: test_blend_constant_swapped: -; CHECK: %bb.0: -; CHECK-NEXT: mov w8, #12345 -; CHECK-NEXT: bfi x8, x0, #48, #16 -; CHECK-NEXT: mov x0, x8 -; CHECK-NEXT: ret - %tmp = call i64 @llvm.ptrauth.blend(i64 12345, i64 %arg) - ret i64 %tmp -} - -; Blends of constants wider than 16 bits truncate the constant. -define i64 @test_blend_constant_wide(i64 %arg) { -; CHECK-LABEL: test_blend_constant_wide: -; CHECK: %bb.0: -; CHECK-NEXT: mov w8, #65536 -; CHECK-NEXT: bfi x0, x8, #48, #16 -; CHECK-NEXT: ret - %tmp = call i64 @llvm.ptrauth.blend(i64 %arg, i64 65536) - ret i64 %tmp -} - -declare i64 @llvm.ptrauth.blend(i64, i64) diff --git a/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-sign.ll b/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-sign.ll index 01fdc05a5aa09..6d3c3dd1ace94 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-sign.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-sign.ll @@ -9,7 +9,7 @@ define i64 @test_sign_ia(i64 %arg, i64 %arg1) { ; CHECK: %bb.0: ; CHECK-NEXT: pacia x0, x1 ; CHECK-NEXT: ret - %tmp = call i64 @llvm.ptrauth.sign(i64 %arg, i32 0, i64 %arg1) + %tmp = call i64 @llvm.ptrauth.sign(i64 %arg) [ "ptrauth"(i64 0, i64 0, i64 %arg1) ] ret i64 %tmp } @@ -18,7 +18,7 @@ define i64 @test_sign_ia_zero(i64 %arg) { ; CHECK: %bb.0: ; CHECK-NEXT: paciza x0 ; CHECK-NEXT: ret - %tmp = call i64 @llvm.ptrauth.sign(i64 %arg, i32 0, i64 0) + %tmp = call i64 @llvm.ptrauth.sign(i64 %arg) [ "ptrauth"(i64 0, i64 0, i64 0) ] ret i64 %tmp } @@ -27,7 +27,7 @@ define i64 @test_sign_ib(i64 %arg, i64 %arg1) { ; CHECK: %bb.0: ; CHECK-NEXT: pacib x0, x1 ; CHECK-NEXT: ret - %tmp = call i64 @llvm.ptrauth.sign(i64 %arg, i32 1, i64 %arg1) + %tmp = call i64 @llvm.ptrauth.sign(i64 %arg) [ "ptrauth"(i64 1, i64 0, i64 %arg1) ] ret i64 %tmp } @@ -36,7 +36,7 @@ define i64 @test_sign_ib_zero(i64 %arg) { ; CHECK: %bb.0: ; CHECK-NEXT: pacizb x0 ; CHECK-NEXT: ret - %tmp = call i64 @llvm.ptrauth.sign(i64 %arg, i32 1, i64 0) + %tmp = call i64 @llvm.ptrauth.sign(i64 %arg) [ "ptrauth"(i64 1, i64 0, i64 0) ] ret i64 %tmp } @@ -45,7 +45,7 @@ define i64 @test_sign_da(i64 %arg, i64 %arg1) { ; CHECK: %bb.0: ; CHECK-NEXT: pacda x0, x1 ; CHECK-NEXT: ret - %tmp = call i64 @llvm.ptrauth.sign(i64 %arg, i32 2, i64 %arg1) + %tmp = call i64 @llvm.ptrauth.sign(i64 %arg) [ "ptrauth"(i64 2, i64 0, i64 %arg1) ] ret i64 %tmp } @@ -54,7 +54,7 @@ define i64 @test_sign_da_zero(i64 %arg) { ; CHECK: %bb.0: ; CHECK-NEXT: pacdza x0 ; CHECK-NEXT: ret - %tmp = call i64 @llvm.ptrauth.sign(i64 %arg, i32 2, i64 0) + %tmp = call i64 @llvm.ptrauth.sign(i64 %arg) [ "ptrauth"(i64 2, i64 0, i64 0) ] ret i64 %tmp } @@ -63,7 +63,7 @@ define i64 @test_sign_db(i64 %arg, i64 %arg1) { ; CHECK: %bb.0: ; CHECK-NEXT: pacdb x0, x1 ; CHECK-NEXT: ret - %tmp = call i64 @llvm.ptrauth.sign(i64 %arg, i32 3, i64 %arg1) + %tmp = call i64 @llvm.ptrauth.sign(i64 %arg) [ "ptrauth"(i64 3, i64 0, i64 %arg1) ] ret i64 %tmp } @@ -72,8 +72,6 @@ define i64 @test_sign_db_zero(i64 %arg) { ; CHECK: %bb.0: ; CHECK-NEXT: pacdzb x0 ; CHECK-NEXT: ret - %tmp = call i64 @llvm.ptrauth.sign(i64 %arg, i32 3, i64 0) + %tmp = call i64 @llvm.ptrauth.sign(i64 %arg) [ "ptrauth"(i64 3, i64 0, i64 0) ] ret i64 %tmp } - -declare i64 @llvm.ptrauth.sign(i64, i32, i64) diff --git a/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-strip.ll b/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-strip.ll index 1aeff7aec2ee4..81e5416f2fa9b 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-strip.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-strip.ll @@ -9,7 +9,7 @@ define i64 @test_strip_ia(i64 %arg) { ; CHECK: %bb.0: ; CHECK-NEXT: xpaci x0 ; CHECK-NEXT: ret - %tmp = call i64 @llvm.ptrauth.strip(i64 %arg, i32 0) + %tmp = call i64 @llvm.ptrauth.strip(i64 %arg) [ "ptrauth"(i64 0) ] ret i64 %tmp } @@ -18,7 +18,7 @@ define i64 @test_strip_ib(i64 %arg) { ; CHECK: %bb.0: ; CHECK-NEXT: xpaci x0 ; CHECK-NEXT: ret - %tmp = call i64 @llvm.ptrauth.strip(i64 %arg, i32 1) + %tmp = call i64 @llvm.ptrauth.strip(i64 %arg) [ "ptrauth"(i64 1) ] ret i64 %tmp } @@ -27,7 +27,7 @@ define i64 @test_strip_da(i64 %arg) { ; CHECK: %bb.0: ; CHECK-NEXT: xpacd x0 ; CHECK-NEXT: ret - %tmp = call i64 @llvm.ptrauth.strip(i64 %arg, i32 2) + %tmp = call i64 @llvm.ptrauth.strip(i64 %arg) [ "ptrauth"(i64 2) ] ret i64 %tmp } @@ -36,8 +36,6 @@ define i64 @test_strip_db(i64 %arg) { ; CHECK: %bb.0: ; CHECK-NEXT: xpacd x0 ; CHECK-NEXT: ret - %tmp = call i64 @llvm.ptrauth.strip(i64 %arg, i32 3) + %tmp = call i64 @llvm.ptrauth.strip(i64 %arg) [ "ptrauth"(i64 3) ] ret i64 %tmp } - -declare i64 @llvm.ptrauth.strip(i64, i32) diff --git a/llvm/test/CodeGen/AArch64/ptrauth-intrinsics-upgrade.ll b/llvm/test/CodeGen/AArch64/ptrauth-intrinsics-upgrade.ll new file mode 100644 index 0000000000000..b46ca8a02bc1f --- /dev/null +++ b/llvm/test/CodeGen/AArch64/ptrauth-intrinsics-upgrade.ll @@ -0,0 +1,134 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -S | FileCheck %s +; RUN: llvm-as < %s | opt -S | FileCheck %s + +define void @test_ptrauth_sign(i64 %p, i64 %addr) { +; CHECK-LABEL: @test_ptrauth_sign( +; CHECK-NEXT: [[ZERO_DISCR:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[P:%.*]]) [ "ptrauth"(i64 1, i64 0, i64 0) ] +; CHECK-NEXT: [[IMM_DISCR:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[P]]) [ "ptrauth"(i64 1, i64 42, i64 0) ] +; CHECK-NEXT: [[ADDR_DISCR:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[P]]) [ "ptrauth"(i64 1, i64 0, i64 [[ADDR:%.*]]) ] +; CHECK-NEXT: [[BLENDED_DISCR:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[P]]) [ "ptrauth"(i64 1, i64 1234, i64 [[ADDR]]) ] +; CHECK-NEXT: ret void +; + %tmp = call i64 @llvm.ptrauth.blend(i64 %addr, i64 1234) + %zero.discr = call i64 @llvm.ptrauth.sign(i64 %p, i32 1, i64 0) + %imm.discr = call i64 @llvm.ptrauth.sign(i64 %p, i32 1, i64 42) + %addr.discr = call i64 @llvm.ptrauth.sign(i64 %p, i32 1, i64 %addr) + %blended.discr = call i64 @llvm.ptrauth.sign(i64 %p, i32 1, i64 %tmp) + ret void +} + +define void @test_ptrauth_auth(i64 %p, i64 %addr) { +; CHECK-LABEL: @test_ptrauth_auth( +; CHECK-NEXT: [[ZERO_DISCR:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[P:%.*]]) [ "ptrauth"(i64 1, i64 0, i64 0) ] +; CHECK-NEXT: [[IMM_DISCR:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[P]]) [ "ptrauth"(i64 1, i64 42, i64 0) ] +; CHECK-NEXT: [[ADDR_DISCR:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[P]]) [ "ptrauth"(i64 1, i64 0, i64 [[ADDR:%.*]]) ] +; CHECK-NEXT: [[BLENDED_DISCR:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[P]]) [ "ptrauth"(i64 1, i64 1234, i64 [[ADDR]]) ] +; CHECK-NEXT: ret void +; + %tmp = call i64 @llvm.ptrauth.blend(i64 %addr, i64 1234) + %zero.discr = call i64 @llvm.ptrauth.auth(i64 %p, i32 1, i64 0) + %imm.discr = call i64 @llvm.ptrauth.auth(i64 %p, i32 1, i64 42) + %addr.discr = call i64 @llvm.ptrauth.auth(i64 %p, i32 1, i64 %addr) + %blended.discr = call i64 @llvm.ptrauth.auth(i64 %p, i32 1, i64 %tmp) + ret void +} + +define void @test_ptrauth_resign(i64 %p, i64 %addr) { +; CHECK-LABEL: @test_ptrauth_resign( +; CHECK-NEXT: [[IMM_IMM_DISCR:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[P:%.*]]) [ "ptrauth"(i64 1, i64 42, i64 0), "ptrauth"(i64 2, i64 123, i64 0) ] +; CHECK-NEXT: [[ZERO_IMM_DISCR:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[P]]) [ "ptrauth"(i64 1, i64 0, i64 0), "ptrauth"(i64 2, i64 123, i64 0) ] +; CHECK-NEXT: [[ADDR_IMM_DISCR:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[P]]) [ "ptrauth"(i64 1, i64 0, i64 [[ADDR:%.*]]), "ptrauth"(i64 2, i64 123, i64 0) ] +; CHECK-NEXT: [[BLENDED_IMM_DISCR:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[P]]) [ "ptrauth"(i64 1, i64 1234, i64 [[ADDR]]), "ptrauth"(i64 2, i64 123, i64 0) ] +; CHECK-NEXT: [[IMM_ZERO_DISCR:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[P]]) [ "ptrauth"(i64 1, i64 123, i64 0), "ptrauth"(i64 2, i64 0, i64 0) ] +; CHECK-NEXT: [[IMM_ADDR_DISCR:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[P]]) [ "ptrauth"(i64 1, i64 123, i64 0), "ptrauth"(i64 2, i64 0, i64 [[ADDR]]) ] +; CHECK-NEXT: [[IMM_BLENDED_DISCR:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[P]]) [ "ptrauth"(i64 1, i64 123, i64 0), "ptrauth"(i64 2, i64 5678, i64 [[ADDR]]) ] +; CHECK-NEXT: [[ZERO_BLENDED_DISCR:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[P]]) [ "ptrauth"(i64 1, i64 0, i64 0), "ptrauth"(i64 2, i64 4321, i64 [[ADDR]]) ] +; CHECK-NEXT: [[ADDR_BLENDED_DISCR:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[P]]) [ "ptrauth"(i64 1, i64 0, i64 [[ADDR]]), "ptrauth"(i64 2, i64 4321, i64 [[ADDR]]) ] +; CHECK-NEXT: [[BLENDED_ZERO_DISCR:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[P]]) [ "ptrauth"(i64 1, i64 8765, i64 [[ADDR]]), "ptrauth"(i64 2, i64 0, i64 0) ] +; CHECK-NEXT: [[BLENDED_ADDR_DISCR:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[P]]) [ "ptrauth"(i64 1, i64 8765, i64 [[ADDR]]), "ptrauth"(i64 2, i64 0, i64 [[ADDR]]) ] +; CHECK-NEXT: [[BLENDED_BLENDED_DISCR:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[P]]) [ "ptrauth"(i64 1, i64 111, i64 [[ADDR]]), "ptrauth"(i64 2, i64 222, i64 [[ADDR]]) ] +; CHECK-NEXT: ret void +; + %imm.imm.discr = call i64 @llvm.ptrauth.resign(i64 %p, i32 1, i64 42, i32 2, i64 123) + + %tmp1 = call i64 @llvm.ptrauth.blend(i64 %addr, i64 1234) + %zero.imm.discr = call i64 @llvm.ptrauth.resign(i64 %p, i32 1, i64 0, i32 2, i64 123) + %addr.imm.discr = call i64 @llvm.ptrauth.resign(i64 %p, i32 1, i64 %addr, i32 2, i64 123) + %blended.imm.discr = call i64 @llvm.ptrauth.resign(i64 %p, i32 1, i64 %tmp1, i32 2, i64 123) + + %tmp2 = call i64 @llvm.ptrauth.blend(i64 %addr, i64 5678) + %imm.zero.discr = call i64 @llvm.ptrauth.resign(i64 %p, i32 1, i64 123, i32 2, i64 0 ) + %imm.addr.discr = call i64 @llvm.ptrauth.resign(i64 %p, i32 1, i64 123, i32 2, i64 %addr) + %imm.blended.discr = call i64 @llvm.ptrauth.resign(i64 %p, i32 1, i64 123, i32 2, i64 %tmp2) + + %tmp3 = call i64 @llvm.ptrauth.blend(i64 %addr, i64 4321) + %zero.blended.discr = call i64 @llvm.ptrauth.resign(i64 %p, i32 1, i64 0, i32 2, i64 %tmp3) + %addr.blended.discr = call i64 @llvm.ptrauth.resign(i64 %p, i32 1, i64 %addr, i32 2, i64 %tmp3) + + %tmp4 = call i64 @llvm.ptrauth.blend(i64 %addr, i64 8765) + %blended.zero.discr = call i64 @llvm.ptrauth.resign(i64 %p, i32 1, i64 %tmp4, i32 2, i64 0 ) + %blended.addr.discr = call i64 @llvm.ptrauth.resign(i64 %p, i32 1, i64 %tmp4, i32 2, i64 %addr) + + %tmp5 = call i64 @llvm.ptrauth.blend(i64 %addr, i64 111) + %tmp6 = call i64 @llvm.ptrauth.blend(i64 %addr, i64 222) + %blended.blended.discr = call i64 @llvm.ptrauth.resign(i64 %p, i32 1, i64 %tmp5, i32 2, i64 %tmp6) + + ret void +} + +define void @test_ptrauth_strip(i64 %p) { +; CHECK-LABEL: @test_ptrauth_strip( +; CHECK-NEXT: [[RES:%.*]] = call i64 @llvm.ptrauth.strip(i64 [[P:%.*]]) [ "ptrauth"(i64 1) ] +; CHECK-NEXT: ret void +; + %res = call i64 @llvm.ptrauth.strip(i64 %p, i32 1) + ret void +} + +define void @test_ptrauth_reused_blend(i64 %p1, i64 %p2, i64 %addr) { +; CHECK-LABEL: @test_ptrauth_reused_blend( +; CHECK-NEXT: [[RES1:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[P1:%.*]]) [ "ptrauth"(i64 1, i64 1234, i64 [[ADDR:%.*]]) ] +; CHECK-NEXT: [[RES2:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[P2:%.*]]) [ "ptrauth"(i64 2, i64 1234, i64 [[ADDR]]) ] +; CHECK-NEXT: ret void +; + %tmp = call i64 @llvm.ptrauth.blend(i64 %addr, i64 1234) + %res1 = call i64 @llvm.ptrauth.auth(i64 %p1, i32 1, i64 %tmp) + %res2 = call i64 @llvm.ptrauth.auth(i64 %p2, i32 2, i64 %tmp) + ret void +} + +define void @test_ptrauth_reused_blend_same_inst(i64 %p, i64 %addr) { +; CHECK-LABEL: @test_ptrauth_reused_blend_same_inst( +; CHECK-NEXT: [[RES:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[P:%.*]]) [ "ptrauth"(i64 1, i64 1234, i64 [[ADDR:%.*]]), "ptrauth"(i64 2, i64 1234, i64 [[ADDR]]) ] +; CHECK-NEXT: ret void +; + %tmp = call i64 @llvm.ptrauth.blend(i64 %addr, i64 1234) + %res = call i64 @llvm.ptrauth.resign(i64 %p, i32 1, i64 %tmp, i32 2, i64 %tmp) + ret void +} + +define void @test_ptrauth_blend_in_other_bb(i64 %p, i64 %addr) { +; CHECK-LABEL: @test_ptrauth_blend_in_other_bb( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: [[RES:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[P:%.*]]) [ "ptrauth"(i64 1, i64 1234, i64 [[ADDR:%.*]]), "ptrauth"(i64 2, i64 1234, i64 [[ADDR]]) ] +; CHECK-NEXT: ret void +; +entry: + %tmp = call i64 @llvm.ptrauth.blend(i64 %addr, i64 1234) + br label %exit + +exit: + %res = call i64 @llvm.ptrauth.resign(i64 %p, i32 1, i64 %tmp, i32 2, i64 %tmp) + ret void +} + +define i64 @test_unused_blend(i64 %addr) { +; CHECK-LABEL: @test_unused_blend( +; CHECK-NEXT: ret i64 [[ADDR:%.*]] +; + %tmp = call i64 @llvm.ptrauth.blend(i64 %addr, i64 1234) + ret i64 %addr +} diff --git a/llvm/test/CodeGen/AArch64/ptrauth-invalid-upgrade.ll b/llvm/test/CodeGen/AArch64/ptrauth-invalid-upgrade.ll new file mode 100644 index 0000000000000..b9d523a659799 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/ptrauth-invalid-upgrade.ll @@ -0,0 +1,154 @@ +; RUN: split-file %s %t + +;--- store.ll +; RUN: not opt -passes=verify -S < %t/store.ll 2>&1 | FileCheck --check-prefix=STORE %s + +; STORE: Cannot upgrade all uses of @llvm.ptrauth.blend in function: +; STORE-NEXT: define void @test(ptr %p, i64 %addr) { +; STORE-NEXT: %disc = call i64 @llvm.ptrauth.blend(i64 %addr, i64 42) +; STORE-NEXT: store i64 %disc, ptr %p, align 4 +; STORE-NEXT: ret void +; STORE-NEXT: } +; STORE-NEXT: LLVM ERROR: Cannot upgrade some uses of @llvm.ptrauth.blend(). + +define void @test(ptr %p, i64 %addr) { + %disc = call i64 @llvm.ptrauth.blend(i64 %addr, i64 42) + store i64 %disc, ptr %p + ret void +} + +;--- arith.ll +; RUN: not opt -passes=verify -S < %t/arith.ll 2>&1 | FileCheck --check-prefix=ARITH %s + +; ARITH: Cannot upgrade all uses of @llvm.ptrauth.blend in function: +; ARITH-NEXT: define void @test(ptr %p, i64 %addr) { +; ARITH-NEXT: %disc = call i64 @llvm.ptrauth.blend(i64 %addr, i64 42) +; ARITH-NEXT: %tmp = add i64 %disc, 42 +; ARITH-NEXT: ret void +; ARITH-NEXT: } +; ARITH-NEXT: LLVM ERROR: Cannot upgrade some uses of @llvm.ptrauth.blend(). + +define void @test(ptr %p, i64 %addr) { + %disc = call i64 @llvm.ptrauth.blend(i64 %addr, i64 42) + %tmp = add i64 %disc, 42 + ret void +} + +;--- indirect-one-arg.ll +; RUN: not opt -passes=verify -S < %t/indirect-one-arg.ll 2>&1 | FileCheck --check-prefix=INDIRECT-ONE-ARG %s + +; INDIRECT-ONE-ARG: Cannot upgrade all uses of @llvm.ptrauth.blend in function: +; INDIRECT-ONE-ARG-NEXT: define void @test(ptr %some_fn, i64 %addr) { +; INDIRECT-ONE-ARG-NEXT: %disc = call i64 @llvm.ptrauth.blend(i64 %addr, i64 42) +; INDIRECT-ONE-ARG-NEXT: call void %some_fn(i64 %disc) +; INDIRECT-ONE-ARG-NEXT: ret void +; INDIRECT-ONE-ARG-NEXT: } +; INDIRECT-ONE-ARG-NEXT: LLVM ERROR: Cannot upgrade some uses of @llvm.ptrauth.blend(). + +define void @test(ptr %some_fn, i64 %addr) { + %disc = call i64 @llvm.ptrauth.blend(i64 %addr, i64 42) + call void %some_fn(i64 %disc) + ret void +} + +;--- direct-one-arg.ll +; RUN: not opt -passes=verify -S < %t/direct-one-arg.ll 2>&1 | FileCheck --check-prefix=DIRECT-ONE-ARG %s + +; DIRECT-ONE-ARG: Cannot upgrade all uses of @llvm.ptrauth.blend in function: +; DIRECT-ONE-ARG-NEXT: define void @test(i64 %addr) { +; DIRECT-ONE-ARG-NEXT: %disc = call i64 @llvm.ptrauth.blend(i64 %addr, i64 42) +; DIRECT-ONE-ARG-NEXT: call void @some_fn(i64 %disc) +; DIRECT-ONE-ARG-NEXT: ret void +; DIRECT-ONE-ARG-NEXT: } +; DIRECT-ONE-ARG-NEXT: LLVM ERROR: Cannot upgrade some uses of @llvm.ptrauth.blend(). + +declare void @some_fn(i64 %0) + +define void @test(i64 %addr) { + %disc = call i64 @llvm.ptrauth.blend(i64 %addr, i64 42) + call void @some_fn(i64 %disc) + ret void +} + +; During the upgrade, it is not always possible to directly check whether +; a call site is an intrinsic call and if it is, which intrinsic is called. +; Though, these errors can be caught indirectly. +; In the below test cases, auth_like_fn has the same arguments as the old +; version of @llvm.ptrauth.auth intrinsic. + +;--- indirect-three-args.ll +; RUN: not opt -passes=verify -S < %t/indirect-three-args.ll 2>&1 | FileCheck --check-prefix=INDIRECT-THREE-ARGS %s + +; Invalid call to %auth_like_fn is detected, because intrinsics are never +; called indirectly. + +; INDIRECT-THREE-ARGS: Cannot upgrade all uses of @llvm.ptrauth.blend in function: +; INDIRECT-THREE-ARGS-NEXT: define void @test(i64 %p, ptr %auth_like_fn, i64 %addr) { +; INDIRECT-THREE-ARGS-NEXT: %disc = call i64 @llvm.ptrauth.blend(i64 %addr, i64 42) +; INDIRECT-THREE-ARGS-NEXT: call void %auth_like_fn(i64 %p, i32 1, i64 %disc) +; INDIRECT-THREE-ARGS-NEXT: ret void +; INDIRECT-THREE-ARGS-NEXT: } +; INDIRECT-THREE-ARGS-NEXT: LLVM ERROR: Cannot upgrade some uses of @llvm.ptrauth.blend(). + +define void @test(i64 %p, ptr %auth_like_fn, i64 %addr) { + %disc = call i64 @llvm.ptrauth.blend(i64 %addr, i64 42) + call void %auth_like_fn(i64 %p, i32 1, i64 %disc) + ret void +} + +;--- direct-three-args.ll +; RUN: not opt -passes=verify -S < %t/direct-three-args.ll 2>&1 | FileCheck --check-prefix=DIRECT-THREE-ARGS %s + +; Invalid call to @auth_like_fn is formally upgraded as if it were an intrinsic +; call, but is caught by the verifier later, as regular function calls with +; "ptrauth" operand bundles must be indirect. + +; DIRECT-THREE-ARGS: Direct call cannot have a ptrauth bundle +; DIRECT-THREE-ARGS-NEXT: call void @auth_like_fn(i64 %p, i32 0, i64 0) [ "ptrauth"(i64 1, i64 42, i64 %addr) ] +; DIRECT-THREE-ARGS-NEXT: error: input module is broken! + +declare void @auth_like_fn(i64 %0, i32 %1, i64 %2) + +define void @test(i64 %p, i64 %addr) { + %disc = call i64 @llvm.ptrauth.blend(i64 %addr, i64 42) + call void @auth_like_fn(i64 %p, i32 1, i64 %disc) + ret void +} + +;--- wrong-intrinsic-with-ptrauth-bundle.ll +; RUN: not opt -passes=verify -S < %t/wrong-intrinsic-with-ptrauth-bundle.ll 2>&1 | FileCheck --check-prefix=WRONG-INTRINSIC-WITH-PTRAUTH-BUNDLE %s + +; This test case does not involve auto-upgrading, but it shows the behavior of +; the IR verifier if any unrelated intrinsic would be formally auto-upgraded. + +; WRONG-INTRINSIC-WITH-PTRAUTH-BUNDLE: Unexpected ptrauth bundle +; WRONG-INTRINSIC-WITH-PTRAUTH-BUNDLE-NEXT: %1 = call i64 @llvm.ptrauth.sign.generic(i64 %p, i64 0) [ "ptrauth"(i64 1, i64 42, i64 %addr) ] +; WRONG-INTRINSIC-WITH-PTRAUTH-BUNDLE-NEXT: /data/ast/llvm-project/build/bin/opt: -: error: input module is broken! + +define void @test(i64 %p, ptr %auth_like_fn, i64 %addr) { + ; The below call uses the new-style all-i64 ptrauth bundle. + call i64 @llvm.ptrauth.sign.generic(i64 %p, i64 0) [ "ptrauth"(i64 1, i64 42, i64 %addr) ] + ret void +} + +;--- wrong-position-in-bundle.ll +; RUN: not opt -passes=verify -S < %t/wrong-position-in-bundle.ll 2>&1 | FileCheck --check-prefix=WRONG-POSITION-IN-BUNDLE %s + +; WRONG-POSITION-IN-BUNDLE: LLVM ERROR: Cannot upgrade: expected constant ptrauth key ID + +define void @test(i64 %p, i64 %addr) { + %disc = call i64 @llvm.ptrauth.blend(i64 %addr, i64 42) + call i64 @llvm.ptrauth.auth(i64 %p, i64 %disc, i64 1) + ret void +} + +;--- both-positions-in-bundle.ll +; RUN: not opt -passes=verify -S < %t/both-positions-in-bundle.ll 2>&1 | FileCheck --check-prefix=BOTH-POSITIONS-IN-BUNDLE %s + +; BOTH-POSITIONS-IN-BUNDLE: LLVM ERROR: Cannot upgrade: expected constant ptrauth key ID + +define void @test(i64 %p, i64 %addr) { + %disc = call i64 @llvm.ptrauth.blend(i64 %addr, i64 42) + call i64 @llvm.ptrauth.auth(i64 %p, i64 %disc, i64 %disc) + ret void +} diff --git a/llvm/test/CodeGen/AArch64/ptrauth-invoke.ll b/llvm/test/CodeGen/AArch64/ptrauth-invoke.ll index f6b3a88ca4677..53a9bd6d462cf 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-invoke.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-invoke.ll @@ -83,7 +83,7 @@ ; CHECK-NEXT: .byte 0 {{.*}} On action: cleanup define i32 @test_invoke_ia_0(ptr %arg0) #0 personality ptr @__gxx_personality_v0 { - %tmp0 = invoke i32 %arg0() [ "ptrauth"(i32 0, i64 0) ] to label %continuebb + %tmp0 = invoke i32 %arg0() [ "ptrauth"(i64 0, i64 0, i64 0) ] to label %continuebb unwind label %unwindbb unwindbb: @@ -233,7 +233,7 @@ continuebb: define void @test_invoke_ib_42_catch(ptr %fptr) #0 personality ptr @__gxx_personality_v0 { %tmp0 = call ptr @__cxa_allocate_exception(i64 8) store ptr getelementptr inbounds ([6 x i8], ptr @hello_str, i64 0, i64 0), ptr %tmp0, align 8 - invoke void %fptr(ptr %tmp0, ptr @_ZTIPKc, ptr null) [ "ptrauth"(i32 1, i64 42) ] + invoke void %fptr(ptr %tmp0, ptr @_ZTIPKc, ptr null) [ "ptrauth"(i64 1, i64 42, i64 0) ] to label %continuebb unwind label %catchbb catchbb: @@ -331,7 +331,7 @@ continuebb: ; CHECK-NEXT: .byte 0 {{.*}} On action: cleanup define i32 @test_invoke_ia_0_direct() #0 personality ptr @__gxx_personality_v0 { - %tmp0 = invoke i32 ptrauth (ptr @baz, i32 0)() [ "ptrauth"(i32 0, i64 0) ] to label %continuebb + %tmp0 = invoke i32 ptrauth (ptr @baz, [i64 0, i64 0, i64 0])() [ "ptrauth"(i64 0, i64 0, i64 0) ] to label %continuebb unwind label %unwindbb unwindbb: @@ -443,7 +443,7 @@ continuebb: ; CHECK-NEXT: .byte 0 {{.*}} On action: cleanup define i32 @test_invoke_ib_2_direct_mismatch() #0 personality ptr @__gxx_personality_v0 { - %tmp0 = invoke i32 ptrauth (ptr @baz, i32 0, i64 1234)() [ "ptrauth"(i32 1, i64 2) ] to label %continuebb + %tmp0 = invoke i32 ptrauth (ptr @baz, [i64 0, i64 1234, i64 0])() [ "ptrauth"(i64 1, i64 2, i64 0) ] to label %continuebb unwind label %unwindbb unwindbb: diff --git a/llvm/test/CodeGen/AArch64/ptrauth-irelative.ll b/llvm/test/CodeGen/AArch64/ptrauth-irelative.ll index 4ee1c19a86490..f093ca73c0245 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-irelative.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-irelative.ll @@ -9,7 +9,7 @@ ; CHECK-NEXT: b __emupac_pacda ; CHECK-NEXT: .section .rodata ; CHECK-NEXT: .xword [[FUNC]]@FUNCINIT -@nullref = constant ptr ptrauth (ptr null, i32 2, i64 1, ptr null), align 8 +@nullref = constant ptr ptrauth (ptr null, [i64 2, i64 1, i64 0]), align 8 @dsolocal = external dso_local global i8 @@ -23,7 +23,7 @@ ; CHECK-NEXT: b __emupac_pacda ; CHECK-NEXT: .section .rodata ; CHECK-NEXT: .xword [[FUNC]]@FUNCINIT -@dsolocalref = constant ptr ptrauth (ptr @dsolocal, i32 2, i64 2, ptr null), align 8 +@dsolocalref = constant ptr ptrauth (ptr @dsolocal, [i64 2, i64 2, i64 0]), align 8 @ds = external global i8 @@ -40,7 +40,7 @@ ; CHECK-NEXT: ret ; CHECK-NEXT: .section .rodata ; CHECK-NEXT: .xword [[FUNC]]@FUNCINIT -@dsolocalrefds = constant ptr ptrauth (ptr @dsolocal, i32 2, i64 2, ptr null, ptr @ds), align 8 +@dsolocalrefds = constant ptr ptrauth (ptr @dsolocal, [i64 2, i64 2, i64 0], ptr @ds), align 8 ; CHECK: dsolocalref8: ; CHECK-NEXT: [[PLACE:.*]]: @@ -52,7 +52,7 @@ ; CHECK-NEXT: b __emupac_pacda ; CHECK-NEXT: .section .rodata ; CHECK-NEXT: .xword [[FUNC]]@FUNCINIT -@dsolocalref8 = constant ptr ptrauth (ptr getelementptr (i8, ptr @dsolocal, i64 8), i32 2, i64 3, ptr null), align 8 +@dsolocalref8 = constant ptr ptrauth (ptr getelementptr (i8, ptr @dsolocal, i64 8), [i64 2, i64 3, i64 0]), align 8 ; CHECK: disc: ; CHECK-NEXT: [[PLACE:.*]]: @@ -65,7 +65,7 @@ ; CHECK-NEXT: b __emupac_pacda ; CHECK-NEXT: .section .rodata ; CHECK-NEXT: .xword [[FUNC]]@FUNCINIT -@disc = constant ptr ptrauth (ptr @dsolocal, i32 2, i64 0, ptr @disc), align 8 +@disc = constant ptr ptrauth (ptr @dsolocal, [i64 2, i64 0, i64 ptrtoint (ptr @disc to i64)]), align 8 @global = external global i8 @@ -79,7 +79,7 @@ ; CHECK-NEXT: b __emupac_pacda ; CHECK-NEXT: .section .rodata ; CHECK-NEXT: .xword [[FUNC]]@FUNCINIT -@globalref = constant ptr ptrauth (ptr @global, i32 2, i64 4, ptr null), align 8 +@globalref = constant ptr ptrauth (ptr @global, [i64 2, i64 4, i64 0]), align 8 ; CHECK: globalref8: ; CHECK-NEXT: [[PLACE:.*]]: @@ -92,4 +92,4 @@ ; CHECK-NEXT: b __emupac_pacda ; CHECK-NEXT: .section .rodata ; CHECK-NEXT: .xword [[FUNC]]@FUNCINIT -@globalref8 = constant ptr ptrauth (ptr getelementptr (i8, ptr @global, i64 8), i32 2, i64 5, ptr null), align 8 +@globalref8 = constant ptr ptrauth (ptr getelementptr (i8, ptr @global, i64 8), [i64 2, i64 5, i64 0]), align 8 diff --git a/llvm/test/CodeGen/AArch64/ptrauth-isel.ll b/llvm/test/CodeGen/AArch64/ptrauth-isel.ll index 7011b946aad74..560621979f7bd 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-isel.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-isel.ll @@ -1,269 +1,75 @@ -; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5 ; RUN: llc < %s -mtriple arm64e-apple-darwin -verify-machineinstrs -stop-after=finalize-isel -global-isel=0 \ -; RUN: | FileCheck %s --check-prefixes=DAGISEL +; RUN: | FileCheck %s --check-prefixes=CHECK,DARWIN --implicit-check-not=name: --implicit-check-not=MOVKXi ; RUN: llc < %s -mtriple arm64e-apple-darwin -verify-machineinstrs -stop-after=finalize-isel -global-isel=1 -global-isel-abort=1 \ -; RUN: | FileCheck %s --check-prefixes=GISEL +; RUN: | FileCheck %s --check-prefixes=CHECK,DARWIN --implicit-check-not=name: --implicit-check-not=MOVKXi ; RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -verify-machineinstrs -stop-after=finalize-isel -global-isel=0 \ -; RUN: | FileCheck %s --check-prefixes=DAGISEL +; RUN: | FileCheck %s --check-prefixes=CHECK,ELF --implicit-check-not=name: --implicit-check-not=MOVKXi ; RUN: llc < %s -mtriple aarch64-linux-gnu -mattr=+pauth -verify-machineinstrs -stop-after=finalize-isel -global-isel=1 -global-isel-abort=1 \ -; RUN: | FileCheck %s --check-prefixes=GISEL +; RUN: | FileCheck %s --check-prefixes=CHECK,ELF --implicit-check-not=name: --implicit-check-not=MOVKXi ; Check MIR produced by the instruction selector to validate properties that ; cannot be reliably tested by only inspecting the final asm output. @discvar = dso_local global i64 0 -; Make sure the components of blend(addr, imm) and integer constants are -; recognized and passed to PAC pseudo via separate operands to prevent -; substitution of the immediate modifier. +; Make sure zero address modifier is translated directly into a $noreg operand +; at the MIR level instead of a virtual register containing zero value. ; -; MIR output of the instruction selector is inspected, as it is hard to reliably -; distinguish MOVKXi immediately followed by a pseudo from a standalone pseudo -; instruction carrying address and immediate modifiers in its separate operands -; by only observing the final asm output. +; All relevant intrinsics are checked because some are selected by TableGen +; patterns and some other are selected by C++ code. -define i64 @small_imm_disc_optimized(i64 %addr) { - ; DAGISEL-LABEL: name: small_imm_disc_optimized - ; DAGISEL: bb.0.entry: - ; DAGISEL-NEXT: liveins: $x0 - ; DAGISEL-NEXT: {{ $}} - ; DAGISEL-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; DAGISEL-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 42 - ; DAGISEL-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64noip = SUBREG_TO_REG 0, killed [[MOVi32imm]], %subreg.sub_32 - ; DAGISEL-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY]], 2, 42, killed $noreg, implicit-def dead $x16, implicit-def dead $x17 - ; DAGISEL-NEXT: $x0 = COPY [[PAC]] - ; DAGISEL-NEXT: RET_ReallyLR implicit $x0 - ; - ; GISEL-LABEL: name: small_imm_disc_optimized - ; GISEL: bb.1.entry: - ; GISEL-NEXT: liveins: $x0 - ; GISEL-NEXT: {{ $}} - ; GISEL-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; GISEL-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 42 - ; GISEL-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64noip = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32 - ; GISEL-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY]], 2, 42, $noreg, implicit-def dead $x16, implicit-def dead $x17 - ; GISEL-NEXT: $x0 = COPY [[PAC]] - ; GISEL-NEXT: RET_ReallyLR implicit $x0 +define i64 @pac_no_addr_modif_optimized(i64 %addr) { + ; CHECK-LABEL: name: pac_no_addr_modif_optimized + ; CHECK: {{.*}} = PAC {{[^,]+}}, 2, 42, $noreg, implicit-def dead $x16, implicit-def dead $x17 + ; CHECK: RET_ReallyLR implicit $x0 entry: - %signed = call i64 @llvm.ptrauth.sign(i64 %addr, i32 2, i64 42) + %signed = call i64 @llvm.ptrauth.sign(i64 %addr) [ "ptrauth"(i64 2, i64 42, i64 0) ] ret i64 %signed } -; Without optimization, MOVi64imm may be used for small i64 constants as well. -define i64 @small_imm_disc_non_optimized(i64 %addr) noinline optnone { - ; DAGISEL-LABEL: name: small_imm_disc_non_optimized - ; DAGISEL: bb.0.entry: - ; DAGISEL-NEXT: liveins: $x0 - ; DAGISEL-NEXT: {{ $}} - ; DAGISEL-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; DAGISEL-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY killed [[COPY]] - ; DAGISEL-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 42 - ; DAGISEL-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64noip = SUBREG_TO_REG 0, killed [[MOVi32imm]], %subreg.sub_32 - ; DAGISEL-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY1]], 2, 42, killed $noreg, implicit-def dead $x16, implicit-def dead $x17 - ; DAGISEL-NEXT: [[COPY2:%[0-9]+]]:gpr64all = COPY [[PAC]] - ; DAGISEL-NEXT: $x0 = COPY [[COPY2]] - ; DAGISEL-NEXT: RET_ReallyLR implicit $x0 - ; - ; GISEL-LABEL: name: small_imm_disc_non_optimized - ; GISEL: bb.1.entry: - ; GISEL-NEXT: liveins: $x0 - ; GISEL-NEXT: {{ $}} - ; GISEL-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; GISEL-NEXT: [[MOVi64imm:%[0-9]+]]:gpr64noip = MOVi64imm 42 - ; GISEL-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY]], 2, 42, $noreg, implicit-def dead $x16, implicit-def dead $x17 - ; GISEL-NEXT: $x0 = COPY [[PAC]] - ; GISEL-NEXT: RET_ReallyLR implicit $x0 +define i64 @pac_no_addr_modif_not_optimized(i64 %addr) noinline optnone { + ; CHECK-LABEL: name: pac_no_addr_modif_not_optimized + ; CHECK: {{.*}} = PAC {{[^,]+}}, 2, 42, $noreg, implicit-def dead $x16, implicit-def dead $x17 + ; CHECK: RET_ReallyLR implicit $x0 entry: - %signed = call i64 @llvm.ptrauth.sign(i64 %addr, i32 2, i64 42) + %signed = call i64 @llvm.ptrauth.sign(i64 %addr) [ "ptrauth"(i64 2, i64 42, i64 0) ] ret i64 %signed } -define i64 @large_imm_disc_wreg(i64 %addr) { - ; DAGISEL-LABEL: name: large_imm_disc_wreg - ; DAGISEL: bb.0.entry: - ; DAGISEL-NEXT: liveins: $x0 - ; DAGISEL-NEXT: {{ $}} - ; DAGISEL-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; DAGISEL-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 12345678 - ; DAGISEL-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64noip = SUBREG_TO_REG 0, killed [[MOVi32imm]], %subreg.sub_32 - ; DAGISEL-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY]], 2, 0, killed [[SUBREG_TO_REG]], implicit-def dead $x16, implicit-def dead $x17 - ; DAGISEL-NEXT: $x0 = COPY [[PAC]] - ; DAGISEL-NEXT: RET_ReallyLR implicit $x0 - ; - ; GISEL-LABEL: name: large_imm_disc_wreg - ; GISEL: bb.1.entry: - ; GISEL-NEXT: liveins: $x0 - ; GISEL-NEXT: {{ $}} - ; GISEL-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; GISEL-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 12345678 - ; GISEL-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64noip = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32 - ; GISEL-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY]], 2, 0, [[SUBREG_TO_REG]], implicit-def dead $x16, implicit-def dead $x17 - ; GISEL-NEXT: $x0 = COPY [[PAC]] - ; GISEL-NEXT: RET_ReallyLR implicit $x0 +define i64 @aut_no_addr_modif_optimized(i64 %addr) { + ; CHECK-LABEL: name: aut_no_addr_modif_optimized + ; DARWIN: AUTx16x17 2, 42, $noreg, implicit-def $x16, implicit-def {{(dead )?}}$x17, implicit-def dead $nzcv, implicit $x16 + ; ELF: {{.*}} = AUTxMxN {{[^,]+}}, 2, 42, $noreg, implicit-def dead $nzcv + ; CHECK: RET_ReallyLR implicit $x0 entry: - %signed = call i64 @llvm.ptrauth.sign(i64 %addr, i32 2, i64 12345678) + %signed = call i64 @llvm.ptrauth.auth(i64 %addr) [ "ptrauth"(i64 2, i64 42, i64 0) ] ret i64 %signed } -define i64 @large_imm_disc_xreg(i64 %addr) { - ; DAGISEL-LABEL: name: large_imm_disc_xreg - ; DAGISEL: bb.0.entry: - ; DAGISEL-NEXT: liveins: $x0 - ; DAGISEL-NEXT: {{ $}} - ; DAGISEL-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; DAGISEL-NEXT: [[MOVi64imm:%[0-9]+]]:gpr64noip = MOVi64imm 123456789012345 - ; DAGISEL-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY]], 2, 0, killed [[MOVi64imm]], implicit-def dead $x16, implicit-def dead $x17 - ; DAGISEL-NEXT: $x0 = COPY [[PAC]] - ; DAGISEL-NEXT: RET_ReallyLR implicit $x0 - ; - ; GISEL-LABEL: name: large_imm_disc_xreg - ; GISEL: bb.1.entry: - ; GISEL-NEXT: liveins: $x0 - ; GISEL-NEXT: {{ $}} - ; GISEL-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; GISEL-NEXT: [[MOVi64imm:%[0-9]+]]:gpr64noip = MOVi64imm 123456789012345 - ; GISEL-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY]], 2, 0, [[MOVi64imm]], implicit-def dead $x16, implicit-def dead $x17 - ; GISEL-NEXT: $x0 = COPY [[PAC]] - ; GISEL-NEXT: RET_ReallyLR implicit $x0 +define i64 @aut_no_addr_modif_not_optimized(i64 %addr) noinline optnone { + ; CHECK-LABEL: name: aut_no_addr_modif_not_optimized + ; DARWIN: AUTx16x17 2, 42, $noreg, implicit-def $x16, implicit-def {{(dead )?}}$x17, implicit-def dead $nzcv, implicit $x16 + ; ELF: {{.*}} = AUTxMxN {{[^,]+}}, 2, 42, $noreg, implicit-def dead $nzcv + ; CHECK: RET_ReallyLR implicit $x0 entry: - %signed = call i64 @llvm.ptrauth.sign(i64 %addr, i32 2, i64 123456789012345) + %signed = call i64 @llvm.ptrauth.auth(i64 %addr) [ "ptrauth"(i64 2, i64 42, i64 0) ] ret i64 %signed } -; Make sure blend() is lowered as expected when optimization is disabled. -define i64 @blended_disc_non_optimized(i64 %addr, i64 %addrdisc) noinline optnone { - ; DAGISEL-LABEL: name: blended_disc_non_optimized - ; DAGISEL: bb.0.entry: - ; DAGISEL-NEXT: liveins: $x0, $x1 - ; DAGISEL-NEXT: {{ $}} - ; DAGISEL-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x1 - ; DAGISEL-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x0 - ; DAGISEL-NEXT: [[COPY2:%[0-9]+]]:gpr64 = COPY killed [[COPY1]] - ; DAGISEL-NEXT: [[COPY3:%[0-9]+]]:gpr64 = COPY killed [[COPY]] - ; DAGISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64 = MOVKXi [[COPY3]], 42, 48 - ; DAGISEL-NEXT: [[COPY4:%[0-9]+]]:gpr64noip = COPY [[MOVKXi]] - ; DAGISEL-NEXT: [[COPY5:%[0-9]+]]:gpr64noip = COPY [[COPY3]] - ; DAGISEL-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY2]], 2, 42, [[COPY5]], implicit-def dead $x16, implicit-def dead $x17 - ; DAGISEL-NEXT: [[COPY6:%[0-9]+]]:gpr64all = COPY [[PAC]] - ; DAGISEL-NEXT: $x0 = COPY [[COPY6]] - ; DAGISEL-NEXT: RET_ReallyLR implicit $x0 - ; - ; GISEL-LABEL: name: blended_disc_non_optimized - ; GISEL: bb.1.entry: - ; GISEL-NEXT: liveins: $x0, $x1 - ; GISEL-NEXT: {{ $}} - ; GISEL-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; GISEL-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; GISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64noip = MOVKXi [[COPY1]], 42, 48 - ; GISEL-NEXT: [[COPY2:%[0-9]+]]:gpr64noip = COPY [[COPY1]] - ; GISEL-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY]], 2, 42, [[COPY2]], implicit-def dead $x16, implicit-def dead $x17 - ; GISEL-NEXT: $x0 = COPY [[PAC]] - ; GISEL-NEXT: RET_ReallyLR implicit $x0 +define i64 @resign_no_addr_modif_optimized(i64 %addr) { + ; CHECK-LABEL: name: resign_no_addr_modif_optimized + ; CHECK: AUTPAC 2, 42, $noreg, 2, 123, $noreg, implicit-def $x16, implicit-def {{(dead )?}}$x17, implicit-def dead $nzcv, implicit $x16 + ; CHECK: RET_ReallyLR implicit $x0 entry: - %disc = call i64 @llvm.ptrauth.blend(i64 %addrdisc, i64 42) - %signed = call i64 @llvm.ptrauth.sign(i64 %addr, i32 2, i64 %disc) + %signed = call i64 @llvm.ptrauth.resign(i64 %addr) [ "ptrauth"(i64 2, i64 42, i64 0), "ptrauth"(i64 2, i64 123, i64 0) ] ret i64 %signed } -define i64 @blend_and_sign_same_bb(i64 %addr) { - ; DAGISEL-LABEL: name: blend_and_sign_same_bb - ; DAGISEL: bb.0.entry: - ; DAGISEL-NEXT: liveins: $x0 - ; DAGISEL-NEXT: {{ $}} - ; DAGISEL-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; DAGISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar - ; DAGISEL-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui killed [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar) - ; DAGISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64noip = MOVKXi [[LDRXui]], 42, 48 - ; DAGISEL-NEXT: [[COPY1:%[0-9]+]]:gpr64noip = COPY [[LDRXui]] - ; DAGISEL-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY]], 2, 42, killed [[COPY1]], implicit-def dead $x16, implicit-def dead $x17 - ; DAGISEL-NEXT: $x0 = COPY [[PAC]] - ; DAGISEL-NEXT: RET_ReallyLR implicit $x0 - ; - ; GISEL-LABEL: name: blend_and_sign_same_bb - ; GISEL: bb.1.entry: - ; GISEL-NEXT: liveins: $x0 - ; GISEL-NEXT: {{ $}} - ; GISEL-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; GISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar - ; GISEL-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar) - ; GISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64noip = MOVKXi [[LDRXui]], 42, 48 - ; GISEL-NEXT: [[COPY1:%[0-9]+]]:gpr64noip = COPY [[LDRXui]] - ; GISEL-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY]], 2, 42, [[COPY1]], implicit-def dead $x16, implicit-def dead $x17 - ; GISEL-NEXT: $x0 = COPY [[PAC]] - ; GISEL-NEXT: RET_ReallyLR implicit $x0 +define i64 @resign_no_addr_modif_not_optimized(i64 %addr) noinline optnone { + ; CHECK-LABEL: name: resign_no_addr_modif_not_optimized + ; CHECK: AUTPAC 2, 42, $noreg, 2, 123, $noreg, implicit-def $x16, implicit-def {{(dead )?}}$x17, implicit-def dead $nzcv, implicit $x16 + ; CHECK: RET_ReallyLR implicit $x0 entry: - %addrdisc = load i64, ptr @discvar - %disc = call i64 @llvm.ptrauth.blend(i64 %addrdisc, i64 42) - %signed = call i64 @llvm.ptrauth.sign(i64 %addr, i32 2, i64 %disc) - ret i64 %signed -} - -; In the below test cases both %addrdisc and %disc are computed (i.e. they are -; neither global addresses, nor function arguments) in a different basic block, -; making them harder to express via ISD::PtrAuthGlobalAddress. - -define i64 @blend_and_sign_different_bbs(i64 %addr, i64 %cond) { - ; DAGISEL-LABEL: name: blend_and_sign_different_bbs - ; DAGISEL: bb.0.entry: - ; DAGISEL-NEXT: successors: %bb.1(0x50000000), %bb.2(0x30000000) - ; DAGISEL-NEXT: liveins: $x0, $x1 - ; DAGISEL-NEXT: {{ $}} - ; DAGISEL-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x1 - ; DAGISEL-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x0 - ; DAGISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar - ; DAGISEL-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui killed [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar) - ; DAGISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64 = MOVKXi [[LDRXui]], 42, 48 - ; DAGISEL-NEXT: [[COPY2:%[0-9]+]]:gpr64noip = COPY [[MOVKXi]] - ; DAGISEL-NEXT: CBZX [[COPY]], %bb.2 - ; DAGISEL-NEXT: B %bb.1 - ; DAGISEL-NEXT: {{ $}} - ; DAGISEL-NEXT: bb.1.next: - ; DAGISEL-NEXT: successors: %bb.2(0x80000000) - ; DAGISEL-NEXT: {{ $}} - ; DAGISEL-NEXT: [[COPY3:%[0-9]+]]:gpr64common = COPY [[COPY2]] - ; DAGISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[COPY3]] - ; DAGISEL-NEXT: {{ $}} - ; DAGISEL-NEXT: bb.2.exit: - ; DAGISEL-NEXT: [[COPY4:%[0-9]+]]:gpr64noip = COPY [[LDRXui]] - ; DAGISEL-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY1]], 2, 42, [[COPY4]], implicit-def dead $x16, implicit-def dead $x17 - ; DAGISEL-NEXT: $x0 = COPY [[PAC]] - ; DAGISEL-NEXT: RET_ReallyLR implicit $x0 - ; - ; GISEL-LABEL: name: blend_and_sign_different_bbs - ; GISEL: bb.1.entry: - ; GISEL-NEXT: successors: %bb.2(0x50000000), %bb.3(0x30000000) - ; GISEL-NEXT: liveins: $x0, $x1 - ; GISEL-NEXT: {{ $}} - ; GISEL-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; GISEL-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; GISEL-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) @discvar - ; GISEL-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) @discvar :: (dereferenceable load (s64) from @discvar) - ; GISEL-NEXT: [[MOVKXi:%[0-9]+]]:gpr64noip = MOVKXi [[LDRXui]], 42, 48 - ; GISEL-NEXT: CBZX [[COPY1]], %bb.3 - ; GISEL-NEXT: B %bb.2 - ; GISEL-NEXT: {{ $}} - ; GISEL-NEXT: bb.2.next: - ; GISEL-NEXT: successors: %bb.3(0x80000000) - ; GISEL-NEXT: {{ $}} - ; GISEL-NEXT: [[COPY2:%[0-9]+]]:gpr64common = COPY [[MOVKXi]] - ; GISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[COPY2]] - ; GISEL-NEXT: {{ $}} - ; GISEL-NEXT: bb.3.exit: - ; GISEL-NEXT: [[COPY3:%[0-9]+]]:gpr64noip = COPY [[LDRXui]] - ; GISEL-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY]], 2, 42, [[COPY3]], implicit-def dead $x16, implicit-def dead $x17 - ; GISEL-NEXT: $x0 = COPY [[PAC]] - ; GISEL-NEXT: RET_ReallyLR implicit $x0 -entry: - %addrdisc = load i64, ptr @discvar - %disc = call i64 @llvm.ptrauth.blend(i64 %addrdisc, i64 42) - %cond.b = icmp ne i64 %cond, 0 - br i1 %cond.b, label %next, label %exit - -next: - call void asm sideeffect "nop", "r"(i64 %disc) - br label %exit - -exit: - %signed = call i64 @llvm.ptrauth.sign(i64 %addr, i32 2, i64 %disc) + %signed = call i64 @llvm.ptrauth.resign(i64 %addr) [ "ptrauth"(i64 2, i64 42, i64 0), "ptrauth"(i64 2, i64 123, i64 0) ] ret i64 %signed } diff --git a/llvm/test/CodeGen/AArch64/ptrauth-isel.mir b/llvm/test/CodeGen/AArch64/ptrauth-isel.mir deleted file mode 100644 index 1a155887059e3..0000000000000 --- a/llvm/test/CodeGen/AArch64/ptrauth-isel.mir +++ /dev/null @@ -1,205 +0,0 @@ -# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5 -# RUN: llc -o - %s -mtriple arm64e-apple-darwin -verify-machineinstrs \ -# RUN: -stop-after=finalize-isel -start-before=finalize-isel | FileCheck %s -# RUN: llc -o - %s -mtriple aarch64-linux-gnu -mattr=+pauth -verify-machineinstrs \ -# RUN: -stop-after=finalize-isel -start-before=finalize-isel | FileCheck %s - -# This MIR-based test contains several test cases that are hard to implement -# via an LLVM IR input. Most other test cases are in ptrauth-isel.ll file. - ---- | - @globalvar = dso_local global i64 0 - - define i64 @movk_correct_blend(i64 %a, i64 %b) { - entry: - ret i64 0 - } - - define i64 @movk_wrong_shift_amount(i64 %a, i64 %b) { - entry: - ret i64 0 - } - - define i64 @movk_non_immediate_operand(i64 %a, i64 %b) { - entry: - ret i64 0 - } - - define i64 @movi64imm_immediate_operand(i64 %a) { - entry: - ret i64 0 - } - - define i64 @movi64imm_non_immediate_operand(i64 %a) { - entry: - ret i64 0 - } - - define i64 @movi32imm_immediate_operand(i64 %a) { - entry: - ret i64 0 - } - - define i64 @movi32imm_non_immediate_operand(i64 %a) { - entry: - ret i64 0 - } -... ---- -name: movk_correct_blend -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $x0, $x1 - - ; CHECK-LABEL: name: movk_correct_blend - ; CHECK: liveins: $x0, $x1 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; CHECK-NEXT: [[MOVKXi:%[0-9]+]]:gpr64noip = MOVKXi [[COPY1]], 42, 48 - ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr64noip = COPY [[COPY1]] - ; CHECK-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY]], 2, 42, killed [[COPY2]], implicit-def dead $x16, implicit-def dead $x17 - ; CHECK-NEXT: $x0 = COPY [[PAC]] - ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:gpr64 = COPY $x0 - %1:gpr64 = COPY $x1 - %2:gpr64noip = MOVKXi %1, 42, 48 - %3:gpr64 = PAC %0, 2, 0, killed %2, implicit-def dead $x16, implicit-def dead $x17 - $x0 = COPY %3 - RET_ReallyLR implicit $x0 -... ---- -name: movk_wrong_shift_amount -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $x0, $x1 - - ; CHECK-LABEL: name: movk_wrong_shift_amount - ; CHECK: liveins: $x0, $x1 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; CHECK-NEXT: [[MOVKXi:%[0-9]+]]:gpr64noip = MOVKXi [[COPY1]], 42, 0 - ; CHECK-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY]], 2, 0, killed [[MOVKXi]], implicit-def dead $x16, implicit-def dead $x17 - ; CHECK-NEXT: $x0 = COPY [[PAC]] - ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:gpr64 = COPY $x0 - %1:gpr64 = COPY $x1 - %2:gpr64noip = MOVKXi %1, 42, 0 - %3:gpr64 = PAC %0, 2, 0, killed %2, implicit-def dead $x16, implicit-def dead $x17 - $x0 = COPY %3 - RET_ReallyLR implicit $x0 -... ---- -name: movk_non_immediate_operand -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $x0, $x1 - - ; CHECK-LABEL: name: movk_non_immediate_operand - ; CHECK: liveins: $x0, $x1 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; CHECK-NEXT: [[MOVKXi:%[0-9]+]]:gpr64noip = MOVKXi [[COPY1]], target-flags(aarch64-pageoff, aarch64-nc) @globalvar, 48 - ; CHECK-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY]], 2, 0, killed [[MOVKXi]], implicit-def dead $x16, implicit-def dead $x17 - ; CHECK-NEXT: $x0 = COPY [[PAC]] - ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:gpr64 = COPY $x0 - %1:gpr64 = COPY $x1 - %2:gpr64noip = MOVKXi %1, target-flags(aarch64-pageoff, aarch64-nc) @globalvar, 48 - %3:gpr64 = PAC %0, 2, 0, killed %2, implicit-def dead $x16, implicit-def dead $x17 - $x0 = COPY %3 - RET_ReallyLR implicit $x0 -... ---- -name: movi64imm_immediate_operand -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $x0, $x1 - - ; CHECK-LABEL: name: movi64imm_immediate_operand - ; CHECK: liveins: $x0, $x1 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK-NEXT: [[MOVi64imm:%[0-9]+]]:gpr64noip = MOVi64imm 42 - ; CHECK-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY]], 2, 42, killed $noreg, implicit-def dead $x16, implicit-def dead $x17 - ; CHECK-NEXT: $x0 = COPY [[PAC]] - ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:gpr64 = COPY $x0 - %1:gpr64noip = MOVi64imm 42 - %2:gpr64 = PAC %0, 2, 0, killed %1, implicit-def dead $x16, implicit-def dead $x17 - $x0 = COPY %2 - RET_ReallyLR implicit $x0 -... ---- -name: movi64imm_non_immediate_operand -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $x0, $x1 - - ; CHECK-LABEL: name: movi64imm_non_immediate_operand - ; CHECK: liveins: $x0, $x1 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK-NEXT: [[MOVi64imm:%[0-9]+]]:gpr64noip = MOVi64imm target-flags(aarch64-pageoff, aarch64-nc) @globalvar - ; CHECK-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY]], 2, 0, killed [[MOVi64imm]], implicit-def dead $x16, implicit-def dead $x17 - ; CHECK-NEXT: $x0 = COPY [[PAC]] - ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:gpr64 = COPY $x0 - %1:gpr64noip = MOVi64imm target-flags(aarch64-pageoff, aarch64-nc) @globalvar - %2:gpr64 = PAC %0, 2, 0, killed %1, implicit-def dead $x16, implicit-def dead $x17 - $x0 = COPY %2 - RET_ReallyLR implicit $x0 -... ---- -name: movi32imm_immediate_operand -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $x0, $x1 - - ; CHECK-LABEL: name: movi32imm_immediate_operand - ; CHECK: liveins: $x0, $x1 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 42 - ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64noip = SUBREG_TO_REG 0, killed [[MOVi32imm]], %subreg.sub_32 - ; CHECK-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY]], 2, 42, killed $noreg, implicit-def dead $x16, implicit-def dead $x17 - ; CHECK-NEXT: $x0 = COPY [[PAC]] - ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:gpr64 = COPY $x0 - %1:gpr32 = MOVi32imm 42 - %2:gpr64noip = SUBREG_TO_REG 0, killed %1, %subreg.sub_32 - %3:gpr64 = PAC %0, 2, 0, killed %2, implicit-def dead $x16, implicit-def dead $x17 - $x0 = COPY %3 - RET_ReallyLR implicit $x0 -... ---- -name: movi32imm_non_immediate_operand -tracksRegLiveness: true -body: | - bb.0.entry: - liveins: $x0, $x1 - - ; CHECK-LABEL: name: movi32imm_non_immediate_operand - ; CHECK: liveins: $x0, $x1 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 - ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm target-flags(aarch64-pageoff, aarch64-nc) @globalvar - ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64noip = SUBREG_TO_REG 0, killed [[MOVi32imm]], %subreg.sub_32 - ; CHECK-NEXT: [[PAC:%[0-9]+]]:gpr64 = PAC [[COPY]], 2, 0, killed [[SUBREG_TO_REG]], implicit-def dead $x16, implicit-def dead $x17 - ; CHECK-NEXT: $x0 = COPY [[PAC]] - ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:gpr64 = COPY $x0 - %1:gpr32 = MOVi32imm target-flags(aarch64-pageoff, aarch64-nc) @globalvar - %2:gpr64noip = SUBREG_TO_REG 0, killed %1, %subreg.sub_32 - %3:gpr64 = PAC %0, 2, 0, killed %2, implicit-def dead $x16, implicit-def dead $x17 - $x0 = COPY %3 - RET_ReallyLR implicit $x0 -... diff --git a/llvm/test/CodeGen/AArch64/ptrauth-reloc.ll b/llvm/test/CodeGen/AArch64/ptrauth-reloc.ll index 02c643f101913..e128c941152a4 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-reloc.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-reloc.ll @@ -35,7 +35,7 @@ ; CHECK-MACHO-NEXT: .quad _g@AUTH(ia,0) ; CHECK-MACHO-NEXT: .quad 6 -@g.ref.ia.0 = constant { i64, ptr, i64 } { i64 5, ptr ptrauth (ptr @g, i32 0), i64 6 } +@g.ref.ia.0 = constant { i64, ptr, i64 } { i64 5, ptr ptrauth (ptr @g, [i64 0, i64 0, i64 0]), i64 6 } ; CHECK-ELF-LABEL: .globl g.ref.ia.42 ; CHECK-ELF-NEXT: .p2align 3 @@ -47,7 +47,7 @@ ; CHECK-MACHO-NEXT: _g.ref.ia.42: ; CHECK-MACHO-NEXT: .quad _g@AUTH(ia,42) -@g.ref.ia.42 = constant ptr ptrauth (ptr @g, i32 0, i64 42) +@g.ref.ia.42 = constant ptr ptrauth (ptr @g, [i64 0, i64 42, i64 0]) ; CHECK-ELF-LABEL: .globl g.ref.ib.0 ; CHECK-ELF-NEXT: .p2align 4 @@ -63,7 +63,7 @@ ; CHECK-MACHO-NEXT: .quad _g@AUTH(ib,0) ; CHECK-MACHO-NEXT: .quad 6 -@g.ref.ib.0 = constant { i64, ptr, i64 } { i64 5, ptr ptrauth (ptr @g, i32 1, i64 0), i64 6 } +@g.ref.ib.0 = constant { i64, ptr, i64 } { i64 5, ptr ptrauth (ptr @g, [i64 1, i64 0, i64 0]), i64 6 } ; CHECK-ELF-LABEL: .globl g.ref.da.42.addr ; CHECK-ELF-NEXT: .p2align 3 @@ -75,7 +75,7 @@ ; CHECK-MACHO-NEXT: _g.ref.da.42.addr: ; CHECK-MACHO-NEXT: .quad _g@AUTH(da,42,addr) -@g.ref.da.42.addr = constant ptr ptrauth (ptr @g, i32 2, i64 42, ptr @g.ref.da.42.addr) +@g.ref.da.42.addr = constant ptr ptrauth (ptr @g, [i64 2, i64 42, i64 ptrtoint (ptr @g.ref.da.42.addr to i64)]) ; CHECK-ELF-LABEL: .globl g.offset.ref.da.0 ; CHECK-ELF-NEXT: .p2align 3 @@ -87,7 +87,7 @@ ; CHECK-MACHO-NEXT: _g.offset.ref.da.0: ; CHECK-MACHO-NEXT: .quad (_g+16)@AUTH(da,0) -@g.offset.ref.da.0 = constant ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 16), i32 2) +@g.offset.ref.da.0 = constant ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 16), [i64 2, i64 0, i64 0]) ; CHECK-ELF-LABEL: .globl g.big_offset.ref.da.0 ; CHECK-ELF-NEXT: .p2align 3 @@ -99,7 +99,7 @@ ; CHECK-MACHO-NEXT: _g.big_offset.ref.da.0: ; CHECK-MACHO-NEXT: .quad (_g+2147549185)@AUTH(da,0) -@g.big_offset.ref.da.0 = constant ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 add (i64 2147483648, i64 65537)), i32 2) +@g.big_offset.ref.da.0 = constant ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 add (i64 2147483648, i64 65537)), [i64 2, i64 0, i64 0]) ; CHECK-ELF-LABEL: .globl g.weird_ref.da.0 ; CHECK-ELF-NEXT: .p2align 3 @@ -111,7 +111,7 @@ ; CHECK-MACHO-NEXT: _g.weird_ref.da.0: ; CHECK-MACHO-NEXT: .quad (_g+16)@AUTH(da,0) -@g.weird_ref.da.0 = constant i64 ptrtoint (ptr inttoptr (i64 ptrtoint (ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 16), i32 2) to i64) to ptr) to i64) +@g.weird_ref.da.0 = constant i64 ptrtoint (ptr inttoptr (i64 ptrtoint (ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 16), [i64 2, i64 0, i64 0]) to i64) to ptr) to i64) ; CHECK-ELF-LABEL: .globl g_weak.ref.ia.42 ; CHECK-ELF-NEXT: .p2align 3 @@ -123,7 +123,7 @@ ; CHECK-MACHO-NEXT: _g_weak.ref.ia.42: ; CHECK-MACHO-NEXT: .quad _g_weak@AUTH(ia,42) -@g_weak.ref.ia.42 = constant ptr ptrauth (ptr @g_weak, i32 0, i64 42) +@g_weak.ref.ia.42 = constant ptr ptrauth (ptr @g_weak, [i64 0, i64 42, i64 0]) ; CHECK-ELF-LABEL: .globl g_strong_def.ref.da.0 ; CHECK-ELF-NEXT: .p2align 3 @@ -135,7 +135,7 @@ ; CHECK-MACHO-NEXT: _g_strong_def.ref.da.0: ; CHECK-MACHO-NEXT: .quad _g_strong_def@AUTH(da,0) -@g_strong_def.ref.da.0 = constant ptr ptrauth (ptr @g_strong_def, i32 2) +@g_strong_def.ref.da.0 = constant ptr ptrauth (ptr @g_strong_def, [i64 2, i64 0, i64 0]) ;--- err-key.ll @@ -155,7 +155,7 @@ @g = external global i32 -@g.ref.4.0 = constant ptr ptrauth (ptr @g, i32 4, i64 0) +@g.ref.4.0 = constant ptr ptrauth (ptr @g, [i64 4, i64 0, i64 0]) ;--- err-disc.ll @@ -174,4 +174,4 @@ ; CHECK-ERR-DISC: error: AArch64 PAC Discriminator '65536' out of range [0, 0xFFFF] @g = external global i32 -@g.ref.ia.65536 = constant ptr ptrauth (ptr @g, i32 0, i64 65536) +@g.ref.ia.65536 = constant ptr ptrauth (ptr @g, [i64 0, i64 65536, i64 0]) diff --git a/llvm/test/CodeGen/AArch64/ptrauth-ret-trap.ll b/llvm/test/CodeGen/AArch64/ptrauth-ret-trap.ll index 4821b3c0f274b..77217028800f2 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-ret-trap.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-ret-trap.ll @@ -61,7 +61,7 @@ define void @test_tailcall_indirect_in_x9(ptr sret(i64) %ret, [8 x i64] %in, ptr ; CHECK: braa x0, x16 define void @test_auth_tailcall_indirect(ptr %fptr) #0 { call i32 @test_tailcall() - tail call void %fptr() [ "ptrauth"(i32 0, i64 42) ] + tail call void %fptr() [ "ptrauth"(i64 0, i64 42, i64 0) ] ret void } @@ -75,7 +75,7 @@ define void @test_auth_tailcall_indirect(ptr %fptr) #0 { define void @test_auth_tailcall_indirect_in_x9(ptr sret(i64) %ret, [8 x i64] %in, ptr %fptr) #0 { %ptr = alloca i8, i32 16 call i32 @test_tailcall() - tail call void %fptr(ptr sret(i64) %ret, [8 x i64] %in) [ "ptrauth"(i32 1, i64 0) ] + tail call void %fptr(ptr sret(i64) %ret, [8 x i64] %in) [ "ptrauth"(i64 1, i64 0, i64 0) ] ret void } @@ -89,7 +89,7 @@ define void @test_auth_tailcall_indirect_in_x9(ptr sret(i64) %ret, [8 x i64] %in define void @test_auth_tailcall_indirect_bti(ptr sret(i64) %ret, [8 x i64] %in, ptr %fptr) #0 "branch-target-enforcement"="true" { %ptr = alloca i8, i32 16 call i32 @test_tailcall() - tail call void %fptr(ptr sret(i64) %ret, [8 x i64] %in) [ "ptrauth"(i32 1, i64 0) ] + tail call void %fptr(ptr sret(i64) %ret, [8 x i64] %in) [ "ptrauth"(i64 1, i64 0, i64 0) ] ret void } diff --git a/llvm/test/CodeGen/AArch64/ptrauth-tail-call-regalloc.ll b/llvm/test/CodeGen/AArch64/ptrauth-tail-call-regalloc.ll index ac578e3e99b81..a159effb8671b 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-tail-call-regalloc.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-tail-call-regalloc.ll @@ -20,7 +20,7 @@ entry: tail call void asm sideeffect "", "~{x0},~{x1},~{x2},~{x3},~{x4},~{x5},~{x6},~{x7},~{x8},~{x9},~{x10},~{x11},~{x12},~{x13},~{x14},~{x15}"() tail call void asm sideeffect "", "~{x18},~{x19},~{x20},~{x21},~{x22},~{x23},~{x24},~{x25},~{x26},~{x27},~{x28},~{fp}"() %addr.i = ptrtoint ptr %addr to i64 - %call = tail call i32 %callee() #1 [ "ptrauth"(i32 0, i64 %addr.i) ] + %call = tail call i32 %callee() #1 [ "ptrauth"(i64 0, i64 0, i64 %addr.i) ] ret i32 %call } ;; Ensure the specific tail call pseudo instruction is used. @@ -70,7 +70,7 @@ entry: tail call void asm sideeffect "", "~{x0},~{x1},~{x2},~{x3},~{x4},~{x5},~{x6},~{x7},~{x8},~{x9},~{x10},~{x11},~{x12},~{x13},~{x14},~{x15}"() tail call void asm sideeffect "", "~{x18},~{x19},~{x20},~{x21},~{x22},~{x23},~{x24},~{x25},~{x26},~{x27},~{x28},~{fp}"() %addr.i = ptrtoint ptr %addr to i64 - %call = tail call i32 %callee() #1 [ "ptrauth"(i32 0, i64 %addr.i) ] + %call = tail call i32 %callee() #1 [ "ptrauth"(i64 0, i64 0, i64 %addr.i) ] ret i32 %call } ;; Ensure the specific tail call pseudo instruction is used. diff --git a/llvm/test/CodeGen/AArch64/ptrauth-type-info-vptr-discr.ll b/llvm/test/CodeGen/AArch64/ptrauth-type-info-vptr-discr.ll index 31ef6cba6fbdd..f7fbcb25b081e 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-type-info-vptr-discr.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-type-info-vptr-discr.ll @@ -12,10 +12,10 @@ ; MACHO-NEXT: .quad (__ZTVN10__cxxabiv117__class_type_infoE+16)@AUTH(da,45546) -@_ZTI10Disc = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2, i64 45546, ptr @_ZTI10Disc), ptr @_ZTS10Disc }, align 8 +@_ZTI10Disc = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), [i64 2, i64 45546, i64 ptrtoint (ptr @_ZTI10Disc to i64)]), ptr @_ZTS10Disc }, align 8 @_ZTS10Disc = constant [4 x i8] c"Disc", align 1 -@_ZTI10NoDisc = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2, i64 45546), ptr @_ZTS10NoDisc }, align 8 +@_ZTI10NoDisc = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), [i64 2, i64 45546, i64 0]), ptr @_ZTS10NoDisc }, align 8 @_ZTS10NoDisc = constant [6 x i8] c"NoDisc", align 1 @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr] diff --git a/llvm/test/CodeGen/AArch64/ptrauth-unsupported-bundle.ll b/llvm/test/CodeGen/AArch64/ptrauth-unsupported-bundle.ll new file mode 100644 index 0000000000000..f448c33bfab6a --- /dev/null +++ b/llvm/test/CodeGen/AArch64/ptrauth-unsupported-bundle.ll @@ -0,0 +1,234 @@ +; RUN: split-file %s %t +; REQUIRES: x86-registered-target + +;--- empty.ll +; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/empty.ll 2>&1 | FileCheck --check-prefix=EMPTY %s + +; Empty "ptrauth" bundles are rejected by target-independent LLVM IR Verifier. + +; EMPTY: Expected non-empty ptrauth bundle +; EMPTY-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"() ] +; EMPTY-NEXT: llc: error: '': input module cannot be verified + +define i64 @test(i64 %p) { + %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"() ] + ret i64 %res +} + +;--- wrong-type-i32.ll +; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-type-i32.ll 2>&1 | FileCheck --check-prefix=WRONG-TYPE-I32 %s + +; Non-i64 operands of "ptrauth" bundles are rejected by target-independent +; LLVM IR Verifier, provided they cannot be auto-upgraded when the LLVM IR +; source is being read. + +; WRONG-TYPE-I32: Ptrauth bundle must only contain i64 operands +; WRONG-TYPE-I32-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i32 0, i32 0, i64 0) ] +; WRONG-TYPE-I32-NEXT: llc: error: '': input module cannot be verified + +define i64 @test(i64 %p) { + %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i32 0, i32 0, i64 0) ] + ret i64 %res +} + +;--- wrong-type-ptr.ll +; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-type-ptr.ll 2>&1 | FileCheck --check-prefix=WRONG-TYPE-PTR %s + +; WRONG-TYPE-PTR: Ptrauth bundle must only contain i64 operands +; WRONG-TYPE-PTR-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 0, ptr %arg) ] +; WRONG-TYPE-PTR-NEXT: llc: error: '': input module cannot be verified + +define i64 @test(i64 %p, ptr %arg) { + %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 0, ptr %arg) ] + ret i64 %res +} + +;--- wrong-not-one-bundle.ll +; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-not-one-bundle.ll 2>&1 | FileCheck --check-prefix=WRONG-NOT-ONE-BUNDLE %s + +; Wrong number of "ptrauth" bundles is rejected by target-independent +; LLVM IR Verifier. + +; WRONG-NOT-ONE-BUNDLE: Expected exactly one ptrauth bundle +; WRONG-NOT-ONE-BUNDLE-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 0, i64 0, i64 0) ] +; WRONG-NOT-ONE-BUNDLE-NEXT: llc: error: '': input module cannot be verified + +define i64 @test(i64 %p) { + %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 0, i64 0, i64 0) ] + ret i64 %res +} + +;--- wrong-not-two-bundles.ll +; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-not-two-bundles.ll 2>&1 | FileCheck --check-prefix=WRONG-NOT-TWO-BUNDLES %s + +; WRONG-NOT-TWO-BUNDLES: Expected exactly two ptrauth bundles +; WRONG-NOT-TWO-BUNDLES-NEXT: %res = call i64 @llvm.ptrauth.resign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0) ] +; WRONG-NOT-TWO-BUNDLES-NEXT: llc: error: '': input module cannot be verified + +define i64 @test(i64 %p) { + %res = call i64 @llvm.ptrauth.resign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0) ] + ret i64 %res +} + +;--- wrong-missing-bundle.ll +; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-missing-bundle.ll 2>&1 | FileCheck --check-prefix=WRONG-MISSING-BUNDLE %s + +; WRONG-MISSING-BUNDLE: Expected exactly one ptrauth bundle +; WRONG-MISSING-BUNDLE-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) +; WRONG-MISSING-BUNDLE-NEXT: llc: error: '': input module cannot be verified + +define i64 @test(i64 %p) { + %res = call i64 @llvm.ptrauth.sign(i64 %p) + ret i64 %res +} + +;--- wrong-indirect-call-multiple-bundles.ll +; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-indirect-call-multiple-bundles.ll 2>&1 | FileCheck --check-prefix=WRONG-INDIRECT-CALL-MULTIPLE-BUNDLES %s + +; WRONG-INDIRECT-CALL-MULTIPLE-BUNDLES: Multiple ptrauth operand bundles on a function call +; WRONG-INDIRECT-CALL-MULTIPLE-BUNDLES-NEXT: %res = call i64 %fptr() [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 0, i64 0, i64 0) ] +; WRONG-INDIRECT-CALL-MULTIPLE-BUNDLES-NEXT: llc: error: '': input module cannot be verified + +define i64 @test(ptr %fptr) { + %res = call i64 %fptr() [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 0, i64 0, i64 0) ] + ret i64 %res +} +;--- unsupported-target-intrinsic.ll +; RUN: not llc -mtriple x86_64 < %t/unsupported-target-intrinsic.ll 2>&1 | FileCheck --check-prefix=UNSUPPORTED-TARGET-INTRINSIC %s + +; UNSUPPORTED-TARGET-INTRINSIC: Ptrauth schema violates target-specific constraints: +; UNSUPPORTED-TARGET-INTRINSIC-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0) ] +; UNSUPPORTED-TARGET-INTRINSIC-NEXT: LLVM ERROR: Invalid ptrauth schema: this target does not support pointer authentication + +define i64 @test(i64 %p) { + %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0) ] + ret i64 %res +} + +;--- unsupported-target-indirect-call.ll +; RUN: not llc -mtriple x86_64 < %t/unsupported-target-indirect-call.ll 2>&1 | FileCheck --check-prefix=UNSUPPORTED-TARGET-INDIRECT-CALL %s + +; UNSUPPORTED-TARGET-INDIRECT-CALL: Ptrauth schema violates target-specific constraints: +; UNSUPPORTED-TARGET-INDIRECT-CALL-NEXT: %res = call i64 %fptr() [ "ptrauth"(i64 0) ] +; UNSUPPORTED-TARGET-INDIRECT-CALL-NEXT: LLVM ERROR: Invalid ptrauth schema: this target does not support pointer authentication + +define i64 @test(ptr %fptr) { + %res = call i64 %fptr() [ "ptrauth"(i64 0) ] + ret i64 %res +} + +;--- wrong-not-3-ops.ll +; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-not-3-ops.ll 2>&1 | FileCheck --check-prefix=WRONG-NOT-3-OPS %s + +; Single-operand bundles are used on AArch64, but not by this intrinsic. + +; WRONG-NOT-3-OPS: Ptrauth schema violates target-specific constraints: +; WRONG-NOT-3-OPS-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0) ] +; WRONG-NOT-3-OPS-NEXT: LLVM ERROR: Invalid ptrauth schema: test: three-element ptrauth bundle expected + +define i64 @test(i64 %p) { + %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0) ] + ret i64 %res +} + +;--- wrong-not-1-ops.ll +; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-not-1-ops.ll 2>&1 | FileCheck --check-prefix=WRONG-NOT-1-OPS %s + +; Three-operand bundles are used on AArch64, but not by this intrinsic. + +; WRONG-NOT-1-OPS: Ptrauth schema violates target-specific constraints: +; WRONG-NOT-1-OPS-NEXT: %res = call i64 @llvm.ptrauth.strip(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0) ] +; WRONG-NOT-1-OPS-NEXT: LLVM ERROR: Invalid ptrauth schema: test: single-element ptrauth bundle expected + +define i64 @test(i64 %p) { + %res = call i64 @llvm.ptrauth.strip(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0) ] + ret i64 %res +} + +;--- wrong-num-operands.ll +; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-num-operands.ll 2>&1 | FileCheck --check-prefix=WRONG-NUM-OPERANDS %s + +; Four-operand bundles are never used on AArch64. + +; WRONG-NUM-OPERANDS: Ptrauth schema violates target-specific constraints: +; WRONG-NUM-OPERANDS-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0, i64 0) ] +; WRONG-NUM-OPERANDS-NEXT: LLVM ERROR: Invalid ptrauth schema: test: three-element ptrauth bundle expected + +define i64 @test(i64 %p, i64 %arg) { + %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0, i64 0) ] + ret i64 %res +} + +;--- wrong-key-not-const.ll +; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-key-not-const.ll 2>&1 | FileCheck --check-prefix=WRONG-KEY-NOT-CONST %s + +; WRONG-KEY-NOT-CONST: Ptrauth schema violates target-specific constraints: +; WRONG-KEY-NOT-CONST-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 %arg, i64 0, i64 0) ] +; WRONG-KEY-NOT-CONST-NEXT: LLVM ERROR: Invalid ptrauth schema: test: key must be constant in range [0, 3] + +define i64 @test(i64 %p, i64 %arg) { + %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 %arg, i64 0, i64 0) ] + ret i64 %res +} + +;--- wrong-imm-modifier-not-const.ll +; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-imm-modifier-not-const.ll 2>&1 | FileCheck --check-prefix=WRONG-IMM-MODIFIER-NOT-CONST %s + +; WRONG-IMM-MODIFIER-NOT-CONST: Ptrauth schema violates target-specific constraints: +; WRONG-IMM-MODIFIER-NOT-CONST-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 %arg, i64 0) ] +; WRONG-IMM-MODIFIER-NOT-CONST-NEXT: LLVM ERROR: Invalid ptrauth schema: test: constant modifier must be 16-bit unsigned constant + +define i64 @test(i64 %p, i64 %arg) { + %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 %arg, i64 0) ] + ret i64 %res +} + +;--- wrong-imm-modifier-negative.ll +; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-imm-modifier-negative.ll 2>&1 | FileCheck --check-prefix=WRONG-IMM-MODIFIER-NEGATIVE %s + +; WRONG-IMM-MODIFIER-NEGATIVE: Ptrauth schema violates target-specific constraints: +; WRONG-IMM-MODIFIER-NEGATIVE-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 -1, i64 0) ] +; WRONG-IMM-MODIFIER-NEGATIVE-NEXT: LLVM ERROR: Invalid ptrauth schema: test: constant modifier must be 16-bit unsigned constant + +define i64 @test(i64 %p) { + %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 -1, i64 0) ] + ret i64 %res +} + +;--- wrong-imm-modifier-too-wide.ll +; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-imm-modifier-too-wide.ll 2>&1 | FileCheck --check-prefix=WRONG-IMM-MODIFIER-TOO-WIDE %s + +; WRONG-IMM-MODIFIER-TOO-WIDE: Ptrauth schema violates target-specific constraints: +; WRONG-IMM-MODIFIER-TOO-WIDE-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 123456, i64 0) ] +; WRONG-IMM-MODIFIER-TOO-WIDE-NEXT: LLVM ERROR: Invalid ptrauth schema: test: constant modifier must be 16-bit unsigned constant + +define i64 @test(i64 %p) { + %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 123456, i64 0) ] + ret i64 %res +} + +;--- wrong-first-bundle.ll +; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-first-bundle.ll 2>&1 | FileCheck --check-prefix=WRONG-FIRST-BUNDLE %s + +; If the intrinsic accepts two bundles, both should be checked. + +; WRONG-FIRST-BUNDLE: Ptrauth schema violates target-specific constraints: +; WRONG-FIRST-BUNDLE-NEXT: %res = call i64 @llvm.ptrauth.resign(i64 %p) [ "ptrauth"(i64 %arg, i64 0, i64 0), "ptrauth"(i64 0, i64 0, i64 0) ] +; WRONG-FIRST-BUNDLE-NEXT: LLVM ERROR: Invalid ptrauth schema: test: key must be constant in range [0, 3] + +define i64 @test(i64 %p, i64 %arg) { + %res = call i64 @llvm.ptrauth.resign(i64 %p) [ "ptrauth"(i64 %arg, i64 0, i64 0), "ptrauth"(i64 0, i64 0, i64 0) ] + ret i64 %res +} + +;--- wrong-second-bundle.ll +; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-second-bundle.ll 2>&1 | FileCheck --check-prefix=WRONG-SECOND-BUNDLE %s + +; WRONG-SECOND-BUNDLE: Ptrauth schema violates target-specific constraints: +; WRONG-SECOND-BUNDLE-NEXT: %res = call i64 @llvm.ptrauth.resign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 %arg, i64 0, i64 0) ] +; WRONG-SECOND-BUNDLE-NEXT: LLVM ERROR: Invalid ptrauth schema: test: key must be constant in range [0, 3] + +define i64 @test(i64 %p, i64 %arg) { + %res = call i64 @llvm.ptrauth.resign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 %arg, i64 0, i64 0) ] + ret i64 %res +} diff --git a/llvm/test/CodeGen/MIR/AArch64/deactivation-symbols.mir b/llvm/test/CodeGen/MIR/AArch64/deactivation-symbols.mir index 6542508ede116..221b13358b711 100644 --- a/llvm/test/CodeGen/MIR/AArch64/deactivation-symbols.mir +++ b/llvm/test/CodeGen/MIR/AArch64/deactivation-symbols.mir @@ -5,8 +5,8 @@ @ds = external global i8 define i64 @pauth_sign_zero(i64 %p) { - ; CHECK: G_INTRINSIC intrinsic(@llvm.ptrauth.sign), %0(s64), 0, %2(s64), deactivation-symbol @ds - %signed = call i64 @llvm.ptrauth.sign(i64 %p, i32 0, i64 0) [ "deactivation-symbol"(ptr @ds) ] + ; CHECK: G_PTRAUTH_SIGN %0, %2(s0), deactivation-symbol @ds + %signed = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0), "deactivation-symbol"(ptr @ds) ] ret i64 %signed } ... diff --git a/llvm/test/CodeGen/MIR2Vec/Inputs/reference_x86_vocab_print.txt b/llvm/test/CodeGen/MIR2Vec/Inputs/reference_x86_vocab_print.txt index 62e07445ad12e..810e9676a33a0 100644 --- a/llvm/test/CodeGen/MIR2Vec/Inputs/reference_x86_vocab_print.txt +++ b/llvm/test/CodeGen/MIR2Vec/Inputs/reference_x86_vocab_print.txt @@ -477,7 +477,12 @@ Key: G_MUL: [ 0.00 0.00 ] Key: G_OR: [ 0.00 0.00 ] Key: G_PHI: [ 0.00 0.00 ] Key: G_PREFETCH: [ 0.00 0.00 ] +Key: G_PTRAUTH_AUTH: [ 0.00 0.00 ] +Key: G_PTRAUTH_BUNDLE: [ 0.00 0.00 ] Key: G_PTRAUTH_GLOBAL_VALUE: [ 0.00 0.00 ] +Key: G_PTRAUTH_RESIGN: [ 0.00 0.00 ] +Key: G_PTRAUTH_SIGN: [ 0.00 0.00 ] +Key: G_PTRAUTH_STRIP: [ 0.00 0.00 ] Key: G_PTRMASK: [ 0.00 0.00 ] Key: G_PTRTOINT: [ 0.00 0.00 ] Key: G_PTR_ADD: [ 0.00 0.00 ] diff --git a/llvm/test/CodeGen/MIR2Vec/Inputs/reference_x86_vocab_wo=0.5_print.txt b/llvm/test/CodeGen/MIR2Vec/Inputs/reference_x86_vocab_wo=0.5_print.txt index 03a3fafc6b801..cf0288ddf5418 100644 --- a/llvm/test/CodeGen/MIR2Vec/Inputs/reference_x86_vocab_wo=0.5_print.txt +++ b/llvm/test/CodeGen/MIR2Vec/Inputs/reference_x86_vocab_wo=0.5_print.txt @@ -477,7 +477,12 @@ Key: G_MUL: [ 0.00 0.00 ] Key: G_OR: [ 0.00 0.00 ] Key: G_PHI: [ 0.00 0.00 ] Key: G_PREFETCH: [ 0.00 0.00 ] +Key: G_PTRAUTH_AUTH: [ 0.00 0.00 ] +Key: G_PTRAUTH_BUNDLE: [ 0.00 0.00 ] Key: G_PTRAUTH_GLOBAL_VALUE: [ 0.00 0.00 ] +Key: G_PTRAUTH_RESIGN: [ 0.00 0.00 ] +Key: G_PTRAUTH_SIGN: [ 0.00 0.00 ] +Key: G_PTRAUTH_STRIP: [ 0.00 0.00 ] Key: G_PTRMASK: [ 0.00 0.00 ] Key: G_PTRTOINT: [ 0.00 0.00 ] Key: G_PTR_ADD: [ 0.00 0.00 ] diff --git a/llvm/test/CodeGen/RISCV/rv32zknd-intrinsic-autoupgrade.ll b/llvm/test/CodeGen/RISCV/rv32zknd-intrinsic-autoupgrade.ll index 6e6d18490782c..e4216319256a3 100644 --- a/llvm/test/CodeGen/RISCV/rv32zknd-intrinsic-autoupgrade.ll +++ b/llvm/test/CodeGen/RISCV/rv32zknd-intrinsic-autoupgrade.ll @@ -2,6 +2,9 @@ ; RUN: llc -mtriple=riscv32 -mattr=+zknd -verify-machineinstrs < %s \ ; RUN: | FileCheck %s -check-prefix=RV32ZKND +; FIXME: Commenting this out makes auto-upgrader fail! +declare i32 @llvm.riscv.aes32dsi(i32, i32, i8); + define i32 @aes32dsi(i32 %a, i32 %b) nounwind { ; RV32ZKND-LABEL: aes32dsi: ; RV32ZKND: # %bb.0: @@ -11,6 +14,17 @@ define i32 @aes32dsi(i32 %a, i32 %b) nounwind { ret i32 %val } +define i32 @aes32dsi_1(i32 %a, i32 %b) nounwind { +; RV32ZKND-LABEL: aes32dsi_1: +; RV32ZKND: # %bb.0: +; RV32ZKND-NEXT: aes32dsi a0, a0, a1, 0 +; RV32ZKND-NEXT: ret + %val = call i32 @llvm.riscv.aes32dsi(i32 %a, i32 %b, i8 0) + ret i32 %val +} + +declare i32 @llvm.riscv.aes32dsmi(i32, i32, i8); + define i32 @aes32dsmi(i32 %a, i32 %b) nounwind { ; RV32ZKND-LABEL: aes32dsmi: ; RV32ZKND: # %bb.0: diff --git a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-cxx.td b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-cxx.td index 28017700a0448..8257da322038b 100644 --- a/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-cxx.td +++ b/llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-cxx.td @@ -96,7 +96,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [ // CHECK: const uint8_t *GenMyCombiner::getMatchTable() const { // CHECK-NEXT: constexpr static uint8_t MatchTable0[] = { -// CHECK-NEXT: /* 0 */ GIM_SwitchOpcode, /*MI*/0, /*[*/GIMT_Encode2(105), GIMT_Encode2(217), /*)*//*default:*//*Label 5*/ GIMT_Encode4(524), +// CHECK-NEXT: /* 0 */ GIM_SwitchOpcode, /*MI*/0, /*[*/GIMT_Encode2(110), GIMT_Encode2(222), /*)*//*default:*//*Label 5*/ GIMT_Encode4(524), // CHECK-NEXT: /* 10 */ /*TargetOpcode::G_STORE*//*Label 0*/ GIMT_Encode4(458), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), // CHECK-NEXT: /* 182 */ /*TargetOpcode::G_SEXT*//*Label 1*/ GIMT_Encode4(476), GIMT_Encode4(0), // CHECK-NEXT: /* 190 */ /*TargetOpcode::G_ZEXT*//*Label 2*/ GIMT_Encode4(488), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), GIMT_Encode4(0), diff --git a/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td b/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td index 64ca63da3b6f0..b0b5746c32ad4 100644 --- a/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td +++ b/llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td @@ -535,7 +535,7 @@ def : Pat<(frag GPR32:$src1, complex:$src2, complex:$src3), // R00O-NEXT: GIM_Reject, // R00O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]] // R00O-NEXT: GIM_Reject, -// R00O-NEXT: }; // Size: 1918 bytes +// R00O-NEXT: }; // Size: 1938 bytes def INSNBOB : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3, GPR32:$src4), [(set GPR32:$dst, diff --git a/llvm/test/TableGen/get-named-operand-idx.td b/llvm/test/TableGen/get-named-operand-idx.td index 7982822c0a895..9bba98a62f10b 100644 --- a/llvm/test/TableGen/get-named-operand-idx.td +++ b/llvm/test/TableGen/get-named-operand-idx.td @@ -98,7 +98,7 @@ defm : RemapAllTargetPseudoPointerOperands; // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // CHECK-NEXT: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// CHECK-NEXT: 1, 2, 2, 0, +// CHECK-NEXT: 0, 0, 0, 0, 1, 2, 2, 0, // CHECK-NEXT: }; // CHECK-NEXT: return InstructionIndex[Opcode]; // CHECK-NEXT: } diff --git a/llvm/test/Transforms/GlobalOpt/global-constructor-complex-constants.ll b/llvm/test/Transforms/GlobalOpt/global-constructor-complex-constants.ll index 6d9bdc41a0041..12db77532f874 100644 --- a/llvm/test/Transforms/GlobalOpt/global-constructor-complex-constants.ll +++ b/llvm/test/Transforms/GlobalOpt/global-constructor-complex-constants.ll @@ -15,13 +15,13 @@ define void @ctor() { ; CHECK-LABEL: define void @ctor() { ; CHECK-NEXT: [[ENTRY:.*:]] ; CHECK-NEXT: [[DST:%.*]] = alloca ptr, align 8 -; CHECK-NEXT: store ptr ptrauth (ptr @foo, i32 0), ptr [[DST]], align 8 +; CHECK-NEXT: store ptr ptrauth (ptr @foo, [i64 0, i64 0, i64 0]), ptr [[DST]], align 8 ; CHECK-NEXT: call void @user(ptr [[DST]]) ; CHECK-NEXT: ret void ; entry: %dst = alloca ptr, align 8 - store ptr ptrauth (ptr @foo, i32 0), ptr %dst, align 8 + store ptr ptrauth (ptr @foo, [i64 0, i64 0, i64 0]), ptr %dst, align 8 call void @user(ptr %dst) ret void } diff --git a/llvm/test/Transforms/InstCombine/ptrauth-call.ll b/llvm/test/Transforms/InstCombine/ptrauth-call.ll index eefe593361c05..49a793e4e7fbf 100644 --- a/llvm/test/Transforms/InstCombine/ptrauth-call.ll +++ b/llvm/test/Transforms/InstCombine/ptrauth-call.ll @@ -9,7 +9,7 @@ define i32 @test_ptrauth_call(i32 %a0) { ; CHECK-NEXT: [[V0:%.*]] = call i32 @f(i32 [[A0:%.*]]) ; CHECK-NEXT: ret i32 [[V0]] ; - %v0 = call i32 ptrauth(ptr @f, i32 0)(i32 %a0) [ "ptrauth"(i32 0, i64 0) ] + %v0 = call i32 ptrauth(ptr @f, [i64 0, i64 0, i64 0])(i32 %a0) [ "ptrauth"(i64 0, i64 0, i64 0) ] ret i32 %v0 } @@ -18,30 +18,29 @@ define i32 @test_ptrauth_call_disc(i32 %a0) { ; CHECK-NEXT: [[V0:%.*]] = call i32 @f(i32 [[A0:%.*]]) ; CHECK-NEXT: ret i32 [[V0]] ; - %v0 = call i32 ptrauth(ptr @f, i32 1, i64 5678)(i32 %a0) [ "ptrauth"(i32 1, i64 5678) ] + %v0 = call i32 ptrauth(ptr @f, [i64 1, i64 5678, i64 0])(i32 %a0) [ "ptrauth"(i64 1, i64 5678, i64 0) ] ret i32 %v0 } -@f_addr_disc.ref = constant ptr ptrauth(ptr @f, i32 1, i64 0, ptr @f_addr_disc.ref) +@f_addr_disc.ref = constant ptr ptrauth(ptr @f, [i64 1, i64 0, i64 ptrtoint (ptr @f_addr_disc.ref to i64)]) define i32 @test_ptrauth_call_addr_disc(i32 %a0) { ; CHECK-LABEL: @test_ptrauth_call_addr_disc( ; CHECK-NEXT: [[V0:%.*]] = call i32 @f(i32 [[A0:%.*]]) ; CHECK-NEXT: ret i32 [[V0]] ; - %v0 = call i32 ptrauth(ptr @f, i32 1, i64 0, ptr @f_addr_disc.ref)(i32 %a0) [ "ptrauth"(i32 1, i64 ptrtoint (ptr @f_addr_disc.ref to i64)) ] + %v0 = call i32 ptrauth(ptr @f, [i64 1, i64 0, i64 ptrtoint (ptr @f_addr_disc.ref to i64)])(i32 %a0) [ "ptrauth"(i64 1, i64 0, i64 ptrtoint (ptr @f_addr_disc.ref to i64)) ] ret i32 %v0 } -@f_both_disc.ref = constant ptr ptrauth(ptr @f, i32 1, i64 1234, ptr @f_both_disc.ref) +@f_both_disc.ref = constant ptr ptrauth(ptr @f, [i64 1, i64 1234, i64 ptrtoint (ptr @f_both_disc.ref to i64)]) define i32 @test_ptrauth_call_blend(i32 %a0) { ; CHECK-LABEL: @test_ptrauth_call_blend( ; CHECK-NEXT: [[V0:%.*]] = call i32 @f(i32 [[A0:%.*]]) ; CHECK-NEXT: ret i32 [[V0]] ; - %v = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @f_both_disc.ref to i64), i64 1234) - %v0 = call i32 ptrauth(ptr @f, i32 1, i64 1234, ptr @f_both_disc.ref)(i32 %a0) [ "ptrauth"(i32 1, i64 %v) ] + %v0 = call i32 ptrauth(ptr @f, [i64 1, i64 1234, i64 ptrtoint (ptr @f_both_disc.ref to i64)])(i32 %a0) [ "ptrauth"(i64 1, i64 1234, i64 ptrtoint (ptr @f_both_disc.ref to i64)) ] ret i32 %v0 } @@ -50,48 +49,42 @@ define i64 @test_ptrauth_call_cast(i32 %a0) { ; CHECK-NEXT: [[V0:%.*]] = call i64 @f2(i32 [[A0:%.*]]) ; CHECK-NEXT: ret i64 [[V0]] ; - %v0 = call i64 ptrauth(ptr @f2, i32 0)(i32 %a0) [ "ptrauth"(i32 0, i64 0) ] + %v0 = call i64 ptrauth(ptr @f2, [i64 0, i64 0, i64 0])(i32 %a0) [ "ptrauth"(i64 0, i64 0, i64 0) ] ret i64 %v0 } define i32 @test_ptrauth_call_mismatch_key(i32 %a0) { ; CHECK-LABEL: @test_ptrauth_call_mismatch_key( -; CHECK-NEXT: [[V0:%.*]] = call i32 ptrauth (ptr @f, i32 1, i64 5678)(i32 [[A0:%.*]]) [ "ptrauth"(i32 0, i64 5678) ] +; CHECK-NEXT: [[V0:%.*]] = call i32 ptrauth (ptr @f, [i64 1, i64 5678, i64 0])(i32 [[A0:%.*]]) [ "ptrauth"(i64 0, i64 5678, i64 0) ] ; CHECK-NEXT: ret i32 [[V0]] ; - %v0 = call i32 ptrauth(ptr @f, i32 1, i64 5678)(i32 %a0) [ "ptrauth"(i32 0, i64 5678) ] + %v0 = call i32 ptrauth(ptr @f, [i64 1, i64 5678, i64 0])(i32 %a0) [ "ptrauth"(i64 0, i64 5678, i64 0) ] ret i32 %v0 } define i32 @test_ptrauth_call_mismatch_disc(i32 %a0) { ; CHECK-LABEL: @test_ptrauth_call_mismatch_disc( -; CHECK-NEXT: [[V0:%.*]] = call i32 ptrauth (ptr @f, i32 1, i64 5678)(i32 [[A0:%.*]]) [ "ptrauth"(i32 1, i64 0) ] +; CHECK-NEXT: [[V0:%.*]] = call i32 ptrauth (ptr @f, [i64 1, i64 5678, i64 0])(i32 [[A0:%.*]]) [ "ptrauth"(i64 1, i64 0, i64 0) ] ; CHECK-NEXT: ret i32 [[V0]] ; - %v0 = call i32 ptrauth(ptr @f, i32 1, i64 5678)(i32 %a0) [ "ptrauth"(i32 1, i64 0) ] + %v0 = call i32 ptrauth(ptr @f, [i64 1, i64 5678, i64 0])(i32 %a0) [ "ptrauth"(i64 1, i64 0, i64 0) ] ret i32 %v0 } define i32 @test_ptrauth_call_mismatch_blend(i32 %a0) { ; CHECK-LABEL: @test_ptrauth_call_mismatch_blend( -; CHECK-NEXT: [[V:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @f_both_disc.ref to i64), i64 0) -; CHECK-NEXT: [[V0:%.*]] = call i32 ptrauth (ptr @f, i32 1, i64 1234, ptr @f_both_disc.ref)(i32 [[A0:%.*]]) [ "ptrauth"(i32 1, i64 [[V]]) ] +; CHECK-NEXT: [[V0:%.*]] = call i32 ptrauth (ptr @f, [i64 1, i64 1234, i64 ptrtoint (ptr @f_both_disc.ref to i64)])(i32 [[A0:%.*]]) [ "ptrauth"(i64 1, i64 0, i64 ptrtoint (ptr @f_both_disc.ref to i64)) ] ; CHECK-NEXT: ret i32 [[V0]] ; - %v = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @f_both_disc.ref to i64), i64 0) - %v0 = call i32 ptrauth(ptr @f, i32 1, i64 1234, ptr @f_both_disc.ref)(i32 %a0) [ "ptrauth"(i32 1, i64 %v) ] + %v0 = call i32 ptrauth(ptr @f, [i64 1, i64 1234, i64 ptrtoint (ptr @f_both_disc.ref to i64)])(i32 %a0) [ "ptrauth"(i64 1, i64 0, i64 ptrtoint (ptr @f_both_disc.ref to i64)) ] ret i32 %v0 } define i32 @test_ptrauth_call_mismatch_blend_addr(i32 %a0) { ; CHECK-LABEL: @test_ptrauth_call_mismatch_blend_addr( -; CHECK-NEXT: [[V:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @f_addr_disc.ref to i64), i64 1234) -; CHECK-NEXT: [[V0:%.*]] = call i32 ptrauth (ptr @f, i32 1, i64 1234, ptr @f_both_disc.ref)(i32 [[A0:%.*]]) [ "ptrauth"(i32 1, i64 [[V]]) ] +; CHECK-NEXT: [[V0:%.*]] = call i32 ptrauth (ptr @f, [i64 1, i64 1234, i64 ptrtoint (ptr @f_both_disc.ref to i64)])(i32 [[A0:%.*]]) [ "ptrauth"(i64 1, i64 1234, i64 ptrtoint (ptr @f_addr_disc.ref to i64)) ] ; CHECK-NEXT: ret i32 [[V0]] ; - %v = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @f_addr_disc.ref to i64), i64 1234) - %v0 = call i32 ptrauth(ptr @f, i32 1, i64 1234, ptr @f_both_disc.ref)(i32 %a0) [ "ptrauth"(i32 1, i64 %v) ] + %v0 = call i32 ptrauth(ptr @f, [i64 1, i64 1234, i64 ptrtoint (ptr @f_both_disc.ref to i64)])(i32 %a0) [ "ptrauth"(i64 1, i64 1234, i64 ptrtoint (ptr @f_addr_disc.ref to i64)) ] ret i32 %v0 } - -declare i64 @llvm.ptrauth.blend(i64, i64) diff --git a/llvm/test/Transforms/InstCombine/ptrauth-intrinsics-call.ll b/llvm/test/Transforms/InstCombine/ptrauth-intrinsics-call.ll index 5e597c9155f40..18642461e6465 100644 --- a/llvm/test/Transforms/InstCombine/ptrauth-intrinsics-call.ll +++ b/llvm/test/Transforms/InstCombine/ptrauth-intrinsics-call.ll @@ -7,9 +7,9 @@ define i32 @test_ptrauth_call_sign(ptr %p) { ; CHECK-NEXT: ret i32 [[V3]] ; %v0 = ptrtoint ptr %p to i64 - %v1 = call i64 @llvm.ptrauth.sign(i64 %v0, i32 2, i64 5678) + %v1 = call i64 @llvm.ptrauth.sign(i64 %v0) [ "ptrauth"(i64 2, i64 5678) ] %v2 = inttoptr i64 %v1 to ptr - %v3 = call i32 %v2() [ "ptrauth"(i32 2, i64 5678) ] + %v3 = call i32 %v2() [ "ptrauth"(i64 2, i64 5678) ] ret i32 %v3 } @@ -19,37 +19,36 @@ define i32 @test_ptrauth_call_sign_otherbundle(ptr %p) { ; CHECK-NEXT: ret i32 [[V3]] ; %v0 = ptrtoint ptr %p to i64 - %v1 = call i64 @llvm.ptrauth.sign(i64 %v0, i32 2, i64 5678) + %v1 = call i64 @llvm.ptrauth.sign(i64 %v0) [ "ptrauth"(i64 2, i64 5678) ] %v2 = inttoptr i64 %v1 to ptr - %v3 = call i32 %v2() [ "somebundle"(ptr null), "ptrauth"(i32 2, i64 5678), "otherbundle"(i64 0) ] + %v3 = call i32 %v2() [ "somebundle"(ptr null), "ptrauth"(i64 2, i64 5678), "otherbundle"(i64 0) ] ret i32 %v3 } define i32 @test_ptrauth_call_resign(ptr %p) { ; CHECK-LABEL: @test_ptrauth_call_resign( -; CHECK-NEXT: [[V3:%.*]] = call i32 [[P:%.*]]() [ "ptrauth"(i32 1, i64 1234) ] +; CHECK-NEXT: [[V3:%.*]] = call i32 [[P:%.*]]() [ "ptrauth"(i64 1, i64 1234) ] ; CHECK-NEXT: ret i32 [[V3]] ; %v0 = ptrtoint ptr %p to i64 - %v1 = call i64 @llvm.ptrauth.resign(i64 %v0, i32 1, i64 1234, i32 1, i64 5678) + %v1 = call i64 @llvm.ptrauth.resign(i64 %v0) [ "ptrauth"(i64 1, i64 1234), "ptrauth"(i64 1, i64 5678) ] %v2 = inttoptr i64 %v1 to ptr - %v3 = call i32 %v2() [ "ptrauth"(i32 1, i64 5678) ] + %v3 = call i32 %v2() [ "ptrauth"(i64 1, i64 5678) ] ret i32 %v3 } define i32 @test_ptrauth_call_resign_blend(ptr %pp) { ; CHECK-LABEL: @test_ptrauth_call_resign_blend( ; CHECK-NEXT: [[V01:%.*]] = load ptr, ptr [[PP:%.*]], align 8 -; CHECK-NEXT: [[V6:%.*]] = call i32 [[V01]]() [ "ptrauth"(i32 1, i64 1234) ] +; CHECK-NEXT: [[V6:%.*]] = call i32 [[V01]]() [ "ptrauth"(i64 1, i64 1234) ] ; CHECK-NEXT: ret i32 [[V6]] ; %v0 = load ptr, ptr %pp, align 8 %v1 = ptrtoint ptr %pp to i64 %v2 = ptrtoint ptr %v0 to i64 - %v3 = call i64 @llvm.ptrauth.blend(i64 %v1, i64 5678) - %v4 = call i64 @llvm.ptrauth.resign(i64 %v2, i32 1, i64 1234, i32 1, i64 %v3) + %v4 = call i64 @llvm.ptrauth.resign(i64 %v2) [ "ptrauth"(i64 1, i64 1234), "ptrauth"(i64 1, i64 %v1, i64 5678) ] %v5 = inttoptr i64 %v4 to ptr - %v6 = call i32 %v5() [ "ptrauth"(i32 1, i64 %v3) ] + %v6 = call i32 %v5() [ "ptrauth"(i64 1, i64 %v1, i64 5678) ] ret i32 %v6 } @@ -57,47 +56,60 @@ define i32 @test_ptrauth_call_resign_blend_2(ptr %pp) { ; CHECK-LABEL: @test_ptrauth_call_resign_blend_2( ; CHECK-NEXT: [[V01:%.*]] = load ptr, ptr [[PP:%.*]], align 8 ; CHECK-NEXT: [[V1:%.*]] = ptrtoint ptr [[PP]] to i64 -; CHECK-NEXT: [[V3:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[V1]], i64 5678) -; CHECK-NEXT: [[V6:%.*]] = call i32 [[V01]]() [ "ptrauth"(i32 0, i64 [[V3]]) ] +; CHECK-NEXT: [[V6:%.*]] = call i32 [[V01]]() [ "ptrauth"(i64 0, i64 [[V1]], i64 5678) ] ; CHECK-NEXT: ret i32 [[V6]] ; %v0 = load ptr, ptr %pp, align 8 %v1 = ptrtoint ptr %pp to i64 %v2 = ptrtoint ptr %v0 to i64 - %v3 = call i64 @llvm.ptrauth.blend(i64 %v1, i64 5678) - %v4 = call i64 @llvm.ptrauth.resign(i64 %v2, i32 0, i64 %v3, i32 0, i64 1234) + %v4 = call i64 @llvm.ptrauth.resign(i64 %v2) [ "ptrauth"(i64 0, i64 %v1, i64 5678), "ptrauth"(i64 0, i64 1234) ] %v5 = inttoptr i64 %v4 to ptr - %v6 = call i32 %v5() [ "ptrauth"(i32 0, i64 1234) ] + %v6 = call i32 %v5() [ "ptrauth"(i64 0, i64 1234) ] + ret i32 %v6 +} + +define i32 @test_ptrauth_call_resign_long_bundle_ops(ptr %pp) { +; CHECK-LABEL: @test_ptrauth_call_resign_long_bundle_ops( +; CHECK-NEXT: [[V01:%.*]] = load ptr, ptr [[PP:%.*]], align 8 +; CHECK-NEXT: [[V6:%.*]] = call i32 [[V01]]() [ "ptrauth"(i64 1, i64 1234) ] +; CHECK-NEXT: ret i32 [[V6]] +; + %v0 = load ptr, ptr %pp, align 8 + %v1 = ptrtoint ptr %pp to i64 + %v2 = ptrtoint ptr %v0 to i64 + %v4 = call i64 @llvm.ptrauth.resign(i64 %v2) [ "ptrauth"(i64 1, i64 1234), "ptrauth"(i64 1, i64 %v1, i64 5678, i64 %v2, i64 123) ] + %v5 = inttoptr i64 %v4 to ptr + %v6 = call i32 %v5() [ "ptrauth"(i64 1, i64 %v1, i64 5678, i64 %v2, i64 123) ] ret i32 %v6 } define i32 @test_ptrauth_call_resign_mismatch_key(ptr %p) { ; CHECK-LABEL: @test_ptrauth_call_resign_mismatch_key( ; CHECK-NEXT: [[V0:%.*]] = ptrtoint ptr [[P:%.*]] to i64 -; CHECK-NEXT: [[V1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[V0]], i32 1, i64 1234, i32 0, i64 5678) +; CHECK-NEXT: [[V1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[V0]]) [ "ptrauth"(i64 1, i64 1234), "ptrauth"(i64 0, i64 5678) ] ; CHECK-NEXT: [[V2:%.*]] = inttoptr i64 [[V1]] to ptr -; CHECK-NEXT: [[V3:%.*]] = call i32 [[V2]]() [ "ptrauth"(i32 1, i64 5678) ] +; CHECK-NEXT: [[V3:%.*]] = call i32 [[V2]]() [ "ptrauth"(i64 1, i64 5678) ] ; CHECK-NEXT: ret i32 [[V3]] ; %v0 = ptrtoint ptr %p to i64 - %v1 = call i64 @llvm.ptrauth.resign(i64 %v0, i32 1, i64 1234, i32 0, i64 5678) + %v1 = call i64 @llvm.ptrauth.resign(i64 %v0) [ "ptrauth"(i64 1, i64 1234), "ptrauth"(i64 0, i64 5678) ] %v2 = inttoptr i64 %v1 to ptr - %v3 = call i32 %v2() [ "ptrauth"(i32 1, i64 5678) ] + %v3 = call i32 %v2() [ "ptrauth"(i64 1, i64 5678) ] ret i32 %v3 } define i32 @test_ptrauth_call_resign_mismatch_disc(ptr %p) { ; CHECK-LABEL: @test_ptrauth_call_resign_mismatch_disc( ; CHECK-NEXT: [[V0:%.*]] = ptrtoint ptr [[P:%.*]] to i64 -; CHECK-NEXT: [[V1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[V0]], i32 1, i64 1234, i32 0, i64 9900) +; CHECK-NEXT: [[V1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[V0]]) [ "ptrauth"(i64 1, i64 1234), "ptrauth"(i64 0, i64 9900) ] ; CHECK-NEXT: [[V2:%.*]] = inttoptr i64 [[V1]] to ptr -; CHECK-NEXT: [[V3:%.*]] = call i32 [[V2]]() [ "ptrauth"(i32 1, i64 5678) ] +; CHECK-NEXT: [[V3:%.*]] = call i32 [[V2]]() [ "ptrauth"(i64 1, i64 5678) ] ; CHECK-NEXT: ret i32 [[V3]] ; %v0 = ptrtoint ptr %p to i64 - %v1 = call i64 @llvm.ptrauth.resign(i64 %v0, i32 1, i64 1234, i32 0, i64 9900) + %v1 = call i64 @llvm.ptrauth.resign(i64 %v0) [ "ptrauth"(i64 1, i64 1234), "ptrauth"(i64 0, i64 9900) ] %v2 = inttoptr i64 %v1 to ptr - %v3 = call i32 %v2() [ "ptrauth"(i32 1, i64 5678) ] + %v3 = call i32 %v2() [ "ptrauth"(i64 1, i64 5678) ] ret i32 %v3 } @@ -106,37 +118,47 @@ define i32 @test_ptrauth_call_resign_mismatch_blend(ptr %pp) { ; CHECK-NEXT: [[V0:%.*]] = load ptr, ptr [[PP:%.*]], align 8 ; CHECK-NEXT: [[V1:%.*]] = ptrtoint ptr [[PP]] to i64 ; CHECK-NEXT: [[V2:%.*]] = ptrtoint ptr [[V0]] to i64 -; CHECK-NEXT: [[V6:%.*]] = call i64 @llvm.ptrauth.blend(i64 [[V1]], i64 5678) -; CHECK-NEXT: [[V4:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[V2]], i32 1, i64 1234, i32 1, i64 [[V6]]) +; CHECK-NEXT: [[V4:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[V2]]) [ "ptrauth"(i64 1, i64 1234), "ptrauth"(i64 1, i64 [[V1]], i64 5678) ] +; CHECK-NEXT: [[V5:%.*]] = inttoptr i64 [[V4]] to ptr +; CHECK-NEXT: [[V3:%.*]] = call i32 [[V5]]() [ "ptrauth"(i64 1, i64 [[V1]]) ] +; CHECK-NEXT: ret i32 [[V3]] +; + %v0 = load ptr, ptr %pp, align 8 + %v1 = ptrtoint ptr %pp to i64 + %v2 = ptrtoint ptr %v0 to i64 + %v4 = call i64 @llvm.ptrauth.resign(i64 %v2) [ "ptrauth"(i64 1, i64 1234), "ptrauth"(i64 1, i64 %v1, i64 5678) ] + %v5 = inttoptr i64 %v4 to ptr + %v6 = call i32 %v5() [ "ptrauth"(i64 1, i64 %v1) ] + ret i32 %v6 +} + +define i32 @test_ptrauth_call_resign_long_bundle_ops_mismatch(ptr %pp) { +; CHECK-LABEL: @test_ptrauth_call_resign_long_bundle_ops_mismatch( +; CHECK-NEXT: [[V0:%.*]] = load ptr, ptr [[PP:%.*]], align 8 +; CHECK-NEXT: [[V1:%.*]] = ptrtoint ptr [[PP]] to i64 +; CHECK-NEXT: [[V2:%.*]] = ptrtoint ptr [[V0]] to i64 +; CHECK-NEXT: [[V4:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[V2]]) [ "ptrauth"(i64 1, i64 1234), "ptrauth"(i64 1, i64 [[V1]], i64 5678, i64 [[V1]], i64 123) ] ; CHECK-NEXT: [[V5:%.*]] = inttoptr i64 [[V4]] to ptr -; CHECK-NEXT: [[V3:%.*]] = call i32 [[V5]]() [ "ptrauth"(i32 1, i64 [[V1]]) ] +; CHECK-NEXT: [[V3:%.*]] = call i32 [[V5]]() [ "ptrauth"(i64 1, i64 [[V1]], i64 [[V2]], i64 123) ] ; CHECK-NEXT: ret i32 [[V3]] ; %v0 = load ptr, ptr %pp, align 8 %v1 = ptrtoint ptr %pp to i64 %v2 = ptrtoint ptr %v0 to i64 - %v3 = call i64 @llvm.ptrauth.blend(i64 %v1, i64 5678) - %v4 = call i64 @llvm.ptrauth.resign(i64 %v2, i32 1, i64 1234, i32 1, i64 %v3) + %v4 = call i64 @llvm.ptrauth.resign(i64 %v2) [ "ptrauth"(i64 1, i64 1234), "ptrauth"(i64 1, i64 %v1, i64 5678, i64 %v1, i64 123) ] %v5 = inttoptr i64 %v4 to ptr - %v6 = call i32 %v5() [ "ptrauth"(i32 1, i64 %v1) ] + %v6 = call i32 %v5() [ "ptrauth"(i64 1, i64 %v1, i64 %v2, i64 123) ] ret i32 %v6 } define i32 @test_ptrauth_call_resign_changing_call_key(ptr %p) { ; CHECK-LABEL: @test_ptrauth_call_resign_changing_call_key( -; CHECK-NEXT: [[V0:%.*]] = ptrtoint ptr [[P:%.*]] to i64 -; CHECK-NEXT: [[V1:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[V0]], i32 2, i64 1234, i32 1, i64 5678) -; CHECK-NEXT: [[V2:%.*]] = inttoptr i64 [[V1]] to ptr -; CHECK-NEXT: [[V3:%.*]] = call i32 [[V2]]() [ "ptrauth"(i32 1, i64 5678) ] +; CHECK-NEXT: [[V3:%.*]] = call i32 [[P:%.*]]() [ "ptrauth"(i64 2, i64 1234) ] ; CHECK-NEXT: ret i32 [[V3]] ; %v0 = ptrtoint ptr %p to i64 - %v1 = call i64 @llvm.ptrauth.resign(i64 %v0, i32 2, i64 1234, i32 1, i64 5678) + %v1 = call i64 @llvm.ptrauth.resign(i64 %v0) [ "ptrauth"(i64 2, i64 1234), "ptrauth"(i64 1, i64 5678) ] %v2 = inttoptr i64 %v1 to ptr - %v3 = call i32 %v2() [ "ptrauth"(i32 1, i64 5678) ] + %v3 = call i32 %v2() [ "ptrauth"(i64 1, i64 5678) ] ret i32 %v3 } - -declare i64 @llvm.ptrauth.sign(i64, i32, i64) -declare i64 @llvm.ptrauth.resign(i64, i32, i64, i32, i64) -declare i64 @llvm.ptrauth.blend(i64, i64) diff --git a/llvm/test/Transforms/InstCombine/ptrauth-intrinsics.ll b/llvm/test/Transforms/InstCombine/ptrauth-intrinsics.ll index 22c330fe7ae61..d33ee4b3df20d 100644 --- a/llvm/test/Transforms/InstCombine/ptrauth-intrinsics.ll +++ b/llvm/test/Transforms/InstCombine/ptrauth-intrinsics.ll @@ -7,8 +7,19 @@ define i64 @test_ptrauth_nop(ptr %p) { ; CHECK-NEXT: ret i64 [[TMP0]] ; %tmp0 = ptrtoint ptr %p to i64 - %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0, i32 1, i64 1234) - %authed = call i64 @llvm.ptrauth.auth(i64 %signed, i32 1, i64 1234) + %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0) [ "ptrauth"(i64 1, i64 1234, i64 0) ] + %authed = call i64 @llvm.ptrauth.auth(i64 %signed) [ "ptrauth"(i64 1, i64 1234, i64 0) ] + ret i64 %authed +} + +define i64 @test_ptrauth_nop_long_bundle_ops(ptr %p) { +; CHECK-LABEL: @test_ptrauth_nop_long_bundle_ops( +; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[P:%.*]] to i64 +; CHECK-NEXT: ret i64 [[TMP0]] +; + %tmp0 = ptrtoint ptr %p to i64 + %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0) [ "ptrauth"(i64 1, i64 1234, i64 0, i64 42, i64 %tmp0) ] + %authed = call i64 @llvm.ptrauth.auth(i64 %signed) [ "ptrauth"(i64 1, i64 1234, i64 0, i64 42, i64 %tmp0) ] ret i64 %authed } @@ -19,7 +30,7 @@ define i64 @test_ptrauth_nop_constant() { ; CHECK-LABEL: @test_ptrauth_nop_constant( ; CHECK-NEXT: ret i64 ptrtoint (ptr @foo to i64) ; - %authed = call i64 @llvm.ptrauth.auth(i64 ptrtoint(ptr ptrauth(ptr @foo, i32 1, i64 1234) to i64), i32 1, i64 1234) + %authed = call i64 @llvm.ptrauth.auth(i64 ptrtoint(ptr ptrauth(ptr @foo, [i64 1, i64 1234, i64 0]) to i64)) [ "ptrauth"(i64 1, i64 1234, i64 0) ] ret i64 %authed } @@ -28,135 +39,143 @@ define i64 @test_ptrauth_nop_constant_addrdisc() { ; CHECK-NEXT: ret i64 ptrtoint (ptr @foo to i64) ; %addr = ptrtoint ptr @foo to i64 - %blended = call i64 @llvm.ptrauth.blend(i64 %addr, i64 1234) - %authed = call i64 @llvm.ptrauth.auth(i64 ptrtoint(ptr ptrauth(ptr @foo, i32 1, i64 1234, ptr @foo) to i64), i32 1, i64 %blended) + %authed = call i64 @llvm.ptrauth.auth(i64 ptrtoint(ptr ptrauth(ptr @foo, [i64 1, i64 1234, i64 ptrtoint (ptr @foo to i64)]) to i64)) [ "ptrauth"(i64 1, i64 1234, i64 %addr) ] ret i64 %authed } define i64 @test_ptrauth_nop_mismatch(ptr %p) { ; CHECK-LABEL: @test_ptrauth_nop_mismatch( ; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[P:%.*]] to i64 -; CHECK-NEXT: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[TMP0]], i32 1, i64 1234) -; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED]], i32 1, i64 10) +; CHECK-NEXT: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[TMP0]]) [ "ptrauth"(i64 1, i64 1234, i64 0) ] +; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED]]) [ "ptrauth"(i64 1, i64 10, i64 0) ] ; CHECK-NEXT: ret i64 [[AUTHED]] ; %tmp0 = ptrtoint ptr %p to i64 - %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0, i32 1, i64 1234) - %authed = call i64 @llvm.ptrauth.auth(i64 %signed, i32 1, i64 10) + %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0) [ "ptrauth"(i64 1, i64 1234, i64 0) ] + %authed = call i64 @llvm.ptrauth.auth(i64 %signed) [ "ptrauth"(i64 1, i64 10, i64 0) ] ret i64 %authed } define i64 @test_ptrauth_nop_mismatch_keys(ptr %p) { ; CHECK-LABEL: @test_ptrauth_nop_mismatch_keys( ; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[P:%.*]] to i64 -; CHECK-NEXT: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[TMP0]], i32 0, i64 1234) -; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED]], i32 1, i64 1234) +; CHECK-NEXT: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[TMP0]]) [ "ptrauth"(i64 0, i64 1234, i64 0) ] +; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED]]) [ "ptrauth"(i64 1, i64 1234, i64 0) ] ; CHECK-NEXT: ret i64 [[AUTHED]] ; %tmp0 = ptrtoint ptr %p to i64 - %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0, i32 0, i64 1234) - %authed = call i64 @llvm.ptrauth.auth(i64 %signed, i32 1, i64 1234) + %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0) [ "ptrauth"(i64 0, i64 1234, i64 0) ] + %authed = call i64 @llvm.ptrauth.auth(i64 %signed) [ "ptrauth"(i64 1, i64 1234, i64 0) ] + ret i64 %authed +} + +define i64 @test_ptrauth_nop_long_bundle_ops_mismatch(ptr %p) { +; CHECK-LABEL: @test_ptrauth_nop_long_bundle_ops_mismatch( +; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[P:%.*]] to i64 +; CHECK-NEXT: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[TMP0]]) [ "ptrauth"(i64 1, i64 1234, i64 0, i64 42, i64 [[TMP0]]) ] +; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED]]) [ "ptrauth"(i64 1, i64 1234, i64 0, i64 42, i64 123) ] +; CHECK-NEXT: ret i64 [[AUTHED]] +; + %tmp0 = ptrtoint ptr %p to i64 + %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0) [ "ptrauth"(i64 1, i64 1234, i64 0, i64 42, i64 %tmp0) ] + %authed = call i64 @llvm.ptrauth.auth(i64 %signed) [ "ptrauth"(i64 1, i64 1234, i64 0, i64 42, i64 123) ] ret i64 %authed } define i64 @test_ptrauth_sign_resign(ptr %p) { ; CHECK-LABEL: @test_ptrauth_sign_resign( ; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[P:%.*]] to i64 -; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[TMP0]], i32 0, i64 42) +; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[TMP0]]) [ "ptrauth"(i64 0, i64 42, i64 0) ] ; CHECK-NEXT: ret i64 [[AUTHED]] ; %tmp0 = ptrtoint ptr %p to i64 - %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0, i32 1, i64 1234) - %authed = call i64 @llvm.ptrauth.resign(i64 %signed, i32 1, i64 1234, i32 0, i64 42) + %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0) [ "ptrauth"(i64 1, i64 1234, i64 0, i64 42, i64 %tmp0) ] + %authed = call i64 @llvm.ptrauth.resign(i64 %signed) [ "ptrauth"(i64 1, i64 1234, i64 0, i64 42, i64 %tmp0), "ptrauth"(i64 0, i64 42, i64 0) ] ret i64 %authed } define i64 @test_ptrauth_resign_resign(ptr %p) { ; CHECK-LABEL: @test_ptrauth_resign_resign( ; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[P:%.*]] to i64 -; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[TMP0]], i32 1, i64 1234, i32 1, i64 3141) +; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[TMP0]]) [ "ptrauth"(i64 1, i64 1234, i64 0), "ptrauth"(i64 1, i64 3141, i64 0) ] ; CHECK-NEXT: ret i64 [[AUTHED]] ; %tmp0 = ptrtoint ptr %p to i64 - %signed = call i64 @llvm.ptrauth.resign(i64 %tmp0, i32 1, i64 1234, i32 0, i64 42) - %authed = call i64 @llvm.ptrauth.resign(i64 %signed, i32 0, i64 42, i32 1, i64 3141) + %signed = call i64 @llvm.ptrauth.resign(i64 %tmp0) [ "ptrauth"(i64 1, i64 1234, i64 0), "ptrauth"(i64 0, i64 42, i64 0, i64 42, i64 %tmp0) ] + %authed = call i64 @llvm.ptrauth.resign(i64 %signed) [ "ptrauth"(i64 0, i64 42, i64 0, i64 42, i64 %tmp0), "ptrauth"(i64 1, i64 3141, i64 0) ] ret i64 %authed } define i64 @test_ptrauth_resign_auth(ptr %p) { ; CHECK-LABEL: @test_ptrauth_resign_auth( ; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[P:%.*]] to i64 -; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP0]], i32 1, i64 1234) +; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[TMP0]]) [ "ptrauth"(i64 1, i64 1234, i64 0) ] ; CHECK-NEXT: ret i64 [[AUTHED]] ; %tmp0 = ptrtoint ptr %p to i64 - %signed = call i64 @llvm.ptrauth.resign(i64 %tmp0, i32 1, i64 1234, i32 0, i64 42) - %authed = call i64 @llvm.ptrauth.auth(i64 %signed, i32 0, i64 42) + %signed = call i64 @llvm.ptrauth.resign(i64 %tmp0) [ "ptrauth"(i64 1, i64 1234, i64 0), "ptrauth"(i64 0, i64 42, i64 0, i64 42, i64 %tmp0) ] + %authed = call i64 @llvm.ptrauth.auth(i64 %signed) [ "ptrauth"(i64 0, i64 42, i64 0, i64 42, i64 %tmp0) ] ret i64 %authed } define i64 @test_ptrauth_resign_auth_mismatch(ptr %p) { ; CHECK-LABEL: @test_ptrauth_resign_auth_mismatch( ; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[P:%.*]] to i64 -; CHECK-NEXT: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[TMP0]], i32 1, i64 1234, i32 0, i64 10) -; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED]], i32 0, i64 42) +; CHECK-NEXT: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.resign(i64 [[TMP0]]) [ "ptrauth"(i64 1, i64 1234, i64 0), "ptrauth"(i64 0, i64 10, i64 0, i64 42, i64 [[TMP0]]) ] +; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED]]) [ "ptrauth"(i64 0, i64 42, i64 0, i64 123, i64 [[TMP0]]) ] ; CHECK-NEXT: ret i64 [[AUTHED]] ; %tmp0 = ptrtoint ptr %p to i64 - %signed = call i64 @llvm.ptrauth.resign(i64 %tmp0, i32 1, i64 1234, i32 0, i64 10) - %authed = call i64 @llvm.ptrauth.auth(i64 %signed, i32 0, i64 42) + %signed = call i64 @llvm.ptrauth.resign(i64 %tmp0) [ "ptrauth"(i64 1, i64 1234, i64 0), "ptrauth"(i64 0, i64 10, i64 0, i64 42, i64 %tmp0) ] + %authed = call i64 @llvm.ptrauth.auth(i64 %signed) [ "ptrauth"(i64 0, i64 42, i64 0, i64 123, i64 %tmp0) ] ret i64 %authed } define i64 @test_ptrauth_nop_constant_mismatch() { ; CHECK-LABEL: @test_ptrauth_nop_constant_mismatch( -; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 ptrtoint (ptr ptrauth (ptr @foo, i32 1, i64 1234) to i64), i32 1, i64 12) +; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 ptrtoint (ptr ptrauth (ptr @foo, [i64 1, i64 1234, i64 0]) to i64)) [ "ptrauth"(i64 1, i64 12, i64 0) ] ; CHECK-NEXT: ret i64 [[AUTHED]] ; - %authed = call i64 @llvm.ptrauth.auth(i64 ptrtoint(ptr ptrauth(ptr @foo, i32 1, i64 1234) to i64), i32 1, i64 12) + %authed = call i64 @llvm.ptrauth.auth(i64 ptrtoint(ptr ptrauth(ptr @foo, [i64 1, i64 1234, i64 0]) to i64)) [ "ptrauth"(i64 1, i64 12, i64 0) ] ret i64 %authed } define i64 @test_ptrauth_nop_constant_mismatch_key() { ; CHECK-LABEL: @test_ptrauth_nop_constant_mismatch_key( -; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 ptrtoint (ptr ptrauth (ptr @foo, i32 1, i64 1234) to i64), i32 0, i64 1234) +; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 ptrtoint (ptr ptrauth (ptr @foo, [i64 1, i64 1234, i64 0]) to i64)) [ "ptrauth"(i64 0, i64 1234, i64 0) ] ; CHECK-NEXT: ret i64 [[AUTHED]] ; - %authed = call i64 @llvm.ptrauth.auth(i64 ptrtoint(ptr ptrauth(ptr @foo, i32 1, i64 1234) to i64), i32 0, i64 1234) + %authed = call i64 @llvm.ptrauth.auth(i64 ptrtoint(ptr ptrauth(ptr @foo, [i64 1, i64 1234, i64 0]) to i64)) [ "ptrauth"(i64 0, i64 1234, i64 0) ] ret i64 %authed } define i64 @test_ptrauth_nop_constant_addrdisc_mismatch() { ; CHECK-LABEL: @test_ptrauth_nop_constant_addrdisc_mismatch( -; CHECK-NEXT: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @foo to i64), i64 12) -; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 ptrtoint (ptr ptrauth (ptr @foo, i32 1, i64 1234, ptr @foo) to i64), i32 1, i64 [[BLENDED]]) +; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 ptrtoint (ptr ptrauth (ptr @foo, [i64 1, i64 1234, i64 ptrtoint (ptr @foo to i64)]) to i64)) [ "ptrauth"(i64 1, i64 12, i64 ptrtoint (ptr @foo to i64)) ] ; CHECK-NEXT: ret i64 [[AUTHED]] ; %addr = ptrtoint ptr @foo to i64 - %blended = call i64 @llvm.ptrauth.blend(i64 %addr, i64 12) - %authed = call i64 @llvm.ptrauth.auth(i64 ptrtoint(ptr ptrauth(ptr @foo, i32 1, i64 1234, ptr @foo) to i64), i32 1, i64 %blended) + %authed = call i64 @llvm.ptrauth.auth(i64 ptrtoint(ptr ptrauth(ptr @foo, [i64 1, i64 1234, i64 ptrtoint (ptr @foo to i64)]) to i64)) [ "ptrauth"(i64 1, i64 12, i64 %addr) ] ret i64 %authed } define i64 @test_ptrauth_nop_constant_addrdisc_mismatch2() { ; CHECK-LABEL: @test_ptrauth_nop_constant_addrdisc_mismatch2( -; CHECK-NEXT: [[BLENDED:%.*]] = call i64 @llvm.ptrauth.blend(i64 ptrtoint (ptr @bar to i64), i64 1234) -; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 ptrtoint (ptr ptrauth (ptr @foo, i32 1, i64 1234, ptr @foo) to i64), i32 1, i64 [[BLENDED]]) +; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 ptrtoint (ptr ptrauth (ptr @foo, [i64 1, i64 1234, i64 ptrtoint (ptr @foo to i64)]) to i64)) [ "ptrauth"(i64 1, i64 1234, i64 ptrtoint (ptr @bar to i64)) ] ; CHECK-NEXT: ret i64 [[AUTHED]] ; %addr = ptrtoint ptr @bar to i64 - %blended = call i64 @llvm.ptrauth.blend(i64 %addr, i64 1234) - %authed = call i64 @llvm.ptrauth.auth(i64 ptrtoint(ptr ptrauth(ptr @foo, i32 1, i64 1234, ptr @foo) to i64), i32 1, i64 %blended) + %authed = call i64 @llvm.ptrauth.auth(i64 ptrtoint(ptr ptrauth(ptr @foo, [i64 1, i64 1234, i64 ptrtoint (ptr @foo to i64)]) to i64)) [ "ptrauth"(i64 1, i64 1234, i64 %addr) ] ret i64 %authed } define i64 @test_ptrauth_resign_ptrauth_constant(ptr %p) { ; CHECK-LABEL: @test_ptrauth_resign_ptrauth_constant( -; CHECK-NEXT: ret i64 ptrtoint (ptr ptrauth (ptr @foo, i32 0, i64 42) to i64) +; CHECK-NEXT: ret i64 ptrtoint (ptr ptrauth (ptr @foo, [i64 0, i64 42, i64 0]) to i64) ; %tmp0 = ptrtoint ptr %p to i64 - %authed = call i64 @llvm.ptrauth.resign(i64 ptrtoint(ptr ptrauth(ptr @foo, i32 1, i64 1234) to i64), i32 1, i64 1234, i32 0, i64 42) + %authed = call i64 @llvm.ptrauth.resign(i64 ptrtoint(ptr ptrauth(ptr @foo, [i64 1, i64 1234, i64 0]) to i64)) [ "ptrauth"(i64 1, i64 1234, i64 0), "ptrauth"(i64 0, i64 42, i64 0) ] ret i64 %authed } @@ -165,39 +184,34 @@ define i64 @test_ptrauth_resign_ptrauth_constant(ptr %p) { define i64 @test_ptrauth_nop_ds1(ptr %p) { ; CHECK-LABEL: @test_ptrauth_nop_ds1( ; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[P:%.*]] to i64 -; CHECK-NEXT: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[TMP0]], i32 1, i64 1234) [ "deactivation-symbol"(ptr @ds) ] -; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED]], i32 1, i64 1234) +; CHECK-NEXT: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[TMP0]]) [ "ptrauth"(i64 1, i64 1234), "deactivation-symbol"(ptr @ds) ] +; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED]]) [ "ptrauth"(i64 1, i64 1234) ] ; CHECK-NEXT: ret i64 [[AUTHED]] ; %tmp0 = ptrtoint ptr %p to i64 - %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0, i32 1, i64 1234) [ "deactivation-symbol"(ptr @ds) ] - %authed = call i64 @llvm.ptrauth.auth(i64 %signed, i32 1, i64 1234) + %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0) [ "ptrauth"(i64 1, i64 1234), "deactivation-symbol"(ptr @ds) ] + %authed = call i64 @llvm.ptrauth.auth(i64 %signed) [ "ptrauth"(i64 1, i64 1234) ] ret i64 %authed } define i64 @test_ptrauth_nop_ds2(ptr %p) { ; CHECK-LABEL: @test_ptrauth_nop_ds2( ; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[P:%.*]] to i64 -; CHECK-NEXT: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[TMP0]], i32 1, i64 1234) -; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED]], i32 1, i64 1234) [ "deactivation-symbol"(ptr @ds) ] +; CHECK-NEXT: [[SIGNED:%.*]] = call i64 @llvm.ptrauth.sign(i64 [[TMP0]]) [ "ptrauth"(i64 1, i64 1234) ] +; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 [[SIGNED]]) [ "ptrauth"(i64 1, i64 1234), "deactivation-symbol"(ptr @ds) ] ; CHECK-NEXT: ret i64 [[AUTHED]] ; %tmp0 = ptrtoint ptr %p to i64 - %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0, i32 1, i64 1234) - %authed = call i64 @llvm.ptrauth.auth(i64 %signed, i32 1, i64 1234) [ "deactivation-symbol"(ptr @ds) ] + %signed = call i64 @llvm.ptrauth.sign(i64 %tmp0) [ "ptrauth"(i64 1, i64 1234) ] + %authed = call i64 @llvm.ptrauth.auth(i64 %signed) [ "ptrauth"(i64 1, i64 1234), "deactivation-symbol"(ptr @ds) ] ret i64 %authed } define i64 @test_ptrauth_nop_ds_constant() { ; CHECK-LABEL: @test_ptrauth_nop_ds_constant( -; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 ptrtoint (ptr ptrauth (ptr @foo, i32 1, i64 1234, ptr null, ptr @ds) to i64), i32 1, i64 1234) +; CHECK-NEXT: [[AUTHED:%.*]] = call i64 @llvm.ptrauth.auth(i64 ptrtoint (ptr ptrauth (ptr @foo, [i64 1, i64 1234, i64 0], ptr @ds) to i64)) [ "ptrauth"(i64 1, i64 1234) ] ; CHECK-NEXT: ret i64 [[AUTHED]] ; - %authed = call i64 @llvm.ptrauth.auth(i64 ptrtoint(ptr ptrauth(ptr @foo, i32 1, i64 1234, ptr null, ptr @ds) to i64), i32 1, i64 1234) + %authed = call i64 @llvm.ptrauth.auth(i64 ptrtoint(ptr ptrauth(ptr @foo, [i64 1, i64 1234, i64 0], ptr @ds) to i64)) [ "ptrauth"(i64 1, i64 1234) ] ret i64 %authed } - -declare i64 @llvm.ptrauth.auth(i64, i32, i64) -declare i64 @llvm.ptrauth.sign(i64, i32, i64) -declare i64 @llvm.ptrauth.resign(i64, i32, i64, i32, i64) -declare i64 @llvm.ptrauth.blend(i64, i64) diff --git a/llvm/test/Transforms/TailCallElim/ptrauth-bundle.ll b/llvm/test/Transforms/TailCallElim/ptrauth-bundle.ll index 0228d3d371333..6b0e75852e51d 100644 --- a/llvm/test/Transforms/TailCallElim/ptrauth-bundle.ll +++ b/llvm/test/Transforms/TailCallElim/ptrauth-bundle.ll @@ -4,7 +4,7 @@ define i64 @f_1(i64 %x, ptr %f_0) { ; CHECK-LABEL: @f_1( entry: -; CHECK: tail call i64 %f_0(i64 %x) [ "ptrauth"(i32 42, i64 %x) ] - %tmp = call i64 %f_0(i64 %x) [ "ptrauth"(i32 42, i64 %x) ] +; CHECK: tail call i64 %f_0(i64 %x) [ "ptrauth"(i64 42, i64 %x) ] + %tmp = call i64 %f_0(i64 %x) [ "ptrauth"(i64 42, i64 %x) ] ret i64 0 } diff --git a/llvm/test/Transforms/WholeProgramDevirt/devirt-single-impl-check-ptrauth.ll b/llvm/test/Transforms/WholeProgramDevirt/devirt-single-impl-check-ptrauth.ll index b7a90d91ad96b..4ba1fb8893b86 100644 --- a/llvm/test/Transforms/WholeProgramDevirt/devirt-single-impl-check-ptrauth.ll +++ b/llvm/test/Transforms/WholeProgramDevirt/devirt-single-impl-check-ptrauth.ll @@ -25,7 +25,7 @@ define void @call(ptr %obj) { cont: ; CHECK: call void @vf( - call void %fptr(ptr %obj) [ "ptrauth"(i32 5, i64 120) ] + call void %fptr(ptr %obj) [ "ptrauth"(i64 5, i64 120) ] ret void trap: diff --git a/llvm/test/Verifier/operand-bundles.ll b/llvm/test/Verifier/operand-bundles.ll index db85b6ae6ef5f..de57a3a2a7213 100644 --- a/llvm/test/Verifier/operand-bundles.ll +++ b/llvm/test/Verifier/operand-bundles.ll @@ -66,8 +66,7 @@ define void @f_gc_transition(ptr %ptr) { } define void @f_clang_arc_attachedcall() { -; CHECK: requires one function as an argument -; CHECK-NEXT: call ptr @foo0() [ "clang.arc.attachedcall"() ] +; CHECK-NOT: requires one function as an argument ; CHECK-NEXT: Multiple "clang.arc.attachedcall" operand bundles ; CHECK-NEXT: call ptr @foo0() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue), "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] ; CHECK-NEXT: must call a function returning a pointer diff --git a/llvm/test/Verifier/ptrauth-constant.ll b/llvm/test/Verifier/ptrauth-constant.ll index 7a6d9d2634bc8..915bf2e6c7fcd 100644 --- a/llvm/test/Verifier/ptrauth-constant.ll +++ b/llvm/test/Verifier/ptrauth-constant.ll @@ -2,5 +2,5 @@ @g = external global i8 -; CHECK: signed ptrauth constant deactivation symbol must be a global value or null -@ptr = global ptr ptrauth (ptr @g, i32 0, i64 65535, ptr null, ptr inttoptr (i64 16 to ptr)) +; CHECK: ptrauth constant deactivation symbol must be a global value or null +@ptr = global ptr ptrauth (ptr @g, [i64 0, i64 65535, i64 0], ptr inttoptr (i64 16 to ptr)) diff --git a/llvm/test/Verifier/ptrauth-operand-bundles.ll b/llvm/test/Verifier/ptrauth-operand-bundles.ll index 7aa5a22f7816f..e67ab23809cde 100644 --- a/llvm/test/Verifier/ptrauth-operand-bundles.ll +++ b/llvm/test/Verifier/ptrauth-operand-bundles.ll @@ -2,30 +2,87 @@ declare void @g() -define void @test_ptrauth_bundle(i64 %arg0, i32 %arg1, ptr %arg2) { +define void @test_ptrauth_bundle(i64 %arg.64, ptr %arg.ptr, ptr %ok) { -; CHECK: Multiple ptrauth operand bundles -; CHECK-NEXT: call void %arg2() [ "ptrauth"(i32 42, i64 100), "ptrauth"(i32 42, i64 %arg0) ] - call void %arg2() [ "ptrauth"(i32 42, i64 100), "ptrauth"(i32 42, i64 %arg0) ] +; CHECK: Multiple ptrauth operand bundles on a function call +; CHECK-NEXT: call void %arg.ptr() [ "ptrauth"(i64 42, i64 100), "ptrauth"(i64 42, i64 %arg.64) ] + call void %arg.ptr() [ "ptrauth"(i64 42, i64 100), "ptrauth"(i64 42, i64 %arg.64) ] -; CHECK: Ptrauth bundle key operand must be an i32 constant -; CHECK-NEXT: call void %arg2() [ "ptrauth"(i32 %arg1, i64 120) ] - call void %arg2() [ "ptrauth"(i32 %arg1, i64 120) ] +; CHECK: Direct call cannot have a ptrauth bundle +; CHECK-NEXT: call void @g() [ "ptrauth"(i64 42, i64 120) ] + call void @g() [ "ptrauth"(i64 42, i64 120) ] -; CHECK: Ptrauth bundle key operand must be an i32 constant -; CHECK-NEXT: call void %arg2() [ "ptrauth"(i64 42, i64 120) ] - call void %arg2() [ "ptrauth"(i64 42, i64 120) ] +; CHECK-NOT: call void %ok() + call void %ok() [ "ptrauth"(i32 42, i64 120) ] ; OK + call void %ok() [ "ptrauth"(i32 42, i64 %arg.64) ] ; OK + call void %ok() [ "ptrauth"(i64 %arg.64, i64 123) ] ; OK + call void %ok() [ "ptrauth"(i64 %arg.64, i64 123, i64 %arg.64, i64 42) ] ; OK -; CHECK: Ptrauth bundle discriminator operand must be an i64 -; CHECK-NEXT: call void %arg2() [ "ptrauth"(i32 42, i32 120) ] - call void %arg2() [ "ptrauth"(i32 42, i32 120) ] +; CHECK: Expected non-empty ptrauth bundle +; CHECK-NEXT: call void %arg.ptr() [ "ptrauth"() ] + call void %arg.ptr() [ "ptrauth"() ] -; CHECK: Direct call cannot have a ptrauth bundle -; CHECK-NEXT: call void @g() [ "ptrauth"(i32 42, i64 120) ] - call void @g() [ "ptrauth"(i32 42, i64 120) ] +; CHECK: Ptrauth bundle must only contain i64 operands +; CHECK-NEXT: call void %arg.ptr() [ "ptrauth"(i64 42, i32 120) ] + call void %arg.ptr() [ "ptrauth"(i64 42, i32 120) ] + +; CHECK: Ptrauth bundle must only contain i64 operands +; CHECK-NEXT: call void %arg.ptr() [ "ptrauth"(i32 42, i64 120, i64 123) ] + call void %arg.ptr() [ "ptrauth"(i32 42, i64 120, i64 123) ] + +; CHECK: Ptrauth bundle must only contain i64 operands +; CHECK-NEXT: call void %arg.ptr() [ "ptrauth"(i64 42, i64 120, i32 123) ] + call void %arg.ptr() [ "ptrauth"(i64 42, i64 120, i32 123) ] + +; Note that for compatibility reasons the first operand (originally, "the key ID") +; might be auto-upgraded to i64: +; +; CHECK-NOT: call void %ok() + call void %ok() [ "ptrauth"(i32 42, i64 120) ] + +; CHECK: Expected exactly one ptrauth bundle +; CHECK-NEXT: call i64 @llvm.ptrauth.auth(i64 0) +; CHECK: Expected exactly one ptrauth bundle +; CHECK-NEXT: call i64 @llvm.ptrauth.auth(i64 0) [ "ptrauth"(i64 42, i64 120), "ptrauth"(i64 42, i64 120) ] +; CHECK-NOT: @llvm.ptrauth.auth + call i64 @llvm.ptrauth.auth(i64 0) + call i64 @llvm.ptrauth.auth(i64 0) [ "ptrauth"(i64 42, i64 120), "ptrauth"(i64 42, i64 120) ] + call i64 @llvm.ptrauth.auth(i64 0) [ "ptrauth"(i64 42, i64 120) ] + call i64 @llvm.ptrauth.auth(i64 0) [ "ptrauth"(i64 %arg.64) ] + +; CHECK: Expected exactly one ptrauth bundle +; CHECK-NEXT: call i64 @llvm.ptrauth.sign(i64 0) +; CHECK: Expected exactly one ptrauth bundle +; CHECK-NEXT: call i64 @llvm.ptrauth.sign(i64 0) [ "ptrauth"(i64 42, i64 120), "ptrauth"(i64 42, i64 120) ] +; CHECK-NOT: @llvm.ptrauth.sign + call i64 @llvm.ptrauth.sign(i64 0) + call i64 @llvm.ptrauth.sign(i64 0) [ "ptrauth"(i64 42, i64 120), "ptrauth"(i64 42, i64 120) ] + call i64 @llvm.ptrauth.sign(i64 0) [ "ptrauth"(i64 42, i64 120) ] + call i64 @llvm.ptrauth.sign(i64 0) [ "ptrauth"(i64 %arg.64) ] + +; CHECK: Expected exactly two ptrauth bundles +; CHECK-NEXT: call i64 @llvm.ptrauth.resign(i64 0) +; CHECK: Expected exactly two ptrauth bundles +; CHECK-NEXT: call i64 @llvm.ptrauth.resign(i64 0) [ "ptrauth"(i64 42, i64 120) ] +; CHECK-NOT: @llvm.ptrauth.resign + call i64 @llvm.ptrauth.resign(i64 0) + call i64 @llvm.ptrauth.resign(i64 0) [ "ptrauth"(i64 42, i64 120) ] + call i64 @llvm.ptrauth.resign(i64 0) [ "ptrauth"(i64 42, i64 120), "ptrauth"(i64 42, i64 120) ] + call i64 @llvm.ptrauth.resign(i64 0) [ "ptrauth"(i64 %arg.64), "ptrauth"(i64 42, i64 120, i64 0, i64 123) ] + +; CHECK: Expected exactly one ptrauth bundle +; CHECK-NEXT: call i64 @llvm.ptrauth.strip(i64 0) +; CHECK: Expected exactly one ptrauth bundle +; CHECK-NEXT: call i64 @llvm.ptrauth.strip(i64 0) [ "ptrauth"(i64 42, i64 120), "ptrauth"(i64 42, i64 120) ] +; CHECK-NOT: @llvm.ptrauth.strip + call i64 @llvm.ptrauth.strip(i64 0) + call i64 @llvm.ptrauth.strip(i64 0) [ "ptrauth"(i64 42, i64 120), "ptrauth"(i64 42, i64 120) ] + call i64 @llvm.ptrauth.strip(i64 0) [ "ptrauth"(i64 42, i64 120) ] + call i64 @llvm.ptrauth.strip(i64 0) [ "ptrauth"(i64 %arg.64) ] + +; CHECK: Unexpected ptrauth bundle +; CHECK-NEXT: call i64 @llvm.ptrauth.sign.generic(i64 0, i64 42) [ "ptrauth"(i64 42, i64 120) ] + call i64 @llvm.ptrauth.sign.generic(i64 0, i64 42) [ "ptrauth"(i64 42, i64 120) ] -; CHECK-NOT: call void - call void %arg2() [ "ptrauth"(i32 42, i64 120) ] ; OK - call void %arg2() [ "ptrauth"(i32 42, i64 %arg0) ] ; OK ret void } diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp index 026d815b43da7..0218fff6feaee 100644 --- a/llvm/tools/llvm-c-test/echo.cpp +++ b/llvm/tools/llvm-c-test/echo.cpp @@ -15,6 +15,7 @@ //===----------------------------------------------------------------------===// #include "llvm-c-test.h" +#include "llvm-c/Core.h" #include "llvm-c/DebugInfo.h" #include "llvm-c/ErrorHandling.h" #include "llvm-c/Target.h" @@ -398,12 +399,19 @@ static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M) { if (LLVMIsAConstantPtrAuth(Cst)) { LLVMValueRef Ptr = clone_constant(LLVMGetConstantPtrAuthPointer(Cst), M); - LLVMValueRef Key = clone_constant(LLVMGetConstantPtrAuthKey(Cst), M); - LLVMValueRef Disc = - clone_constant(LLVMGetConstantPtrAuthDiscriminator(Cst), M); - LLVMValueRef AddrDisc = - clone_constant(LLVMGetConstantPtrAuthAddrDiscriminator(Cst), M); - return LLVMConstantPtrAuth(Ptr, Key, Disc, AddrDisc); + + unsigned SchemaSize = LLVMGetConstantPtrAuthSchemaSize(Cst); + SmallVector Schema; + for (unsigned I = 0; I < SchemaSize; ++I) { + LLVMValueRef Op = LLVMGetConstantPtrAuthSchemaOperand(Cst, I); + Schema.push_back(clone_constant(Op, M)); + } + + LLVMValueRef DeactivationSymbol = clone_constant( + LLVMGetConstantPtrAuthDeactivationSymbol(Cst), M); + + return LLVMConstantPtrAuth(Ptr, Schema.data(), Schema.size(), + DeactivationSymbol); } // At this point, if it's not a constant expression, it's a kind of constant @@ -419,6 +427,9 @@ static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M) { case LLVMBitCast: return LLVMConstBitCast(clone_constant(LLVMGetOperand(Cst, 0), M), TypeCloner(M).Clone(Cst)); + case LLVMPtrToInt: + return LLVMConstPtrToInt(clone_constant(LLVMGetOperand(Cst, 0), M), + TypeCloner(M).Clone(Cst)); case LLVMGetElementPtr: { LLVMTypeRef ElemTy = TypeCloner(M).Clone(LLVMGetGEPSourceElementType(Cst)); diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp index 168502f89cbf8..8d4b24a909538 100644 --- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp +++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp @@ -1367,7 +1367,7 @@ define void @foo() { TEST_F(SandboxIRTest, ConstantPtrAuth) { parseIR(C, R"IR( define ptr @foo() { - ret ptr ptrauth (ptr @foo, i32 2, i64 1234) + ret ptr ptrauth (ptr @foo, [i64 2, i64 1234, i64 0]) } )IR"); Function &LLVMF = *M->getFunction("foo"); @@ -1384,8 +1384,8 @@ define ptr @foo() { auto *PtrAuth = cast(Ret->getReturnValue()); // Check get(), getKey(), getDiscriminator(), getAddrDiscriminator(). auto *NewPtrAuth = sandboxir::ConstantPtrAuth::get( - &F, PtrAuth->getKey(), PtrAuth->getDiscriminator(), - PtrAuth->getAddrDiscriminator(), PtrAuth->getDeactivationSymbol()); + &F, {PtrAuth->getKey(), PtrAuth->getDiscriminator(), + PtrAuth->getAddrDiscriminator()}, PtrAuth->getDeactivationSymbol()); EXPECT_EQ(NewPtrAuth, PtrAuth); // Check hasAddressDiscriminator(). EXPECT_EQ(PtrAuth->hasAddressDiscriminator(), @@ -1395,8 +1395,9 @@ define ptr @foo() { LLVMPtrAuth->hasSpecialAddressDiscriminator(0u)); // Check isKnownCompatibleWith(). const DataLayout &DL = M->getDataLayout(); - EXPECT_TRUE(PtrAuth->isKnownCompatibleWith(PtrAuth->getKey(), - PtrAuth->getDiscriminator(), DL)); + EXPECT_TRUE(PtrAuth->isKnownCompatibleWith( + {PtrAuth->getKey(), PtrAuth->getDiscriminator(), + PtrAuth->getAddrDiscriminator()}, DL)); // Check getWithSameSchema(). EXPECT_EQ(PtrAuth->getWithSameSchema(&F), PtrAuth); } diff --git a/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp b/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp index 60e9c5688c795..7c543d0f3049a 100644 --- a/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp +++ b/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp @@ -440,7 +440,6 @@ TEST(ValueMapperTest, mapValueConstantTargetNoneToLayoutTypeNullValue) { TEST(ValueMapperTest, mapValuePtrAuth) { LLVMContext C; Type *PtrTy = PointerType::get(C, 0); - IntegerType *Int32Ty = Type::getInt32Ty(C); IntegerType *Int64Ty = Type::getInt64Ty(C); std::unique_ptr Var0 = std::make_unique( @@ -456,18 +455,21 @@ TEST(ValueMapperTest, mapValuePtrAuth) { std::unique_ptr DS1 = std::make_unique( PtrTy, false, GlobalValue::ExternalLinkage, nullptr, "DS1"); - ConstantInt *ConstKey = ConstantInt::get(Int32Ty, 1); + ConstantInt *ConstKey = ConstantInt::get(Int64Ty, 1); ConstantInt *ConstDisc = ConstantInt::get(Int64Ty, 1234); + Constant *Storage0AsInt = ConstantExpr::getPtrToInt(Storage0.get(), Int64Ty); + Constant *Storage1AsInt = ConstantExpr::getPtrToInt(Storage1.get(), Int64Ty); + ValueToValueMapTy VM; VM[Var0.get()] = Var1.get(); - VM[Storage0.get()] = Storage1.get(); + VM[Storage0AsInt] = Storage1AsInt; VM[DS0.get()] = DS1.get(); - ConstantPtrAuth *Value = ConstantPtrAuth::get(Var0.get(), ConstKey, ConstDisc, - Storage0.get(), DS0.get()); + ConstantPtrAuth *Value = ConstantPtrAuth::get( + Var0.get(), {ConstKey, ConstDisc, Storage0AsInt}, DS0.get()); ConstantPtrAuth *MappedValue = ConstantPtrAuth::get( - Var1.get(), ConstKey, ConstDisc, Storage1.get(), DS1.get()); + Var1.get(), {ConstKey, ConstDisc, Storage1AsInt}, DS1.get()); EXPECT_EQ(ValueMapper(VM).mapValue(*Value), MappedValue); } diff --git a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp index 8540faed34e5d..18b05a259f302 100644 --- a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp +++ b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp @@ -1472,6 +1472,9 @@ Error OperandMatcher::addTypeCheckPredicate(const TypeSetByHwMode &VTy, return Error::success(); } + if (VTy.getMachineValueType() == MVT::Untyped) + return Error::success(); + auto OpTyOrNone = MVTToLLT(VTy.getMachineValueType().SimpleTy); if (!OpTyOrNone) return failUnsupported("unsupported type");