Skip to content

Commit ce1a0d8

Browse files
ParkHanbumdavemgreen
authored andcommitted
[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
1 parent 384bf54 commit ce1a0d8

File tree

4 files changed

+25
-8
lines changed

4 files changed

+25
-8
lines changed

llvm/lib/Target/AArch64/AArch64ExpandImm.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,14 @@ static inline void expandMOVImmSimple(uint64_t Imm, unsigned BitSize,
518518
Insn.push_back({ Opc, Imm16,
519519
AArch64_AM::getShifterImm(AArch64_AM::LSL, Shift) });
520520
}
521+
522+
// Now, we get 16-bit divided Imm. If high and low bits are same in
523+
// 32-bit, there is an opportunity to reduce instruction.
524+
if (Insn.size() > 2 && (Imm >> 32) == (Imm & 0xffffffffULL)) {
525+
for (int Size = Insn.size(); Size > 2; Size--)
526+
Insn.pop_back();
527+
Insn.push_back({AArch64::ORRXrs, 0, 32});
528+
}
521529
}
522530

523531
/// Expand a MOVi32imm or MOVi64imm pseudo instruction to one or more

llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,19 @@ bool AArch64ExpandPseudo::expandMOVImm(MachineBasicBlock &MBB,
168168
.addImm(I->Op2));
169169
}
170170
break;
171+
case AArch64::ORRWrs:
172+
case AArch64::ORRXrs: {
173+
Register DstReg = MI.getOperand(0).getReg();
174+
bool DstIsDead = MI.getOperand(0).isDead();
175+
MIBS.push_back(
176+
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(I->Opcode))
177+
.addReg(DstReg, RegState::Define |
178+
getDeadRegState(DstIsDead && LastItem) |
179+
RenamableState)
180+
.addReg(DstReg)
181+
.addReg(DstReg)
182+
.addImm(I->Op2));
183+
} break;
171184
case AArch64::ANDXri:
172185
case AArch64::EORXri:
173186
if (I->Op1 == 0) {

llvm/test/CodeGen/AArch64/movimm-expand-ldst.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ define i64 @test0x1234567812345678() {
66
; CHECK: // %bb.0:
77
; CHECK-NEXT: mov x0, #22136 // =0x5678
88
; CHECK-NEXT: movk x0, #4660, lsl #16
9-
; CHECK-NEXT: movk x0, #22136, lsl #32
10-
; CHECK-NEXT: movk x0, #4660, lsl #48
9+
; CHECK-NEXT: orr x0, x0, x0, lsl #32
1110
; CHECK-NEXT: ret
1211
ret i64 u0x1234567812345678
1312
}
@@ -17,8 +16,7 @@ define i64 @test0xff3456ffff3456ff() {
1716
; CHECK: // %bb.0:
1817
; CHECK-NEXT: mov x0, #22271 // =0x56ff
1918
; CHECK-NEXT: movk x0, #65332, lsl #16
20-
; CHECK-NEXT: movk x0, #22271, lsl #32
21-
; CHECK-NEXT: movk x0, #65332, lsl #48
19+
; CHECK-NEXT: orr x0, x0, x0, lsl #32
2220
; CHECK-NEXT: ret
2321
ret i64 u0xff3456ffff3456ff
2422
}

llvm/test/CodeGen/AArch64/movimm-expand-ldst.mir

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ body: |
1111
; CHECK-NEXT: {{ $}}
1212
; CHECK-NEXT: renamable $x0 = MOVZXi 49370, 0
1313
; CHECK-NEXT: renamable $x0 = MOVKXi $x0, 320, 16
14-
; CHECK-NEXT: renamable $x0 = MOVKXi $x0, 49370, 32
15-
; CHECK-NEXT: renamable $x0 = MOVKXi $x0, 320, 48
14+
; CHECK-NEXT: renamable $x0 = ORRXrs $x0, $x0, 32
1615
; CHECK-NEXT: RET undef $lr, implicit $x0
1716
renamable $x0 = MOVi64imm 90284035103834330
1817
RET_ReallyLR implicit $x0
@@ -28,8 +27,7 @@ body: |
2827
; CHECK-NEXT: {{ $}}
2928
; CHECK-NEXT: renamable $x0 = MOVZXi 320, 0
3029
; CHECK-NEXT: renamable $x0 = MOVKXi $x0, 49370, 16
31-
; CHECK-NEXT: renamable $x0 = MOVKXi $x0, 320, 32
32-
; CHECK-NEXT: renamable $x0 = MOVKXi $x0, 49370, 48
30+
; CHECK-NEXT: renamable $x0 = ORRXrs $x0, $x0, 32
3331
; CHECK-NEXT: RET undef $lr, implicit $x0
3432
renamable $x0 = MOVi64imm -4550323095879417536
3533
RET_ReallyLR implicit $x0

0 commit comments

Comments
 (0)