Index: llvm/include/llvm/MC/MCInstrDesc.h =================================================================== --- llvm/include/llvm/MC/MCInstrDesc.h +++ llvm/include/llvm/MC/MCInstrDesc.h @@ -168,6 +168,7 @@ Add, Trap, VariadicOpsAreDefs, + Authenticating, }; } @@ -408,6 +409,15 @@ return Flags & (1ULL << MCID::VariadicOpsAreDefs); } + /// Return true if this instruction authenticates a pointer (e.g. LDRAx/BRAx + /// from ARMv8.3, which perform loads/branches with authentication). + /// + /// An authenticating instruction may fail in an ABI-defined manner when + /// operating on an invalid signed pointer. + bool isAuthenticating() const { + return Flags & (1ULL << MCID::Authenticating); + } + //===--------------------------------------------------------------------===// // Side Effect Analysis //===--------------------------------------------------------------------===// Index: llvm/include/llvm/Target/Target.td =================================================================== --- llvm/include/llvm/Target/Target.td +++ llvm/include/llvm/Target/Target.td @@ -530,6 +530,7 @@ bit hasCtrlDep = 0; // Does this instruction r/w ctrl-flow chains? bit isNotDuplicable = 0; // Is it unsafe to duplicate this instruction? bit isConvergent = 0; // Is this instruction convergent? + bit isAuthenticating = 0; // Does this instruction authenticate a pointer? bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction. bit hasExtraSrcRegAllocReq = 0; // Sources have special regalloc requirement? bit hasExtraDefRegAllocReq = 0; // Defs have special regalloc requirement? Index: llvm/lib/Target/AArch64/AArch64InstrFormats.td =================================================================== --- llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -1262,6 +1262,11 @@ let Inst{4-0} = 0b11111; } +class SystemNoOperandsAuth op2, string asm, list pattern = []> + : SystemNoOperands { + let isAuthenticating = 1; +} + // MRS/MSR system instructions. These have different operand classes because // a different subset of registers can be accessed through each instruction. def MRSSystemRegisterOperand : AsmOperandClass { @@ -1483,6 +1488,7 @@ class AuthBase M, dag oops, dag iops, string asm, string operands, list pattern> : I, Sched<[]> { + let isAuthenticating = 1; let Inst{31-25} = 0b1101011; let Inst{20-11} = 0b1111100001; let Inst{10} = M; @@ -1522,6 +1528,7 @@ bits<10> offset; bits<5> Rn; bits<5> Rt; + let isAuthenticating = 1; let Inst{31-24} = 0b11111000; let Inst{23} = M; let Inst{22} = offset{9}; Index: llvm/lib/Target/AArch64/AArch64InstrInfo.td =================================================================== --- llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -819,20 +819,20 @@ let Uses = [LR], Defs = [LR] in { def PACIAZ : SystemNoOperands<0b000, "paciaz">; def PACIBZ : SystemNoOperands<0b010, "pacibz">; - def AUTIAZ : SystemNoOperands<0b100, "autiaz">; - def AUTIBZ : SystemNoOperands<0b110, "autibz">; + def AUTIAZ : SystemNoOperandsAuth<0b100, "autiaz">; + def AUTIBZ : SystemNoOperandsAuth<0b110, "autibz">; } let Uses = [LR, SP], Defs = [LR] in { def PACIASP : SystemNoOperands<0b001, "paciasp">; def PACIBSP : SystemNoOperands<0b011, "pacibsp">; - def AUTIASP : SystemNoOperands<0b101, "autiasp">; - def AUTIBSP : SystemNoOperands<0b111, "autibsp">; + def AUTIASP : SystemNoOperandsAuth<0b101, "autiasp">; + def AUTIBSP : SystemNoOperandsAuth<0b111, "autibsp">; } let Uses = [X16, X17], Defs = [X17], CRm = 0b0001 in { def PACIA1716 : SystemNoOperands<0b000, "pacia1716">; def PACIB1716 : SystemNoOperands<0b010, "pacib1716">; - def AUTIA1716 : SystemNoOperands<0b100, "autia1716">; - def AUTIB1716 : SystemNoOperands<0b110, "autib1716">; + def AUTIA1716 : SystemNoOperandsAuth<0b100, "autia1716">; + def AUTIB1716 : SystemNoOperandsAuth<0b110, "autib1716">; } let Uses = [LR], Defs = [LR], CRm = 0b0000 in { Index: llvm/unittests/Target/AArch64/InstSizes.cpp =================================================================== --- llvm/unittests/Target/AArch64/InstSizes.cpp +++ llvm/unittests/Target/AArch64/InstSizes.cpp @@ -78,6 +78,38 @@ } // anonymous namespace +TEST(InstSizes, Authenticated) { + std::unique_ptr TM = createTargetMachine(); + ASSERT_TRUE(TM); + std::unique_ptr II = createInstrInfo(TM.get()); + + auto isAuthInst = [](AArch64InstrInfo &II, MachineFunction &MF) { + auto I = MF.begin()->begin(); + EXPECT_EQ(4u, II.getInstSizeInBytes(*I)); + EXPECT_TRUE(I->getDesc().isAuthenticating()); + }; + + runChecks(TM.get(), II.get(), "", + " \n" + " BLRAA $x10, $x9\n", + isAuthInst); + + runChecks(TM.get(), II.get(), "", + " \n" + " RETAB implicit $lr, implicit $sp, implicit killed $x0\n", + isAuthInst); + + runChecks(TM.get(), II.get(), "", + " \n" + " frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp\n", + isAuthInst); + + runChecks(TM.get(), II.get(), "", + " \n" + " frame-destroy AUTIBSP implicit-def $lr, implicit killed $lr, implicit $sp\n", + isAuthInst); +} + TEST(InstSizes, STACKMAP) { std::unique_ptr TM = createTargetMachine(); ASSERT_TRUE(TM); Index: llvm/utils/TableGen/CodeGenInstruction.h =================================================================== --- llvm/utils/TableGen/CodeGenInstruction.h +++ llvm/utils/TableGen/CodeGenInstruction.h @@ -278,6 +278,7 @@ bool hasChain : 1; bool hasChain_Inferred : 1; bool variadicOpsAreDefs : 1; + bool isAuthenticating : 1; std::string DeprecatedReason; bool HasComplexDeprecationPredicate; Index: llvm/utils/TableGen/CodeGenInstruction.cpp =================================================================== --- llvm/utils/TableGen/CodeGenInstruction.cpp +++ llvm/utils/TableGen/CodeGenInstruction.cpp @@ -396,6 +396,7 @@ hasNoSchedulingInfo = R->getValueAsBit("hasNoSchedulingInfo"); FastISelShouldIgnore = R->getValueAsBit("FastISelShouldIgnore"); variadicOpsAreDefs = R->getValueAsBit("variadicOpsAreDefs"); + isAuthenticating = R->getValueAsBit("isAuthenticating"); bool Unset; mayLoad = R->getValueAsBitOrUnset("mayLoad", Unset); Index: llvm/utils/TableGen/InstrDocsEmitter.cpp =================================================================== --- llvm/utils/TableGen/InstrDocsEmitter.cpp +++ llvm/utils/TableGen/InstrDocsEmitter.cpp @@ -138,6 +138,7 @@ FLAG(isConvergent) FLAG(hasNoSchedulingInfo) FLAG(variadicOpsAreDefs) + FLAG(isAuthenticating) if (!FlagStrings.empty()) { OS << "Flags: "; bool IsFirst = true; Index: llvm/utils/TableGen/InstrInfoEmitter.cpp =================================================================== --- llvm/utils/TableGen/InstrInfoEmitter.cpp +++ llvm/utils/TableGen/InstrInfoEmitter.cpp @@ -703,6 +703,7 @@ if (Inst.isInsertSubreg) OS << "|(1ULL<getValueAsBitsInit("TSFlags");