https://github.com/atrosinenko updated https://github.com/llvm/llvm-project/pull/146489
>From 3e4b8697e6318e8b6985cb6b6f7cfec883e9c233 Mon Sep 17 00:00:00 2001 From: Anatoly Trosinenko <atrosine...@accesssoftek.com> Date: Sat, 28 Jun 2025 11:09:01 +0300 Subject: [PATCH] [AArch64][PAC] Rework discriminator analysis in AUT and AUTPAC Make use of post-processing the discriminator components by custom inserter hook to eliminate duplication for DAGISel and GlobalISel and improve cross-BB analysis for DAGISel. --- .../Target/AArch64/AArch64ISelDAGToDAG.cpp | 51 +--- .../Target/AArch64/AArch64ISelLowering.cpp | 10 + llvm/lib/Target/AArch64/AArch64InstrInfo.td | 2 + .../GISel/AArch64InstructionSelector.cpp | 27 +- llvm/test/CodeGen/AArch64/ptrauth-isel.ll | 235 +++++++++++++++++- 5 files changed, 256 insertions(+), 69 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp index da617b7e19266..5d3fd48f448b5 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -1487,39 +1487,6 @@ void AArch64DAGToDAGISel::SelectTable(SDNode *N, unsigned NumVecs, unsigned Opc, ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, VT, Ops)); } -static std::tuple<SDValue, SDValue> -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<ConstantSDNode>(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) { SDLoc DL(N); // IntrinsicID is operand #0 @@ -1530,13 +1497,11 @@ void AArch64DAGToDAGISel::SelectPtrauthAuth(SDNode *N) { unsigned AUTKeyC = cast<ConstantSDNode>(AUTKey)->getZExtValue(); AUTKey = CurDAG->getTargetConstant(AUTKeyC, DL, MVT::i64); - SDValue AUTAddrDisc, AUTConstDisc; - std::tie(AUTConstDisc, AUTAddrDisc) = - extractPtrauthBlendDiscriminators(AUTDisc, CurDAG); + SDValue Zero = CurDAG->getTargetConstant(0, DL, MVT::i64); SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(), DL, AArch64::X16, Val, SDValue()); - SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, X16Copy.getValue(1)}; + SDValue Ops[] = {AUTKey, Zero, AUTDisc, X16Copy.getValue(1)}; SDNode *AUT = CurDAG->getMachineNode(AArch64::AUT, DL, MVT::i64, Ops); ReplaceNode(N, AUT); @@ -1557,19 +1522,13 @@ void AArch64DAGToDAGISel::SelectPtrauthResign(SDNode *N) { AUTKey = CurDAG->getTargetConstant(AUTKeyC, DL, MVT::i64); PACKey = CurDAG->getTargetConstant(PACKeyC, DL, MVT::i64); - SDValue AUTAddrDisc, AUTConstDisc; - std::tie(AUTConstDisc, AUTAddrDisc) = - extractPtrauthBlendDiscriminators(AUTDisc, CurDAG); - - SDValue PACAddrDisc, PACConstDisc; - std::tie(PACConstDisc, PACAddrDisc) = - extractPtrauthBlendDiscriminators(PACDisc, CurDAG); + SDValue Zero = CurDAG->getTargetConstant(0, DL, MVT::i64); SDValue X16Copy = CurDAG->getCopyToReg(CurDAG->getEntryNode(), DL, AArch64::X16, Val, SDValue()); - SDValue Ops[] = {AUTKey, AUTConstDisc, AUTAddrDisc, PACKey, - PACConstDisc, PACAddrDisc, X16Copy.getValue(1)}; + SDValue Ops[] = { + AUTKey, Zero, AUTDisc, PACKey, Zero, PACDisc, X16Copy.getValue(1)}; SDNode *AUTPAC = CurDAG->getMachineNode(AArch64::AUTPAC, DL, MVT::i64, Ops); ReplaceNode(N, AUTPAC); diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index c8eb9f3dd01ad..d7b835c8acba7 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -3241,10 +3241,20 @@ MachineBasicBlock *AArch64TargetLowering::EmitInstrWithCustomInserter( case AArch64::MOVT_TIZ_PSEUDO: return EmitZTInstr(MI, BB, AArch64::MOVT_TIZ, /*Op0IsDef=*/true); + case AArch64::AUT: + fixupBlendComponents(MI, BB, MI.getOperand(1), MI.getOperand(2), + &AArch64::GPR64noipRegClass); + return BB; case AArch64::PAC: fixupBlendComponents(MI, BB, MI.getOperand(3), MI.getOperand(4), &AArch64::GPR64noipRegClass); return BB; + case AArch64::AUTPAC: + fixupBlendComponents(MI, BB, MI.getOperand(1), MI.getOperand(2), + &AArch64::GPR64noipRegClass); + fixupBlendComponents(MI, BB, MI.getOperand(4), MI.getOperand(5), + &AArch64::GPR64noipRegClass); + return BB; } } diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index c509b431927c1..46ad4bb947497 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -2134,6 +2134,7 @@ let Predicates = [HasPAuth] in { let Size = 32; let Defs = [X16,X17,NZCV]; let Uses = [X16]; + let usesCustomInserter = 1; } // PAC pseudo instruction. Is AsmPrinter, it is expanded into an actual PAC* @@ -2170,6 +2171,7 @@ let Predicates = [HasPAuth] in { let Size = 48; let Defs = [X16,X17,NZCV]; let Uses = [X16]; + let usesCustomInserter = 1; } // Materialize a signed global address, with adrp+add and PAC. diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp index d55ff5acb3dca..831247fbfae75 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp @@ -6725,25 +6725,15 @@ bool AArch64InstructionSelector::selectIntrinsic(MachineInstr &I, 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(0) + .addUse(AUTDisc) .addImm(PACKey) - .addImm(PACConstDiscC) - .addUse(PACAddrDisc) + .addImm(0) + .addUse(PACDisc) .constrainAllUses(TII, TRI, RBI); MIB.buildCopy({DstReg}, Register(AArch64::X16)); @@ -6757,17 +6747,12 @@ bool AArch64InstructionSelector::selectIntrinsic(MachineInstr &I, 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); - MIB.buildCopy({AArch64::X16}, {ValReg}); MIB.buildInstr(TargetOpcode::IMPLICIT_DEF, {AArch64::X17}, {}); MIB.buildInstr(AArch64::AUT) .addImm(AUTKey) - .addImm(AUTConstDiscC) - .addUse(AUTAddrDisc) + .addImm(0) + .addUse(AUTDisc) .constrainAllUses(TII, TRI, RBI); MIB.buildCopy({DstReg}, Register(AArch64::X16)); diff --git a/llvm/test/CodeGen/AArch64/ptrauth-isel.ll b/llvm/test/CodeGen/AArch64/ptrauth-isel.ll index 89ce439f5b47b..15b4c2edaa7b3 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-isel.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-isel.ll @@ -14,8 +14,8 @@ @discvar = dso_local global i64 0 ; Make sure the components of blend(addr, imm) are recognized and passed to -; PAC pseudo via separate operands to prevent substitution of the immediate -; modifier. +; AUT / PAC / AUTPAC pseudo via separate operands to prevent substitution of +; the immediate modifier. ; ; 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 @@ -101,6 +101,44 @@ entry: ret i64 %signed } +define i64 @blend_and_auth_same_bb(i64 %addr) { + ; DAGISEL-LABEL: name: blend_and_auth_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: $x16 = COPY [[COPY]] + ; DAGISEL-NEXT: [[COPY1:%[0-9]+]]:gpr64noip = COPY [[LDRXui]] + ; DAGISEL-NEXT: AUT 2, 42, killed [[COPY1]], implicit-def $x16, implicit-def dead $x17, implicit-def dead $nzcv, implicit $x16 + ; DAGISEL-NEXT: [[COPY2:%[0-9]+]]:gpr64all = COPY $x16 + ; DAGISEL-NEXT: $x0 = COPY [[COPY2]] + ; DAGISEL-NEXT: RET_ReallyLR implicit $x0 + ; + ; GISEL-LABEL: name: blend_and_auth_same_bb + ; GISEL: bb.1.entry: + ; GISEL-NEXT: liveins: $x0 + ; GISEL-NEXT: {{ $}} + ; GISEL-NEXT: [[COPY:%[0-9]+]]:gpr64all = 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: $x16 = COPY [[COPY]] + ; GISEL-NEXT: $x17 = IMPLICIT_DEF + ; GISEL-NEXT: [[COPY1:%[0-9]+]]:gpr64noip = COPY [[LDRXui]] + ; GISEL-NEXT: AUT 2, 42, [[COPY1]], implicit-def $x16, implicit-def $x17, implicit-def dead $nzcv, implicit $x16 + ; GISEL-NEXT: [[COPY2:%[0-9]+]]:gpr64 = COPY $x16 + ; GISEL-NEXT: $x0 = COPY [[COPY2]] + ; GISEL-NEXT: RET_ReallyLR implicit $x0 +entry: + %addrdisc = load i64, ptr @discvar + %disc = call i64 @llvm.ptrauth.blend(i64 %addrdisc, i64 42) + %authed = call i64 @llvm.ptrauth.auth(i64 %addr, i32 2, i64 %disc) + ret i64 %authed +} + define i64 @blend_and_sign_same_bb(i64 %addr) { ; DAGISEL-LABEL: name: blend_and_sign_same_bb ; DAGISEL: bb.0.entry: @@ -134,10 +172,124 @@ entry: ret i64 %signed } +define i64 @blend_and_resign_same_bb(i64 %addr) { + ; DAGISEL-LABEL: name: blend_and_resign_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: [[MOVKXi1:%[0-9]+]]:gpr64noip = MOVKXi [[LDRXui]], 123, 48 + ; DAGISEL-NEXT: $x16 = COPY [[COPY]] + ; DAGISEL-NEXT: [[COPY1:%[0-9]+]]:gpr64noip = COPY [[LDRXui]] + ; DAGISEL-NEXT: [[COPY2:%[0-9]+]]:gpr64noip = COPY [[LDRXui]] + ; DAGISEL-NEXT: AUTPAC 2, 42, killed [[COPY1]], 3, 123, killed [[COPY2]], implicit-def $x16, implicit-def dead $x17, implicit-def dead $nzcv, implicit $x16 + ; DAGISEL-NEXT: [[COPY3:%[0-9]+]]:gpr64all = COPY $x16 + ; DAGISEL-NEXT: $x0 = COPY [[COPY3]] + ; DAGISEL-NEXT: RET_ReallyLR implicit $x0 + ; + ; GISEL-LABEL: name: blend_and_resign_same_bb + ; GISEL: bb.1.entry: + ; GISEL-NEXT: liveins: $x0 + ; GISEL-NEXT: {{ $}} + ; GISEL-NEXT: [[COPY:%[0-9]+]]:gpr64all = 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: [[MOVKXi1:%[0-9]+]]:gpr64noip = MOVKXi [[LDRXui]], 123, 48 + ; GISEL-NEXT: $x16 = COPY [[COPY]] + ; GISEL-NEXT: $x17 = IMPLICIT_DEF + ; GISEL-NEXT: [[COPY1:%[0-9]+]]:gpr64noip = COPY [[LDRXui]] + ; GISEL-NEXT: [[COPY2:%[0-9]+]]:gpr64noip = COPY [[LDRXui]] + ; GISEL-NEXT: AUTPAC 2, 42, [[COPY1]], 3, 123, [[COPY2]], implicit-def $x16, implicit-def $x17, implicit-def dead $nzcv, implicit $x16 + ; GISEL-NEXT: [[COPY3:%[0-9]+]]:gpr64 = COPY $x16 + ; GISEL-NEXT: $x0 = COPY [[COPY3]] + ; GISEL-NEXT: RET_ReallyLR implicit $x0 +entry: + %addrdisc = load i64, ptr @discvar + %auth.disc = call i64 @llvm.ptrauth.blend(i64 %addrdisc, i64 42) + %sign.disc = call i64 @llvm.ptrauth.blend(i64 %addrdisc, i64 123) + %resigned = call i64 @llvm.ptrauth.resign(i64 %addr, i32 2, i64 %auth.disc, i32 3, i64 %sign.disc) + ret i64 %resigned +} + ; 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_auth_different_bbs(i64 %addr, i64 %cond) { + ; DAGISEL-LABEL: name: blend_and_auth_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: $x16 = COPY [[COPY1]] + ; DAGISEL-NEXT: [[COPY4:%[0-9]+]]:gpr64noip = COPY [[LDRXui]] + ; DAGISEL-NEXT: AUT 2, 42, [[COPY4]], implicit-def $x16, implicit-def dead $x17, implicit-def dead $nzcv, implicit $x16 + ; DAGISEL-NEXT: [[COPY5:%[0-9]+]]:gpr64all = COPY $x16 + ; DAGISEL-NEXT: $x0 = COPY [[COPY5]] + ; DAGISEL-NEXT: RET_ReallyLR implicit $x0 + ; + ; GISEL-LABEL: name: blend_and_auth_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]+]]:gpr64all = 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: $x16 = COPY [[COPY]] + ; GISEL-NEXT: $x17 = IMPLICIT_DEF + ; GISEL-NEXT: [[COPY3:%[0-9]+]]:gpr64noip = COPY [[LDRXui]] + ; GISEL-NEXT: AUT 2, 42, [[COPY3]], implicit-def $x16, implicit-def $x17, implicit-def dead $nzcv, implicit $x16 + ; GISEL-NEXT: [[COPY4:%[0-9]+]]:gpr64 = COPY $x16 + ; GISEL-NEXT: $x0 = COPY [[COPY4]] + ; 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: + %authed = call i64 @llvm.ptrauth.auth(i64 %addr, i32 2, i64 %disc) + ret i64 %authed +} + define i64 @blend_and_sign_different_bbs(i64 %addr, i64 %cond) { ; DAGISEL-LABEL: name: blend_and_sign_different_bbs ; DAGISEL: bb.0.entry: @@ -203,3 +355,82 @@ exit: %signed = call i64 @llvm.ptrauth.sign(i64 %addr, i32 2, i64 %disc) ret i64 %signed } + +define i64 @blend_and_resign_different_bbs(i64 %addr, i64 %cond) { + ; DAGISEL-LABEL: name: blend_and_resign_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: [[MOVKXi1:%[0-9]+]]:gpr64 = MOVKXi [[LDRXui]], 123, 48 + ; DAGISEL-NEXT: [[COPY3:%[0-9]+]]:gpr64noip = COPY [[MOVKXi1]] + ; 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: [[COPY4:%[0-9]+]]:gpr64common = COPY [[COPY2]] + ; DAGISEL-NEXT: [[COPY5:%[0-9]+]]:gpr64common = COPY [[COPY3]] + ; DAGISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[COPY4]], 3866633 /* reguse:GPR64common */, [[COPY5]] + ; DAGISEL-NEXT: {{ $}} + ; DAGISEL-NEXT: bb.2.exit: + ; DAGISEL-NEXT: $x16 = COPY [[COPY1]] + ; DAGISEL-NEXT: [[COPY6:%[0-9]+]]:gpr64noip = COPY [[LDRXui]] + ; DAGISEL-NEXT: [[COPY7:%[0-9]+]]:gpr64noip = COPY [[LDRXui]] + ; DAGISEL-NEXT: AUTPAC 2, 42, [[COPY6]], 3, 123, [[COPY7]], implicit-def $x16, implicit-def dead $x17, implicit-def dead $nzcv, implicit $x16 + ; DAGISEL-NEXT: [[COPY8:%[0-9]+]]:gpr64all = COPY $x16 + ; DAGISEL-NEXT: $x0 = COPY [[COPY8]] + ; DAGISEL-NEXT: RET_ReallyLR implicit $x0 + ; + ; GISEL-LABEL: name: blend_and_resign_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]+]]:gpr64all = 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: [[MOVKXi1:%[0-9]+]]:gpr64noip = MOVKXi [[LDRXui]], 123, 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: [[COPY3:%[0-9]+]]:gpr64common = COPY [[MOVKXi1]] + ; GISEL-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 3866633 /* reguse:GPR64common */, [[COPY2]], 3866633 /* reguse:GPR64common */, [[COPY3]] + ; GISEL-NEXT: {{ $}} + ; GISEL-NEXT: bb.3.exit: + ; GISEL-NEXT: $x16 = COPY [[COPY]] + ; GISEL-NEXT: $x17 = IMPLICIT_DEF + ; GISEL-NEXT: [[COPY4:%[0-9]+]]:gpr64noip = COPY [[LDRXui]] + ; GISEL-NEXT: [[COPY5:%[0-9]+]]:gpr64noip = COPY [[LDRXui]] + ; GISEL-NEXT: AUTPAC 2, 42, [[COPY4]], 3, 123, [[COPY5]], implicit-def $x16, implicit-def $x17, implicit-def dead $nzcv, implicit $x16 + ; GISEL-NEXT: [[COPY6:%[0-9]+]]:gpr64 = COPY $x16 + ; GISEL-NEXT: $x0 = COPY [[COPY6]] + ; GISEL-NEXT: RET_ReallyLR implicit $x0 +entry: + %addrdisc = load i64, ptr @discvar + %auth.disc = call i64 @llvm.ptrauth.blend(i64 %addrdisc, i64 42) + %sign.disc = call i64 @llvm.ptrauth.blend(i64 %addrdisc, i64 123) + %cond.b = icmp ne i64 %cond, 0 + br i1 %cond.b, label %next, label %exit + +next: + call void asm sideeffect "nop", "r,r"(i64 %auth.disc, i64 %sign.disc) + br label %exit + +exit: + %resigned = call i64 @llvm.ptrauth.resign(i64 %addr, i32 2, i64 %auth.disc, i32 3, i64 %sign.disc) + ret i64 %resigned +} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits