Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

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

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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants