Skip to content

[PAC][CodeGen] Do not emit trivial 'mov xN, xN' on tail call #109100

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 3 commits into from
Sep 19, 2024

Conversation

kovdan01
Copy link
Contributor

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 atrosinenko@accesssoftek.com

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, llvm#6503, lsl llvm#48
        autda   x16, x17
        ldr     x1, [x16]
 =====> mov     x16, x16
        movk    x16, llvm#54167, lsl llvm#48
        braa    x1, x16
```

This patch makes such movs being omitted.

Co-authored-by: Anatoly Trosinenko <atrosinenko@accesssoftek.com>
@kovdan01 kovdan01 self-assigned this Sep 18, 2024
@kovdan01 kovdan01 marked this pull request as ready for review September 18, 2024 10:27
@llvmbot
Copy link
Member

llvmbot commented Sep 18, 2024

@llvm/pr-subscribers-backend-aarch64

Author: Daniil Kovalev (kovdan01)

Changes

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-&gt;f();
}

Correponding assembly:

_Z6call_fP4Test:
        ldr     x16, [x0]
        mov     x17, x0
        movk    x17, #<!-- -->6503, lsl #<!-- -->48
        autda   x16, x17
        ldr     x1, [x16]
 =====&gt; mov     x16, x16
        movk    x16, #<!-- -->54167, lsl #<!-- -->48
        braa    x1, x16

This patch makes such movs being omitted.

Co-authored-by: Anatoly Trosinenko <atrosinenko@accesssoftek.com>


Full diff: https://github.com/llvm/llvm-project/pull/109100.diff

2 Files Affected:

  • (modified) llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp (+6-5)
  • (modified) llvm/test/CodeGen/AArch64/ptrauth-call.ll (+22)
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]!

Copy link
Collaborator

@asl asl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Copy link
Contributor

@atrosinenko atrosinenko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@kovdan01 kovdan01 changed the title [PAC][CodeGen] Do not emit trivial 'mov xN xN' on tail call [PAC][CodeGen] Do not emit trivial 'mov xN, xN' on tail call Sep 19, 2024
@kovdan01 kovdan01 merged commit 3d5e8e4 into llvm:main Sep 19, 2024
8 checks passed
tmsri pushed a commit to tmsri/llvm-project that referenced this pull request Sep 19, 2024
…9100)

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, llvm#6503, lsl llvm#48
        autda   x16, x17
        ldr     x1, [x16]
 =====> mov     x16, x16
        movk    x16, llvm#54167, lsl llvm#48
        braa    x1, x16
```

This patch makes such movs being omitted.

Co-authored-by: Anatoly Trosinenko <atrosinenko@accesssoftek.com>
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants