Skip to content

Commit

Permalink
[AArch64][PAC] Select llvm.ptrauth.sign/sign.generic to PAC*.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ahmedbougacha committed Nov 18, 2021
1 parent 3b463c4 commit e3a7f0e
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 19 deletions.
16 changes: 9 additions & 7 deletions llvm/lib/Target/AArch64/AArch64InstrFormats.td
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
26 changes: 14 additions & 12 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.td
Expand Up @@ -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 {
Expand Down
27 changes: 27 additions & 0 deletions llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
Expand Up @@ -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();
Expand Down
14 changes: 14 additions & 0 deletions 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)
77 changes: 77 additions & 0 deletions 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)

0 comments on commit e3a7f0e

Please sign in to comment.