[llvm] e3a7f0e - [AArch64][PAC] Select llvm.ptrauth.sign/sign.generic to PAC*.

Ahmed Bougacha via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 18 15:21:56 PST 2021


Author: Ahmed Bougacha
Date: 2021-11-18T15:21:30-08:00
New Revision: e3a7f0e2f9ab566bd9b71fb54fe77e947b061a12

URL: https://github.com/llvm/llvm-project/commit/e3a7f0e2f9ab566bd9b71fb54fe77e947b061a12
DIFF: https://github.com/llvm/llvm-project/commit/e3a7f0e2f9ab566bd9b71fb54fe77e947b061a12.diff

LOG: [AArch64][PAC] Select llvm.ptrauth.sign/sign.generic to PAC*.

The @llvm.ptrauth.sign/sign.generic intrinsics map cleanly to
the various AArch64 PAC[IDG][Z][AB] instructions.  Select them.

Differential Revision: https://reviews.llvm.org/D91087

Added: 
    llvm/test/CodeGen/AArch64/ptrauth-intrinsic-sign-generic.ll
    llvm/test/CodeGen/AArch64/ptrauth-intrinsic-sign.ll

Modified: 
    llvm/lib/Target/AArch64/AArch64InstrFormats.td
    llvm/lib/Target/AArch64/AArch64InstrInfo.td
    llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 056ef33466bab..cd4bc8a61a8af 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -2012,10 +2012,10 @@ class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
   let Inst{31} = 1;
 }
 
-class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm>
-  : I<(outs GPR64:$Rd), (ins GPR64:$src, GPR64sp:$Rn), asm, "\t$Rd, $Rn",
-      "$Rd = $src",
-      []>,
+class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm,
+                      SDPatternOperator op>
+  : I<(outs GPR64:$dst), (ins GPR64:$Rd, GPR64sp:$Rn), asm, "\t$Rd, $Rn",
+      "$dst = $Rd", [(set GPR64:$dst, (op GPR64:$Rd, opcode, GPR64sp:$Rn))]>,
     Sched<[WriteI, ReadI]> {
   bits<5> Rd;
   bits<5> Rn;
@@ -2026,9 +2026,11 @@ class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm>
   let Inst{4-0} = Rd;
 }
 
