diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -1904,9 +1904,10 @@ let Inst{31} = 1; } -class SignAuthOneData opcode_prefix, bits<2> opcode, string asm> - : I<(outs GPR64:$Rd), (ins GPR64sp:$Rn), asm, "\t$Rd, $Rn", "", - []>, +class SignAuthOneData opcode_prefix, bits<2> opcode, string asm, + Intrinsic 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; @@ -1917,8 +1918,11 @@ let Inst{4-0} = Rd; } -class SignAuthZero opcode_prefix, bits<2> opcode, string asm> - : I<(outs GPR64:$Rd), (ins), asm, "\t$Rd", "", []>, Sched<[]> { +class SignAuthZero 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 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -1007,23 +1007,25 @@ def : InstAlias<"autib1716", (AUTIB1716), 1>; def : InstAlias<"xpaclri", (XPACLRI), 1>; - multiclass SignAuth prefix, bits<3> prefix_z, string asm> { - def IA : SignAuthOneData; - def IB : SignAuthOneData; - def DA : SignAuthOneData; - def DB : SignAuthOneData; - def IZA : SignAuthZero; - def DZA : SignAuthZero; - def IZB : SignAuthZero; - def DZB : SignAuthZero; + multiclass SignAuth prefix, bits<3> prefix_z, string asm, + Intrinsic op> { + def IA : SignAuthOneData; + def IB : SignAuthOneData; + def DA : SignAuthOneData; + def DB : SignAuthOneData; + def IZA : SignAuthZero; + def DZA : SignAuthZero; + def IZB : SignAuthZero; + def DZB : SignAuthZero; } - 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/test/CodeGen/AArch64/GlobalISel/ptrauth-intrinsics.ll b/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-intrinsics.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-intrinsics.ll @@ -0,0 +1,89 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple arm64e-apple-darwin -global-isel -global-isel-abort=1 \ +; RUN: | FileCheck %s --check-prefixes=ALL + +target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" + +define i64 @test_sign_ia(i64 %arg, i64 %arg1) { +; ALL-LABEL: test_sign_ia: +; ALL: ; %bb.0: +; ALL-NEXT: pacia x0, x1 +; ALL-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) { +; ALL-LABEL: test_sign_ia_zero: +; ALL: ; %bb.0: +; ALL-NEXT: paciza x0 +; ALL-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) { +; ALL-LABEL: test_sign_ib: +; ALL: ; %bb.0: +; ALL-NEXT: pacib x0, x1 +; ALL-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) { +; ALL-LABEL: test_sign_ib_zero: +; ALL: ; %bb.0: +; ALL-NEXT: pacizb x0 +; ALL-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) { +; ALL-LABEL: test_sign_da: +; ALL: ; %bb.0: +; ALL-NEXT: pacda x0, x1 +; ALL-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) { +; ALL-LABEL: test_sign_da_zero: +; ALL: ; %bb.0: +; ALL-NEXT: pacdza x0 +; ALL-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) { +; ALL-LABEL: test_sign_db: +; ALL: ; %bb.0: +; ALL-NEXT: pacdb x0, x1 +; ALL-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) { +; ALL-LABEL: test_sign_db_zero: +; ALL: ; %bb.0: +; ALL-NEXT: pacdzb x0 +; ALL-NEXT: ret + %tmp = call i64 @llvm.ptrauth.sign(i64 %arg, i32 3, i64 0) + ret i64 %tmp +} + +define i64 @test_sign_generic(i64 %arg, i64 %arg1) { +; ALL-LABEL: test_sign_generic: +; ALL: ; %bb.0: +; ALL-NEXT: pacga x0, x0, x1 +; ALL-NEXT: ret + %tmp = call i64 @llvm.ptrauth.sign.generic(i64 %arg, i64 %arg1) + ret i64 %tmp +} + +declare i64 @llvm.ptrauth.sign(i64, i32, i64) +declare i64 @llvm.ptrauth.sign.generic(i64, i64) diff --git a/llvm/test/CodeGen/AArch64/ptrauth-intrinsics.ll b/llvm/test/CodeGen/AArch64/ptrauth-intrinsics.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/ptrauth-intrinsics.ll @@ -0,0 +1,100 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple arm64e-apple-darwin -verify-machineinstrs | FileCheck %s --check-prefixes=ALL + +target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" + +define i64 @test_sign_ia(i64 %arg, i64 %arg1) { +; ALL-LABEL: test_sign_ia: +; ALL: ; %bb.0: +; ALL-NEXT: pacia x0, x1 +; ALL-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) { +; ALL-LABEL: test_sign_ia_zero: +; ALL: ; %bb.0: +; ALL-NEXT: paciza x0 +; ALL-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) { +; ALL-LABEL: test_sign_ib: +; ALL: ; %bb.0: +; ALL-NEXT: pacib x0, x1 +; ALL-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) { +; ALL-LABEL: test_sign_ib_zero: +; ALL: ; %bb.0: +; ALL-NEXT: pacizb x0 +; ALL-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) { +; ALL-LABEL: test_sign_da: +; ALL: ; %bb.0: +; ALL-NEXT: pacda x0, x1 +; ALL-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) { +; ALL-LABEL: test_sign_da_zero: +; ALL: ; %bb.0: +; ALL-NEXT: pacdza x0 +; ALL-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) { +; ALL-LABEL: test_sign_db: +; ALL: ; %bb.0: +; ALL-NEXT: pacdb x0, x1 +; ALL-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) { +; ALL-LABEL: test_sign_db_zero: +; ALL: ; %bb.0: +; ALL-NEXT: pacdzb x0 +; ALL-NEXT: ret + %tmp = call i64 @llvm.ptrauth.sign(i64 %arg, i32 3, i64 0) + ret i64 %tmp +} + +define i64 @test_sign_generic(i64 %arg, i64 %arg1) { +; ALL-LABEL: test_sign_generic: +; ALL: ; %bb.0: +; ALL-NEXT: pacga x0, x0, x1 +; ALL-NEXT: ret + %tmp = call i64 @llvm.ptrauth.sign.generic(i64 %arg, i64 %arg1) + ret i64 %tmp +} + +define i64 @test_sign_cse(i64 %arg, i64 %arg1) { +; ALL-LABEL: test_sign_cse: +; ALL: ; %bb.0: +; ALL-NEXT: pacia x0, x1 +; ALL-NEXT: add x0, x0, x0 +; ALL-NEXT: ret + %tmp0 = call i64 @llvm.ptrauth.sign(i64 %arg, i32 0, i64 %arg1) + %tmp1 = call i64 @llvm.ptrauth.sign(i64 %arg, i32 0, i64 %arg1) + %tmp2 = add i64 %tmp0, %tmp1 + ret i64 %tmp2 +} + +declare i64 @llvm.ptrauth.sign(i64, i32, i64) +declare i64 @llvm.ptrauth.sign.generic(i64, i64)