[llvm] ce1a0d8 - [AArch64] Optimize `MOV` to `ORR` when load symmetric constants (#86249)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Mon May 20 01:57:55 PDT 2024
Author: hanbeom
Date: 2024-05-20T09:57:50+01:00
New Revision: ce1a0d8ad380d12dc7ea001cfab3749bb23d445d
URL: https://github.com/llvm/llvm-project/commit/ce1a0d8ad380d12dc7ea001cfab3749bb23d445d
DIFF: https://github.com/llvm/llvm-project/commit/ce1a0d8ad380d12dc7ea001cfab3749bb23d445d.diff
LOG: [AArch64] Optimize `MOV` to `ORR` when load symmetric constants (#86249)
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
Added:
Modified:
llvm/lib/Target/AArch64/AArch64ExpandImm.cpp
llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
llvm/test/CodeGen/AArch64/movimm-expand-ldst.ll
llvm/test/CodeGen/AArch64/movimm-expand-ldst.mir
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64ExpandImm.cpp b/llvm/lib/Target/AArch64/AArch64ExpandImm.cpp
index a7d72b59b1d5a..98016271a9d00 100644
--- a/llvm/lib/Target/AArch64/AArch64ExpandImm.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ExpandImm.cpp
@@ -518,6 +518,14 @@ static inline void expandMOVImmSimple(uint64_t Imm, unsigned BitSize,
Insn.push_back({ Opc, Imm16,
AArch64_AM::getShifterImm(AArch64_AM::LSL, Shift) });
}
+
+ // Now, we get 16-bit divided Imm. If high and low bits are same in
+ // 32-bit, there is an opportunity to reduce instruction.
+ if (Insn.size() > 2 && (Imm >> 32) == (Imm & 0xffffffffULL)) {
+ for (int Size = Insn.size(); Size > 2; Size--)
+ Insn.pop_back();
+ Insn.push_back({AArch64::ORRXrs, 0, 32});
+ }
}
/// Expand a MOVi32imm or MOVi64imm pseudo instruction to one or more
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 82bba7b5f8540..b25ac96f97c7d 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
}
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