[llvm] [AArch64] Optimization of repeated constant loads (#51483) (PR #86249)

via llvm-commits llvm-commits at lists.llvm.org
Wed May 15 00:18:21 PDT 2024


https://github.com/ParkHanbum updated https://github.com/llvm/llvm-project/pull/86249

>From ead5047a84217f1d4edfc09c0b58312a26bd8fcb Mon Sep 17 00:00:00 2001
From: hanbeom <kese111 at gmail.com>
Date: Sun, 21 Apr 2024 18:41:21 +0900
Subject: [PATCH 1/2] [AArch64] Add PreTest for optimizing `MOV` to `ORR`

---
 .../CodeGen/AArch64/movimm-expand-ldst.ll     | 78 +++++++++++++++++++
 .../CodeGen/AArch64/movimm-expand-ldst.mir    | 35 +++++++++
 2 files changed, 113 insertions(+)
 create mode 100644 llvm/test/CodeGen/AArch64/movimm-expand-ldst.ll
 create mode 100644 llvm/test/CodeGen/AArch64/movimm-expand-ldst.mir

diff --git a/llvm/test/CodeGen/AArch64/movimm-expand-ldst.ll b/llvm/test/CodeGen/AArch64/movimm-expand-ldst.ll
new file mode 100644
index 0000000000000..35da221837510
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/movimm-expand-ldst.ll
@@ -0,0 +1,78 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc -mtriple=aarch64 %s -o - | FileCheck %s
+
+define i64 @test0x1234567812345678() {
+; CHECK-LABEL: test0x1234567812345678:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    mov x0, #22136 // =0x5678
+; CHECK-NEXT:    movk x0, #4660, lsl #16
+; CHECK-NEXT:    movk x0, #22136, lsl #32
+; CHECK-NEXT:    movk x0, #4660, lsl #48
+; CHECK-NEXT:    ret
+  ret i64 u0x1234567812345678
+}
+
+define i64 @test0xff3456ffff3456ff() {
+; CHECK-LABEL: test0xff3456ffff3456ff:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    mov x0, #22271 // =0x56ff
+; CHECK-NEXT:    movk x0, #65332, lsl #16
+; CHECK-NEXT:    movk x0, #22271, lsl #32
+; CHECK-NEXT:    movk x0, #65332, lsl #48
+; CHECK-NEXT:    ret
+  ret i64 u0xff3456ffff3456ff
+}
+
+define i64 @test0x00345600345600() {
+; CHECK-LABEL: test0x00345600345600:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    mov x0, #22016 // =0x5600
+; CHECK-NEXT:    movk x0, #52, lsl #16
+; CHECK-NEXT:    movk x0, #13398, lsl #32
+; CHECK-NEXT:    ret
+  ret i64 u0x00345600345600
+}
+
+define i64 @test0x5555555555555555() {
+; CHECK-LABEL: test0x5555555555555555:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    mov x0, #6148914691236517205 // =0x5555555555555555
+; CHECK-NEXT:    ret
+  ret i64 u0x5555555555555555
+}
+
+define i64 @test0x5055555550555555() {
+; CHECK-LABEL: test0x5055555550555555:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    mov x0, #6148914691236517205 // =0x5555555555555555
+; CHECK-NEXT:    and x0, x0, #0xf0fffffff0ffffff
+; CHECK-NEXT:    ret
+  ret i64 u0x5055555550555555
+}
+
+define i64 @test0x0000555555555555() {
+; CHECK-LABEL: test0x0000555555555555:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    mov x0, #6148914691236517205 // =0x5555555555555555
+; CHECK-NEXT:    movk x0, #0, lsl #48
+; CHECK-NEXT:    ret
+  ret i64 u0x0000555555555555
+}
+
+define i64 @test0x0000555500005555() {
+; CHECK-LABEL: test0x0000555500005555:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    mov x0, #21845 // =0x5555
+; CHECK-NEXT:    movk x0, #21845, lsl #32
+; CHECK-NEXT:    ret
+  ret i64 u0x0000555500005555
+}
+
+define i64 @testu0xffff5555ffff5555() {
+; CHECK-LABEL: testu0xffff5555ffff5555:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    mov x0, #-43691 // =0xffffffffffff5555
+; CHECK-NEXT:    movk x0, #21845, lsl #32
+; CHECK-NEXT:    ret
+  ret i64 u0xffff5555ffff5555
+}
diff --git a/llvm/test/CodeGen/AArch64/movimm-expand-ldst.mir b/llvm/test/CodeGen/AArch64/movimm-expand-ldst.mir
new file mode 100644
index 0000000000000..de14437108c93
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/movimm-expand-ldst.mir
@@ -0,0 +1,35 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
+# RUN: llc -mtriple=aarch64 -verify-machineinstrs -run-pass=aarch64-expand-pseudo -run-pass=aarch64-ldst-opt -debug-only=aarch64-ldst-opt %s -o - | FileCheck %s
+---
+name: test_fold_repeating_constant_load
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $x0
+    ; CHECK-LABEL: name: test_fold_repeating_constant_load
+    ; CHECK: liveins: $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: renamable $x0 = MOVZXi 49370, 0
+    ; CHECK-NEXT: renamable $x0 = MOVKXi $x0, 320, 16
+    ; CHECK-NEXT: renamable $x0 = MOVKXi $x0, 49370, 32
+    ; CHECK-NEXT: renamable $x0 = MOVKXi $x0, 320, 48
+    ; CHECK-NEXT: RET undef $lr, implicit $x0
+    renamable $x0 = MOVi64imm 90284035103834330
+    RET_ReallyLR implicit $x0
+...
+---
+name: test_fold_repeating_constant_load_neg
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $x0
+    ; CHECK-LABEL: name: test_fold_repeating_constant_load_neg
+    ; CHECK: liveins: $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: renamable $x0 = MOVZXi 320, 0
+    ; CHECK-NEXT: renamable $x0 = MOVKXi $x0, 49370, 16
+    ; CHECK-NEXT: renamable $x0 = MOVKXi $x0, 320, 32
+    ; CHECK-NEXT: renamable $x0 = MOVKXi $x0, 49370, 48
+    ; CHECK-NEXT: RET undef $lr, implicit $x0
+    renamable $x0 = MOVi64imm -4550323095879417536
+    RET_ReallyLR implicit $x0

>From 12e5abbb5e0a0dfb5166a5fafc1f4c34b1d59f92 Mon Sep 17 00:00:00 2001
From: hanbeom <kese111 at gmail.com>
Date: Fri, 12 Apr 2024 16:53:37 +0900
Subject: [PATCH 2/2] [AArch64] Optimize `MOV` to `ORR` when load symmetric
 constants (#51483)

This change looks for cases of symmetric constant loading.
`symmetric constant load` is when the upper 32 bits and lower 32 bits
of a 64-bit register load the same value.

When it finds this, it replaces it with an instruction that loads only
the lower 32 bits of the constant and stores it in the upper and lower
bits simultaneously.

For example:
  renamable $x8 = MOVZXi 49370, 0
  renamable $x8 = MOVKXi $x8, 320, 16
  renamable $x8 = MOVKXi $x8, 49370, 32
  renamable $x8 = MOVKXi $x8, 320, 48
becomes
  renamable $x8 = MOVZXi 49370, 0
  renamable $x8 = MOVKXi $x8, 320, 16
  renamable $x8 = ORRXrs $x8, $x8, 32
---
 llvm/lib/Target/AArch64/AArch64ExpandImm.cpp        | 10 ++++++++++
 .../lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp | 13 +++++++++++++
 llvm/test/CodeGen/AArch64/movimm-expand-ldst.ll     | 10 ++++------
 llvm/test/CodeGen/AArch64/movimm-expand-ldst.mir    |  6 ++----
 4 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ExpandImm.cpp b/llvm/lib/Target/AArch64/AArch64ExpandImm.cpp
index a7d72b59b1d5a..3d96c0619bfc0 100644
--- a/llvm/lib/Target/AArch64/AArch64ExpandImm.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ExpandImm.cpp
@@ -509,6 +509,16 @@ static inline void expandMOVImmSimple(uint64_t Imm, unsigned BitSize,
     Imm = ~Imm;
 
   unsigned Opc = (BitSize == 32 ? AArch64::MOVKWi : AArch64::MOVKXi);
+  Shift += 16;
+  Imm16 = (Imm >> Shift) & Mask;
+  if (Imm16 != (isNeg ? Mask : 0))
+    Insn.push_back(
+        {Opc, Imm16, AArch64_AM::getShifterImm(AArch64_AM::LSL, Shift)});
+  if (Imm != 0 && (Imm >> 32) == (Imm & UINT_MAX)) {
+    Insn.push_back({AArch64::ORRXrs, 0, 32});
+    return;
+  }
+
   while (Shift < LastShift) {
     Shift += 16;
     Imm16 = (Imm >> Shift) & Mask;
diff --git a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
index 03f0778bae59d..36957bb0f5a05 100644
--- a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
@@ -168,6 +168,19 @@ bool AArch64ExpandPseudo::expandMOVImm(MachineBasicBlock &MBB,
                 .addImm(I->Op2));
       }
       break;
+    case AArch64::ORRWrs:
+    case AArch64::ORRXrs: {
+      Register DstReg = MI.getOperand(0).getReg();
+      bool DstIsDead = MI.getOperand(0).isDead();
+      MIBS.push_back(
+          BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(I->Opcode))
+              .addReg(DstReg, RegState::Define |
+                                  getDeadRegState(DstIsDead && LastItem) |
+                                  RenamableState)
+              .addReg(DstReg)
+              .addReg(DstReg)
+              .addImm(I->Op2));
+    } break;
     case AArch64::ANDXri:
     case AArch64::EORXri:
       if (I->Op1 == 0) {
diff --git a/llvm/test/CodeGen/AArch64/movimm-expand-ldst.ll b/llvm/test/CodeGen/AArch64/movimm-expand-ldst.ll
index 35da221837510..01a03f88457f0 100644
--- a/llvm/test/CodeGen/AArch64/movimm-expand-ldst.ll
+++ b/llvm/test/CodeGen/AArch64/movimm-expand-ldst.ll
@@ -6,8 +6,7 @@ define i64 @test0x1234567812345678() {
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    mov x0, #22136 // =0x5678
 ; CHECK-NEXT:    movk x0, #4660, lsl #16
-; CHECK-NEXT:    movk x0, #22136, lsl #32
-; CHECK-NEXT:    movk x0, #4660, lsl #48
+; CHECK-NEXT:    orr x0, x0, x0, lsl #32
 ; CHECK-NEXT:    ret
   ret i64 u0x1234567812345678
 }
@@ -17,8 +16,7 @@ define i64 @test0xff3456ffff3456ff() {
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    mov x0, #22271 // =0x56ff
 ; CHECK-NEXT:    movk x0, #65332, lsl #16
-; CHECK-NEXT:    movk x0, #22271, lsl #32
-; CHECK-NEXT:    movk x0, #65332, lsl #48
+; CHECK-NEXT:    orr x0, x0, x0, lsl #32
 ; CHECK-NEXT:    ret
   ret i64 u0xff3456ffff3456ff
 }
@@ -63,7 +61,7 @@ define i64 @test0x0000555500005555() {
 ; CHECK-LABEL: test0x0000555500005555:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    mov x0, #21845 // =0x5555
-; CHECK-NEXT:    movk x0, #21845, lsl #32
+; CHECK-NEXT:    orr x0, x0, x0, lsl #32
 ; CHECK-NEXT:    ret
   ret i64 u0x0000555500005555
 }
@@ -72,7 +70,7 @@ define i64 @testu0xffff5555ffff5555() {
 ; CHECK-LABEL: testu0xffff5555ffff5555:
 ; CHECK:       // %bb.0:
 ; CHECK-NEXT:    mov x0, #-43691 // =0xffffffffffff5555
-; CHECK-NEXT:    movk x0, #21845, lsl #32
+; CHECK-NEXT:    orr x0, x0, x0, lsl #32
 ; CHECK-NEXT:    ret
   ret i64 u0xffff5555ffff5555
 }
diff --git a/llvm/test/CodeGen/AArch64/movimm-expand-ldst.mir b/llvm/test/CodeGen/AArch64/movimm-expand-ldst.mir
index de14437108c93..1ec2a00f67690 100644
--- a/llvm/test/CodeGen/AArch64/movimm-expand-ldst.mir
+++ b/llvm/test/CodeGen/AArch64/movimm-expand-ldst.mir
@@ -11,8 +11,7 @@ body:             |
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: renamable $x0 = MOVZXi 49370, 0
     ; CHECK-NEXT: renamable $x0 = MOVKXi $x0, 320, 16
-    ; CHECK-NEXT: renamable $x0 = MOVKXi $x0, 49370, 32
-    ; CHECK-NEXT: renamable $x0 = MOVKXi $x0, 320, 48
+    ; CHECK-NEXT: renamable $x0 = ORRXrs $x0, $x0, 32
     ; CHECK-NEXT: RET undef $lr, implicit $x0
     renamable $x0 = MOVi64imm 90284035103834330
     RET_ReallyLR implicit $x0
@@ -28,8 +27,7 @@ body:             |
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: renamable $x0 = MOVZXi 320, 0
     ; CHECK-NEXT: renamable $x0 = MOVKXi $x0, 49370, 16
-    ; CHECK-NEXT: renamable $x0 = MOVKXi $x0, 320, 32
-    ; CHECK-NEXT: renamable $x0 = MOVKXi $x0, 49370, 48
+    ; CHECK-NEXT: renamable $x0 = ORRXrs $x0, $x0, 32
     ; CHECK-NEXT: RET undef $lr, implicit $x0
     renamable $x0 = MOVi64imm -4550323095879417536
     RET_ReallyLR implicit $x0



More information about the llvm-commits mailing list