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

Reply via email to