From 2a7788b957abef8bd240e7b8db900656fed7fb58 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Wed, 18 Sep 2024 09:41:02 +0300 Subject: [PATCH] [PAC][CodeGen] Do not emit trivial 'mov xN xN' on tail call Under some conditions, a trivial `mov xN xN` instruction was emitted on tail calls. Consider the following code: ``` class Test { public: virtual void f() {} }; void call_f(Test *t) { t->f(); } ``` Correponding assembly: ``` _Z6call_fP4Test: ldr x16, [x0] mov x17, x0 movk x17, #6503, lsl #48 autda x16, x17 ldr x1, [x16] =====> mov x16, x16 movk x16, #54167, lsl #48 braa x1, x16 ``` This patch makes such movs being omitted. Co-authored-by: Anatoly Trosinenko --- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 11 +++++----- llvm/test/CodeGen/AArch64/ptrauth-call.ll | 22 +++++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index b8f9b58a216446..c6e88131d5a343 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -2510,11 +2510,12 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) { unsigned DiscReg = AddrDisc; if (Disc) { if (AddrDisc != AArch64::NoRegister) { - EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::ORRXrs) - .addReg(ScratchReg) - .addReg(AArch64::XZR) - .addReg(AddrDisc) - .addImm(0)); + if (ScratchReg != AddrDisc) + EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::ORRXrs) + .addReg(ScratchReg) + .addReg(AArch64::XZR) + .addReg(AddrDisc) + .addImm(0)); EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::MOVKXi) .addReg(ScratchReg) .addReg(ScratchReg) diff --git a/llvm/test/CodeGen/AArch64/ptrauth-call.ll b/llvm/test/CodeGen/AArch64/ptrauth-call.ll index 9f211b6e1796e6..c3a2a2b0431300 100644 --- a/llvm/test/CodeGen/AArch64/ptrauth-call.ll +++ b/llvm/test/CodeGen/AArch64/ptrauth-call.ll @@ -167,6 +167,28 @@ define i32 @test_tailcall_ib_var(ptr %arg0, ptr %arg1) #0 { ret i32 %tmp1 } +define void @test_tailcall_omit_mov_x16_x16(ptr %t) { +; CHECK-LABEL: test_tailcall_omit_mov_x16_x16: +; CHECK: ldr x16, [x0] +; CHECK: mov x17, x0 +; CHECK: movk x17, #6503, lsl #48 +; CHECK: autda x16, x17 +; CHECK: ldr x1, [x16] +; CHECK: movk x16, #54167, lsl #48 +; CHECK: braa x1, x16 +entry: + %vtable = load ptr, ptr %t, align 8 + %0 = ptrtoint ptr %t to i64 + %1 = tail call i64 @llvm.ptrauth.blend(i64 %0, i64 6503) + %2 = ptrtoint ptr %vtable to i64 + %3 = tail call i64 @llvm.ptrauth.auth(i64 %2, i32 2, i64 %1) + %4 = inttoptr i64 %3 to ptr + %5 = load ptr, ptr %4, align 8 + %6 = tail call i64 @llvm.ptrauth.blend(i64 %3, i64 54167) + tail call void %5(ptr %t) [ "ptrauth"(i32 0, i64 %6) ] + ret void +} + define i32 @test_call_ia_arg(ptr %arg0, i64 %arg1) #0 { ; DARWIN-LABEL: test_call_ia_arg: ; DARWIN-NEXT: stp x29, x30, [sp, #-16]!