Skip to content

Commit 728b18f

Browse files
author
Jessica Paquette
committed
[AArch64][GlobalISel] Select immediate modes for ADD when selecting G_GEP
Before, we weren't able to select things like this for G_GEP: add x0, x8, #8 And instead we'd materialize the 8. This teaches GISel to do that. It gives some considerable code size savings on 252.eon-- about 4%! Differential Revision: https://reviews.llvm.org/D65248 llvm-svn: 366959
1 parent 75c64a6 commit 728b18f

File tree

3 files changed

+87
-10
lines changed

3 files changed

+87
-10
lines changed

llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp

+35-2
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ class AArch64InstructionSelector : public InstructionSelector {
133133
MachineInstr *emitIntegerCompare(MachineOperand &LHS, MachineOperand &RHS,
134134
MachineOperand &Predicate,
135135
MachineIRBuilder &MIRBuilder) const;
136+
MachineInstr *emitADD(Register DefReg, MachineOperand &LHS, MachineOperand &RHS,
137+
MachineIRBuilder &MIRBuilder) const;
136138
MachineInstr *emitCMN(MachineOperand &LHS, MachineOperand &RHS,
137139
MachineIRBuilder &MIRBuilder) const;
138140
MachineInstr *emitTST(const Register &LHS, const Register &RHS,
@@ -1829,8 +1831,7 @@ bool AArch64InstructionSelector::select(MachineInstr &I,
18291831
return selectVectorSHL(I, MRI);
18301832
LLVM_FALLTHROUGH;
18311833
case TargetOpcode::G_OR:
1832-
case TargetOpcode::G_LSHR:
1833-
case TargetOpcode::G_GEP: {
1834+
case TargetOpcode::G_LSHR: {
18341835
// Reject the various things we don't support yet.
18351836
if (unsupportedBinOp(I, RBI, MRI, TRI))
18361837
return false;
@@ -1852,6 +1853,13 @@ bool AArch64InstructionSelector::select(MachineInstr &I,
18521853
return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
18531854
}
18541855

1856+
case TargetOpcode::G_GEP: {
1857+
MachineIRBuilder MIRBuilder(I);
1858+
emitADD(I.getOperand(0).getReg(), I.getOperand(1), I.getOperand(2),
1859+
MIRBuilder);
1860+
I.eraseFromParent();
1861+
return true;
1862+
}
18551863
case TargetOpcode::G_UADDO: {
18561864
// TODO: Support other types.
18571865
unsigned OpSize = Ty.getSizeInBits();
@@ -3080,6 +3088,31 @@ getInsertVecEltOpInfo(const RegisterBank &RB, unsigned EltSize) {
30803088
return std::make_pair(Opc, SubregIdx);
30813089
}
30823090

3091+
MachineInstr *
3092+
AArch64InstructionSelector::emitADD(Register DefReg, MachineOperand &LHS,
3093+
MachineOperand &RHS,
3094+
MachineIRBuilder &MIRBuilder) const {
3095+
assert(LHS.isReg() && RHS.isReg() && "Expected LHS and RHS to be registers!");
3096+
MachineRegisterInfo &MRI = MIRBuilder.getMF().getRegInfo();
3097+
static const unsigned OpcTable[2][2]{{AArch64::ADDXrr, AArch64::ADDXri},
3098+
{AArch64::ADDWrr, AArch64::ADDWri}};
3099+
bool Is32Bit = MRI.getType(LHS.getReg()).getSizeInBits() == 32;
3100+
auto ImmFns = selectArithImmed(RHS);
3101+
unsigned Opc = OpcTable[Is32Bit][ImmFns.hasValue()];
3102+
auto AddMI = MIRBuilder.buildInstr(Opc, {DefReg}, {LHS.getReg()});
3103+
3104+
// If we matched a valid constant immediate, add those operands.
3105+
if (ImmFns) {
3106+
for (auto &RenderFn : *ImmFns)
3107+
RenderFn(AddMI);
3108+
} else {
3109+
AddMI.addUse(RHS.getReg());
3110+
}
3111+
3112+
constrainSelectedInstRegOperands(*AddMI, TII, TRI, RBI);
3113+
return &*AddMI;
3114+
}
3115+
30833116
MachineInstr *
30843117
AArch64InstructionSelector::emitCMN(MachineOperand &LHS, MachineOperand &RHS,
30853118
MachineIRBuilder &MIRBuilder) const {

llvm/test/CodeGen/AArch64/GlobalISel/select.mir

+49-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
}
1212

1313
define i8* @gep(i8* %in) { ret i8* undef }
14+
define i8* @gep_no_constant(i8* %in) { ret i8* undef }
15+
define i8* @gep_bad_imm(i8* %in) { ret i8* undef }
1416

1517
define i8* @ptr_mask(i8* %in) { ret i8* undef }
1618

@@ -61,8 +63,7 @@ registers:
6163
- { id: 2, class: gpr }
6264

6365
# CHECK: body:
64-
# CHECK: %1:gpr64 = MOVi64imm 42
65-
# CHECK: %2:gpr64 = ADDXrr %0, %1
66+
# CHECK: %2:gpr64sp = ADDXri %0, 42, 0
6667
body: |
6768
bb.0:
6869
liveins: $x0
@@ -72,6 +73,52 @@ body: |
7273
$x0 = COPY %2(p0)
7374
...
7475

76+
---
77+
# CHECK-LABEL: name: gep_no_constant
78+
name: gep_no_constant
79+
legalized: true
80+
regBankSelected: true
81+
registers:
82+
- { id: 0, class: gpr }
83+
- { id: 1, class: gpr }
84+
- { id: 2, class: gpr }
85+
86+
# CHECK: body:
87+
# CHECK: %0:gpr64 = COPY $x0
88+
# CHECK: %1:gpr64 = COPY $x1
89+
# CHECK: %2:gpr64 = ADDXrr %0, %1
90+
body: |
91+
bb.0:
92+
liveins: $x0, $x1
93+
%0(p0) = COPY $x0
94+
%1(s64) = COPY $x1
95+
%2(p0) = G_GEP %0, %1(s64)
96+
$x0 = COPY %2(p0)
97+
...
98+
99+
---
100+
# CHECK-LABEL: name: gep_bad_imm
101+
name: gep_bad_imm
102+
legalized: true
103+
regBankSelected: true
104+
registers:
105+
- { id: 0, class: gpr }
106+
- { id: 1, class: gpr }
107+
- { id: 2, class: gpr }
108+
109+
# CHECK: body:
110+
# CHECK: %0:gpr64 = COPY $x0
111+
# CHECK: %1:gpr64 = MOVi64imm 10000
112+
# CHECK: %2:gpr64 = ADDXrr %0, %1
113+
body: |
114+
bb.0:
115+
liveins: $x0, $x1
116+
%0(p0) = COPY $x0
117+
%1(s64) = G_CONSTANT i64 10000
118+
%2(p0) = G_GEP %0, %1(s64)
119+
$x0 = COPY %2(p0)
120+
...
121+
75122
---
76123
# CHECK-LABEL: name: ptr_mask
77124
name: ptr_mask

llvm/test/CodeGen/AArch64/GlobalISel/swifterror.ll

+3-6
Original file line numberDiff line numberDiff line change
@@ -226,14 +226,11 @@ define float @foo_vararg(%swift_error** swifterror %error_ptr_ref, ...) {
226226
; CHECK-DAG: strb [[ID]], [x0, #8]
227227

228228
; First vararg
229-
; CHECK: ldr {{w[0-9]+}}, [x[[ARG1:[0-9]+]]]
229+
; CHECK: ldr {{w[0-9]+}}, [x[[ARG1:[0-9]+]]], #8
230230
; Second vararg
231-
; CHECK: mov [[EIGHT:x[0-9]+]], #8
232-
; CHECK: add x[[ARG2:[0-9]+]], x[[ARG1]], [[EIGHT]]
233-
; CHECK: ldr {{w[0-9]+}}, [x[[ARG2]]]
231+
; CHECK: ldr {{w[0-9]+}}, [x[[ARG1]]], #8
234232
; Third vararg
235-
; CHECK: add x[[ARG3:[0-9]+]], x[[ARG2]], [[EIGHT]]
236-
; CHECK: ldr {{w[0-9]+}}, [x[[ARG3]]]
233+
; CHECK: ldr {{w[0-9]+}}, [x[[ARG1]]], #8
237234

238235
; CHECK: mov x21, x0
239236
; CHECK-NOT: x21

0 commit comments

Comments
 (0)