Skip to content

Commit 6d9505b

Browse files
committed
[AArch64][GlobalISel] Support for folding G_ROTR as shifted operands.
This allows selection like: eor w0, w1, w2, ror #8 Saves 500 bytes on ClamAV -Os, which is 0.1%. Differential Revision: https://reviews.llvm.org/D109206
1 parent d0f9553 commit 6d9505b

File tree

2 files changed

+76
-12
lines changed

2 files changed

+76
-12
lines changed

llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -379,18 +379,15 @@ class AArch64InstructionSelector : public InstructionSelector {
379379
return selectAddrModeWRO(Root, Width / 8);
380380
}
381381

382-
ComplexRendererFns selectShiftedRegister(MachineOperand &Root) const;
382+
ComplexRendererFns selectShiftedRegister(MachineOperand &Root,
383+
bool AllowROR = false) const;
383384

384385
ComplexRendererFns selectArithShiftedRegister(MachineOperand &Root) const {
385386
return selectShiftedRegister(Root);
386387
}
387388

388389
ComplexRendererFns selectLogicalShiftedRegister(MachineOperand &Root) const {
389-
// TODO: selectShiftedRegister should allow for rotates on logical shifts.
390-
// For now, make them the same. The only difference between the two is that
391-
// logical shifts are allowed to fold in rotates. Otherwise, these are
392-
// functionally the same.
393-
return selectShiftedRegister(Root);
390+
return selectShiftedRegister(Root, true);
394391
}
395392

396393
/// Given an extend instruction, determine the correct shift-extend type for
@@ -6014,7 +6011,6 @@ AArch64InstructionSelector::selectAddrModeIndexed(MachineOperand &Root,
60146011
/// Given a shift instruction, return the correct shift type for that
60156012
/// instruction.
60166013
static AArch64_AM::ShiftExtendType getShiftTypeForInst(MachineInstr &MI) {
6017-
// TODO: Handle AArch64_AM::ROR
60186014
switch (MI.getOpcode()) {
60196015
default:
60206016
return AArch64_AM::InvalidShiftExtend;
@@ -6024,30 +6020,31 @@ static AArch64_AM::ShiftExtendType getShiftTypeForInst(MachineInstr &MI) {
60246020
return AArch64_AM::LSR;
60256021
case TargetOpcode::G_ASHR:
60266022
return AArch64_AM::ASR;
6023+
case TargetOpcode::G_ROTR:
6024+
return AArch64_AM::ROR;
60276025
}
60286026
}
60296027

60306028
/// Select a "shifted register" operand. If the value is not shifted, set the
60316029
/// shift operand to a default value of "lsl 0".
6032-
///
6033-
/// TODO: Allow shifted register to be rotated in logical instructions.
60346030
InstructionSelector::ComplexRendererFns
6035-
AArch64InstructionSelector::selectShiftedRegister(MachineOperand &Root) const {
6031+
AArch64InstructionSelector::selectShiftedRegister(MachineOperand &Root,
6032+
bool AllowROR) const {
60366033
if (!Root.isReg())
60376034
return None;
60386035
MachineRegisterInfo &MRI =
60396036
Root.getParent()->getParent()->getParent()->getRegInfo();
60406037

60416038
// Check if the operand is defined by an instruction which corresponds to
60426039
// a ShiftExtendType. E.g. a G_SHL, G_LSHR, etc.
6043-
//
6044-
// TODO: Handle AArch64_AM::ROR for logical instructions.
60456040
MachineInstr *ShiftInst = MRI.getVRegDef(Root.getReg());
60466041
if (!ShiftInst)
60476042
return None;
60486043
AArch64_AM::ShiftExtendType ShType = getShiftTypeForInst(*ShiftInst);
60496044
if (ShType == AArch64_AM::InvalidShiftExtend)
60506045
return None;
6046+
if (ShType == AArch64_AM::ROR && !AllowROR)
6047+
return None;
60516048
if (!isWorthFoldingIntoExtendedReg(*ShiftInst, MRI))
60526049
return None;
60536050

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=aarch64-unknown-unknown -verify-machineinstrs -run-pass=instruction-select -global-isel-abort=1 %s -o - | FileCheck %s
3+
---
4+
name: fold_ror_eor
5+
alignment: 4
6+
legalized: true
7+
regBankSelected: true
8+
tracksRegLiveness: true
9+
liveins:
10+
- { reg: '$w0' }
11+
body: |
12+
bb.1.entry:
13+
liveins: $w0
14+
15+
; Our codegen differs from SDAG here, we decide to fold in LHS
16+
; operand instead of RHS since they're both rotates and XOR is commutative.
17+
; Either is valid.
18+
19+
; CHECK-LABEL: name: fold_ror_eor
20+
; CHECK: liveins: $w0
21+
; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
22+
; CHECK: [[EXTRWrri:%[0-9]+]]:gpr32 = EXTRWrri [[COPY]], [[COPY]], 11
23+
; CHECK: [[EORWrs:%[0-9]+]]:gpr32 = EORWrs [[EXTRWrri]], [[COPY]], 198
24+
; CHECK: $w0 = COPY [[EORWrs]]
25+
; CHECK: RET_ReallyLR implicit $w0
26+
%0:gpr(s32) = COPY $w0
27+
%13:gpr(s64) = G_CONSTANT i64 6
28+
%2:gpr(s32) = G_ROTR %0, %13(s64)
29+
%14:gpr(s64) = G_CONSTANT i64 11
30+
%4:gpr(s32) = G_ROTR %0, %14(s64)
31+
%5:gpr(s32) = G_XOR %2, %4
32+
$w0 = COPY %5(s32)
33+
RET_ReallyLR implicit $w0
34+
35+
...
36+
---
37+
name: fold_ror_eor_rhs_only
38+
alignment: 4
39+
legalized: true
40+
regBankSelected: true
41+
tracksRegLiveness: true
42+
liveins:
43+
- { reg: '$w0' }
44+
- { reg: '$w1' }
45+
frameInfo:
46+
maxAlignment: 1
47+
machineFunctionInfo: {}
48+
body: |
49+
bb.1.entry:
50+
liveins: $w0, $w1
51+
52+
; CHECK-LABEL: name: fold_ror_eor_rhs_only
53+
; CHECK: liveins: $w0, $w1
54+
; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
55+
; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1
56+
; CHECK: [[EORWrs:%[0-9]+]]:gpr32 = EORWrs [[COPY1]], [[COPY]], 198
57+
; CHECK: $w0 = COPY [[EORWrs]]
58+
; CHECK: RET_ReallyLR implicit $w0
59+
%0:gpr(s32) = COPY $w0
60+
%1:gpr(s32) = COPY $w1
61+
%9:gpr(s64) = G_CONSTANT i64 6
62+
%3:gpr(s32) = G_ROTR %0, %9(s64)
63+
%4:gpr(s32) = G_XOR %1, %3
64+
$w0 = COPY %4(s32)
65+
RET_ReallyLR implicit $w0
66+
67+
...

0 commit comments

Comments
 (0)