-class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm>
-  : I<(outs GPR64:$Rd), (ins GPR64:$src), asm, "\t$Rd", "$Rd = $src",
-      []>, Sched<[]> {
+class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm,
+                   SDPatternOperator op>
+  : I<(outs GPR64:$dst), (ins GPR64:$Rd), asm, "\t$Rd", "$dst = $Rd",
+      [(set GPR64:$dst, (op GPR64:$Rd, opcode, (i64 0)))]>,
+    Sched<[]> {
   bits<5> Rd;
   let Inst{31-15} = 0b11011010110000010;
   let Inst{14-12} = opcode_prefix;

diff  --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 3d8826f6b2278..db8e0c5dac4a4 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -1215,23 +1215,25 @@ let Predicates = [HasPAuth] in {
   def : InstAlias<"autib1716", (AUTIB1716), 1>;
   def : InstAlias<"xpaclri", (XPACLRI), 1>;
 
-  multiclass SignAuth<bits<3> prefix, bits<3> prefix_z, string asm> {
-    def IA   : SignAuthOneData<prefix, 0b00, !strconcat(asm, "ia")>;
-    def IB   : SignAuthOneData<prefix, 0b01, !strconcat(asm, "ib")>;
-    def DA   : SignAuthOneData<prefix, 0b10, !strconcat(asm, "da")>;
-    def DB   : SignAuthOneData<prefix, 0b11, !strconcat(asm, "db")>;
-    def IZA  : SignAuthZero<prefix_z, 0b00, !strconcat(asm, "iza")>;
-    def DZA  : SignAuthZero<prefix_z, 0b10, !strconcat(asm, "dza")>;
-    def IZB  : SignAuthZero<prefix_z, 0b01, !strconcat(asm, "izb")>;
-    def DZB  : SignAuthZero<prefix_z, 0b11, !strconcat(asm, "dzb")>;
+  multiclass SignAuth<bits<3> prefix, bits<3> prefix_z, string asm,
+                      SDPatternOperator op> {
+    def IA   : SignAuthOneData<prefix, 0b00, !strconcat(asm,  "ia"), op>;
+    def IB   : SignAuthOneData<prefix, 0b01, !strconcat(asm,  "ib"), op>;
+    def DA   : SignAuthOneData<prefix, 0b10, !strconcat(asm,  "da"), op>;
+    def DB   : SignAuthOneData<prefix, 0b11, !strconcat(asm,  "db"), op>;
+    def IZA  : SignAuthZero<prefix_z,  0b00, !strconcat(asm, "iza"), op>;
+    def DZA  : SignAuthZero<prefix_z,  0b10, !strconcat(asm, "dza"), op>;
+    def IZB  : SignAuthZero<prefix_z,  0b01, !strconcat(asm, "izb"), op>;
+    def DZB  : SignAuthZero<prefix_z,  0b11, !strconcat(asm, "dzb"), op>;
   }
 
-  defm PAC : SignAuth<0b000, 0b010, "pac">;
-  defm AUT : SignAuth<0b001, 0b011, "aut">;
+  defm PAC : SignAuth<0b000, 0b010, "pac", int_ptrauth_sign>;
+  defm AUT : SignAuth<0b001, 0b011, "aut", null_frag>;
 
   def XPACI : ClearAuth<0, "xpaci">;
   def XPACD : ClearAuth<1, "xpacd">;
-  def PACGA : SignAuthTwoOperand<0b1100, "pacga", null_frag>;
+
+  def PACGA : SignAuthTwoOperand<0b1100, "pacga", int_ptrauth_sign_generic>;
 
   // Combined Instructions
   let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1  in {

diff  --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index da9bd112442aa..e090d87d59a2e 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -5435,6 +5435,33 @@ bool AArch64InstructionSelector::selectIntrinsic(MachineInstr &I,
     I.eraseFromParent();
     return true;
   }
+  case Intrinsic::ptrauth_sign: {
+    Register DstReg = I.getOperand(0).getReg();
+    Register ValReg = I.getOperand(2).getReg();
+    uint64_t Key = I.getOperand(3).getImm();
+    Register DiscReg = I.getOperand(4).getReg();
+    auto DiscVal = getIConstantVRegVal(DiscReg, MRI);
+    bool IsDiscZero = DiscVal.hasValue() && DiscVal->isNullValue();
+
+    if (Key > 3)
+      return false;
+
+    unsigned Opcodes[][4] = {
+        {AArch64::PACIA, AArch64::PACIB, AArch64::PACDA, AArch64::PACDB},
+        {AArch64::PACIZA, AArch64::PACIZB, AArch64::PACDZA, AArch64::PACDZB}};
+    unsigned Opcode = Opcodes[IsDiscZero][Key];
+
+    auto PAC = MIB.buildInstr(Opcode, {DstReg}, {ValReg});
+
+    if (!IsDiscZero) {
+      PAC.addUse(DiscReg);
+      RBI.constrainGenericRegister(DiscReg, AArch64::GPR64spRegClass, MRI);
+    }
+
+    RBI.constrainGenericRegister(DstReg, AArch64::GPR64RegClass, MRI);
+    I.eraseFromParent();
+    return true;
+  }
   case Intrinsic::frameaddress:
   case Intrinsic::returnaddress: {
     MachineFunction &MF = *I.getParent()->getParent();

diff  --git a/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-sign-generic.ll b/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-sign-generic.ll
new file mode 100644
index 0000000000000..1f14f67926f77
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-sign-generic.ll
@@ -0,0 +1,14 @@
+; 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
+
+define i64 @test_sign_generic(i64 %arg, i64 %arg1) {
+; CHECK-LABEL: test_sign_generic:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    pacga x0, x0, x1
+; CHECK-NEXT:    ret
+  %tmp = call i64 @llvm.ptrauth.sign.generic(i64 %arg, i64 %arg1)
+  ret i64 %tmp
+}
+
+declare i64 @llvm.ptrauth.sign.generic(i64, i64)

diff  --git a/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-sign.ll b/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-sign.ll
new file mode 100644
index 0000000000000..340a3530a5f5b
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/ptrauth-intrinsic-sign.ll
@@ -0,0 +1,77 @@
+; 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
+
+define i64 @test_sign_ia(i64 %arg, i64 %arg1) {
+; CHECK-LABEL: test_sign_ia:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    pacia x0, x1
+; CHECK-NEXT:    ret
+  %tmp = call i64 @llvm.ptrauth.sign(i64 %arg, i32 0, i64 %arg1)
+  ret i64 %tmp
+}
+
+define i64 @test_sign_ia_zero(i64 %arg) {
+; CHECK-LABEL: test_sign_ia_zero:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    paciza x0
+; CHECK-NEXT:    ret
+  %tmp = call i64 @llvm.ptrauth.sign(i64 %arg, i32 0, i64 0)
+  ret i64 %tmp
+}
+
+define i64 @test_sign_ib(i64 %arg, i64 %arg1) {
+; CHECK-LABEL: test_sign_ib:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    pacib x0, x1
+; CHECK-NEXT:    ret
+  %tmp = call i64 @llvm.ptrauth.sign(i64 %arg, i32 1, i64 %arg1)
+  ret i64 %tmp
+}
+
+define i64 @test_sign_ib_zero(i64 %arg) {
+; CHECK-LABEL: test_sign_ib_zero:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    pacizb x0
+; CHECK-NEXT:    ret
+  %tmp = call i64 @llvm.ptrauth.sign(i64 %arg, i32 1, i64 0)
+  ret i64 %tmp
+}
+
+define i64 @test_sign_da(i64 %arg, i64 %arg1) {
+; CHECK-LABEL: test_sign_da:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    pacda x0, x1
+; CHECK-NEXT:    ret
+  %tmp = call i64 @llvm.ptrauth.sign(i64 %arg, i32 2, i64 %arg1)
+  ret i64 %tmp
+}
+
+define i64 @test_sign_da_zero(i64 %arg) {
+; CHECK-LABEL: test_sign_da_zero:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    pacdza x0
+; CHECK-NEXT:    ret
+  %tmp = call i64 @llvm.ptrauth.sign(i64 %arg, i32 2, i64 0)
+  ret i64 %tmp
+}
+
+define i64 @test_sign_db(i64 %arg, i64 %arg1) {
+; CHECK-LABEL: test_sign_db:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    pacdb x0, x1
+; CHECK-NEXT:    ret
+  %tmp = call i64 @llvm.ptrauth.sign(i64 %arg, i32 3, i64 %arg1)
+  ret i64 %tmp
+}
+
+define i64 @test_sign_db_zero(i64 %arg) {
+; CHECK-LABEL: test_sign_db_zero:
+; CHECK:       ; %bb.0:
+; CHECK-NEXT:    pacdzb x0
+; CHECK-NEXT:    ret
+  %tmp = call i64 @llvm.ptrauth.sign(i64 %arg, i32 3, i64 0)
+  ret i64 %tmp
+}
+
+declare i64 @llvm.ptrauth.sign(i64, i32, i64)


        


More information about the llvm-commits mailing list