Skip to content

Commit 50ac896

Browse files
committed
[RISCV][GISel] Custom promote s32 G_SHL/ASHR/LSHR on RV64.
Still to add custom isel to select SRAIW+SRLIW like SelectionDAG.
1 parent 552f6fe commit 50ac896

27 files changed

+1475
-1046
lines changed

llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -159,12 +159,11 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
159159
.lower();
160160

161161
getActionDefinitionsBuilder({G_ASHR, G_LSHR, G_SHL})
162-
.legalFor({{s32, s32}, {sXLen, sXLen}})
162+
.legalFor({{sXLen, sXLen}})
163+
.customFor(ST.is64Bit(), {{s32, s32}})
163164
.widenScalarToNextPow2(0)
164-
.clampScalar(1, s32, sXLen)
165-
.clampScalar(0, s32, sXLen)
166-
.minScalarSameAs(1, 0)
167-
.maxScalarSameAs(1, 0);
165+
.clampScalar(1, sXLen, sXLen)
166+
.clampScalar(0, sXLen, sXLen);
168167

169168
auto &ExtActions =
170169
getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT})
@@ -1171,6 +1170,12 @@ static unsigned getRISCVWOpcode(unsigned Opcode) {
11711170
switch (Opcode) {
11721171
default:
11731172
llvm_unreachable("Unexpected opcode");
1173+
case TargetOpcode::G_ASHR:
1174+
return RISCV::G_SRAW;
1175+
case TargetOpcode::G_LSHR:
1176+
return RISCV::G_SRLW;
1177+
case TargetOpcode::G_SHL:
1178+
return RISCV::G_SLLW;
11741179
case TargetOpcode::G_SDIV:
11751180
return RISCV::G_DIVW;
11761181
case TargetOpcode::G_UDIV:
@@ -1228,6 +1233,36 @@ bool RISCVLegalizerInfo::legalizeCustom(
12281233
return Helper.lower(MI, 0, /* Unused hint type */ LLT()) ==
12291234
LegalizerHelper::Legalized;
12301235
}
1236+
case TargetOpcode::G_ASHR:
1237+
case TargetOpcode::G_LSHR:
1238+
case TargetOpcode::G_SHL: {
1239+
Register AmtReg = MI.getOperand(2).getReg();
1240+
auto VRegAndVal = getIConstantVRegValWithLookThrough(AmtReg, MRI);
1241+
if (VRegAndVal) {
1242+
// We don't need a custom node for shift by constant. Just widen the
1243+
// source and the shift amount.
1244+
unsigned ExtOpc = TargetOpcode::G_ANYEXT;
1245+
if (MI.getOpcode() == TargetOpcode::G_ASHR)
1246+
ExtOpc = TargetOpcode::G_SEXT;
1247+
else if (MI.getOpcode() == TargetOpcode::G_LSHR)
1248+
ExtOpc = TargetOpcode::G_ZEXT;
1249+
1250+
Helper.Observer.changingInstr(MI);
1251+
Helper.widenScalarSrc(MI, sXLen, 1, ExtOpc);
1252+
Helper.widenScalarSrc(MI, sXLen, 2, TargetOpcode::G_ZEXT);
1253+
Helper.widenScalarDst(MI, sXLen);
1254+
Helper.Observer.changedInstr(MI);
1255+
return true;
1256+
}
1257+
1258+
Helper.Observer.changingInstr(MI);
1259+
Helper.widenScalarSrc(MI, sXLen, 1, TargetOpcode::G_ANYEXT);
1260+
Helper.widenScalarSrc(MI, sXLen, 2, TargetOpcode::G_ANYEXT);
1261+
Helper.widenScalarDst(MI, sXLen);
1262+
MI.setDesc(MIRBuilder.getTII().get(getRISCVWOpcode(MI.getOpcode())));
1263+
Helper.Observer.changedInstr(MI);
1264+
return true;
1265+
}
12311266
case TargetOpcode::G_SDIV:
12321267
case TargetOpcode::G_UDIV:
12331268
case TargetOpcode::G_UREM:

llvm/lib/Target/RISCV/RISCVGISel.td

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,15 @@ def : LdPat<load, LD, PtrVT>;
169169
def : StPat<store, SD, GPR, PtrVT>;
170170
}
171171

172+
let Predicates = [IsRV64] in {
173+
// FIXME: tblgen can't import sext_inreg patterns.
174+
def : Pat<(sra (sexti32 (i64 GPR:$rs1)), uimm5:$shamt),
175+
(SRAIW GPR:$rs1, uimm5:$shamt)>;
176+
// FIXME: Temporary until i32->i64 zext is no longer legal.
177+
def : Pat <(srl (zext GPR:$rs1), uimm5:$shamt),
178+
(SRLIW GPR:$rs1, uimm5:$shamt)>;
179+
}
180+
172181
//===----------------------------------------------------------------------===//
173182
// RV64 i32 patterns not used by SelectionDAG
174183
//===----------------------------------------------------------------------===//
@@ -201,9 +210,6 @@ def : PatGprGpr<sub, SUBW, i32, i32>;
201210
def : PatGprGpr<and, AND, i32, i32>;
202211
def : PatGprGpr<or, OR, i32, i32>;
203212
def : PatGprGpr<xor, XOR, i32, i32>;
204-
def : PatGprGpr<shl, SLLW, i32, i32>;
205-
def : PatGprGpr<srl, SRLW, i32, i32>;
206-
def : PatGprGpr<sra, SRAW, i32, i32>;
207213

208214
def : Pat<(i32 (add GPR:$rs1, simm12i32:$imm)),
209215
(ADDIW GPR:$rs1, (i64 (as_i64imm $imm)))>;
@@ -214,13 +220,6 @@ def : Pat<(i32 (or GPR:$rs1, simm12i32:$imm)),
214220
def : Pat<(i32 (xor GPR:$rs1, simm12i32:$imm)),
215221
(XORI GPR:$rs1, (i64 (as_i64imm $imm)))>;
216222

217-
def : Pat<(i32 (shl GPR:$rs1, uimm5i32:$imm)),
218-
(SLLIW GPR:$rs1, (i64 (as_i64imm $imm)))>;
219-
def : Pat<(i32 (srl GPR:$rs1, uimm5i32:$imm)),
220-
(SRLIW GPR:$rs1, (i64 (as_i64imm $imm)))>;
221-
def : Pat<(i32 (sra GPR:$rs1, uimm5i32:$imm)),
222-
(SRAIW GPR:$rs1, (i64 (as_i64imm $imm)))>;
223-
224223
def : Pat<(i32 (and GPR:$rs, TrailingOnesMask:$mask)),
225224
(SRLI (i32 (SLLI $rs, (i64 (XLenSubTrailingOnes $mask)))),
226225
(i64 (XLenSubTrailingOnes $mask)))>;
@@ -270,10 +269,4 @@ def : Pat<(shl (i64 (zext i32:$rs1)), uimm5:$shamt),
270269
def : Pat<(i64 (add_like_non_imm12 (zext GPR:$rs1), GPR:$rs2)),
271270
(ADD_UW GPR:$rs1, GPR:$rs2)>;
272271
def : Pat<(zext GPR:$src), (ADD_UW GPR:$src, (XLenVT X0))>;
273-
274-
foreach i = {1,2,3} in {
275-
defvar shxadd = !cast<Instruction>("SH"#i#"ADD");
276-
def : Pat<(i32 (add_like_non_imm12 (shl GPR:$rs1, (i32 i)), GPR:$rs2)),
277-
(shxadd GPR:$rs1, GPR:$rs2)>;
278-
}
279272
}

llvm/lib/Target/RISCV/RISCVInstrGISel.td

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,30 @@ class RISCVGenericInstruction : GenericInstruction {
1717
let Namespace = "RISCV";
1818
}
1919

20+
// Pseudo equivalent to a RISCVISD::SRAW.
21+
def G_SRAW : RISCVGenericInstruction {
22+
let OutOperandList = (outs type0:$dst);
23+
let InOperandList = (ins type0:$src1, type0:$src2);
24+
let hasSideEffects = false;
25+
}
26+
def : GINodeEquiv<G_SRAW, riscv_sraw>;
27+
28+
// Pseudo equivalent to a RISCVISD::SRLW.
29+
def G_SRLW : RISCVGenericInstruction {
30+
let OutOperandList = (outs type0:$dst);
31+
let InOperandList = (ins type0:$src1, type0:$src2);
32+
let hasSideEffects = false;
33+
}
34+
def : GINodeEquiv<G_SRLW, riscv_srlw>;
35+
36+
// Pseudo equivalent to a RISCVISD::SLLW.
37+
def G_SLLW : RISCVGenericInstruction {
38+
let OutOperandList = (outs type0:$dst);
39+
let InOperandList = (ins type0:$src1, type0:$src2);
40+
let hasSideEffects = false;
41+
}
42+
def : GINodeEquiv<G_SLLW, riscv_sllw>;
43+
2044
// Pseudo equivalent to a RISCVISD::DIVW.
2145
def G_DIVW : RISCVGenericInstruction {
2246
let OutOperandList = (outs type0:$dst);

llvm/test/CodeGen/RISCV/GlobalISel/alu-roundtrip.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ define i32 @slli_i32(i32 %a) {
168168
;
169169
; RV64IM-LABEL: slli_i32:
170170
; RV64IM: # %bb.0: # %entry
171-
; RV64IM-NEXT: slliw a0, a0, 11
171+
; RV64IM-NEXT: slli a0, a0, 11
172172
; RV64IM-NEXT: ret
173173
entry:
174174
%0 = shl i32 %a, 11

llvm/test/CodeGen/RISCV/GlobalISel/bitmanip.ll

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ define i2 @bitreverse_i2(i2 %x) {
1717
; RV64-NEXT: slli a1, a0, 1
1818
; RV64-NEXT: andi a1, a1, 2
1919
; RV64-NEXT: andi a0, a0, 3
20-
; RV64-NEXT: srliw a0, a0, 1
20+
; RV64-NEXT: srli a0, a0, 1
2121
; RV64-NEXT: or a0, a1, a0
2222
; RV64-NEXT: ret
2323
%rev = call i2 @llvm.bitreverse.i2(i2 %x)
@@ -43,7 +43,7 @@ define i3 @bitreverse_i3(i3 %x) {
4343
; RV64-NEXT: andi a0, a0, 7
4444
; RV64-NEXT: andi a2, a0, 2
4545
; RV64-NEXT: or a1, a1, a2
46-
; RV64-NEXT: srliw a0, a0, 2
46+
; RV64-NEXT: srli a0, a0, 2
4747
; RV64-NEXT: or a0, a1, a0
4848
; RV64-NEXT: ret
4949
%rev = call i3 @llvm.bitreverse.i3(i3 %x)
@@ -74,10 +74,10 @@ define i4 @bitreverse_i4(i4 %x) {
7474
; RV64-NEXT: andi a2, a2, 4
7575
; RV64-NEXT: or a1, a1, a2
7676
; RV64-NEXT: andi a0, a0, 15
77-
; RV64-NEXT: srliw a2, a0, 1
77+
; RV64-NEXT: srli a2, a0, 1
7878
; RV64-NEXT: andi a2, a2, 2
7979
; RV64-NEXT: or a1, a1, a2
80-
; RV64-NEXT: srliw a0, a0, 3
80+
; RV64-NEXT: srli a0, a0, 3
8181
; RV64-NEXT: or a0, a1, a0
8282
; RV64-NEXT: ret
8383
%rev = call i4 @llvm.bitreverse.i4(i4 %x)
@@ -121,13 +121,13 @@ define i7 @bitreverse_i7(i7 %x) {
121121
; RV64-NEXT: andi a3, a0, 8
122122
; RV64-NEXT: or a2, a2, a3
123123
; RV64-NEXT: or a1, a1, a2
124-
; RV64-NEXT: srliw a2, a0, 2
124+
; RV64-NEXT: srli a2, a0, 2
125125
; RV64-NEXT: andi a2, a2, 4
126-
; RV64-NEXT: srliw a3, a0, 4
126+
; RV64-NEXT: srli a3, a0, 4
127127
; RV64-NEXT: andi a3, a3, 2
128128
; RV64-NEXT: or a2, a2, a3
129129
; RV64-NEXT: or a1, a1, a2
130-
; RV64-NEXT: srliw a0, a0, 6
130+
; RV64-NEXT: srli a0, a0, 6
131131
; RV64-NEXT: or a0, a1, a0
132132
; RV64-NEXT: ret
133133
%rev = call i7 @llvm.bitreverse.i7(i7 %x)
@@ -171,36 +171,36 @@ define i24 @bitreverse_i24(i24 %x) {
171171
;
172172
; RV64-LABEL: bitreverse_i24:
173173
; RV64: # %bb.0:
174-
; RV64-NEXT: slli a1, a0, 16
175-
; RV64-NEXT: lui a2, 4096
176-
; RV64-NEXT: addi a2, a2, -1
177-
; RV64-NEXT: and a0, a0, a2
178-
; RV64-NEXT: srliw a0, a0, 16
179-
; RV64-NEXT: or a0, a0, a1
180-
; RV64-NEXT: lui a1, 1048335
181-
; RV64-NEXT: addi a1, a1, 240
182-
; RV64-NEXT: and a3, a1, a2
174+
; RV64-NEXT: lui a1, 4096
175+
; RV64-NEXT: addiw a1, a1, -1
176+
; RV64-NEXT: slli a2, a0, 16
177+
; RV64-NEXT: and a0, a0, a1
178+
; RV64-NEXT: srli a0, a0, 16
179+
; RV64-NEXT: or a0, a0, a2
180+
; RV64-NEXT: lui a2, 1048335
181+
; RV64-NEXT: addiw a2, a2, 240
182+
; RV64-NEXT: and a3, a2, a1
183183
; RV64-NEXT: and a3, a0, a3
184-
; RV64-NEXT: srliw a3, a3, 4
184+
; RV64-NEXT: srli a3, a3, 4
185185
; RV64-NEXT: slli a0, a0, 4
186-
; RV64-NEXT: and a0, a0, a1
186+
; RV64-NEXT: and a0, a0, a2
187187
; RV64-NEXT: or a0, a3, a0
188-
; RV64-NEXT: lui a1, 1047757
189-
; RV64-NEXT: addi a1, a1, -820
190-
; RV64-NEXT: and a3, a1, a2
188+
; RV64-NEXT: lui a2, 1047757
189+
; RV64-NEXT: addiw a2, a2, -820
190+
; RV64-NEXT: and a3, a2, a1
191191
; RV64-NEXT: and a3, a0, a3
192-
; RV64-NEXT: srliw a3, a3, 2
192+
; RV64-NEXT: srli a3, a3, 2
193193
; RV64-NEXT: slli a0, a0, 2
194-
; RV64-NEXT: and a0, a0, a1
194+
; RV64-NEXT: and a0, a0, a2
195195
; RV64-NEXT: or a0, a3, a0
196-
; RV64-NEXT: lui a1, 1047211
197-
; RV64-NEXT: addiw a1, a1, -1366
198-
; RV64-NEXT: and a2, a1, a2
199-
; RV64-NEXT: and a2, a0, a2
200-
; RV64-NEXT: srliw a2, a2, 1
201-
; RV64-NEXT: slliw a0, a0, 1
202-
; RV64-NEXT: and a0, a0, a1
203-
; RV64-NEXT: or a0, a2, a0
196+
; RV64-NEXT: lui a2, 1047211
197+
; RV64-NEXT: addiw a2, a2, -1366
198+
; RV64-NEXT: and a1, a2, a1
199+
; RV64-NEXT: and a1, a0, a1
200+
; RV64-NEXT: srli a1, a1, 1
201+
; RV64-NEXT: slli a0, a0, 1
202+
; RV64-NEXT: and a0, a0, a2
203+
; RV64-NEXT: or a0, a1, a0
204204
; RV64-NEXT: ret
205205
%rev = call i24 @llvm.bitreverse.i24(i24 %x)
206206
ret i24 %rev

llvm/test/CodeGen/RISCV/GlobalISel/combine.ll

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,18 @@ define i32 @mul_to_shift(i32 %x) {
4242
; RV32-NEXT: slli a0, a0, 2
4343
; RV32-NEXT: ret
4444
;
45-
; RV64-LABEL: mul_to_shift:
46-
; RV64: # %bb.0:
47-
; RV64-NEXT: slliw a0, a0, 2
48-
; RV64-NEXT: ret
45+
; RV64-O0-LABEL: mul_to_shift:
46+
; RV64-O0: # %bb.0:
47+
; RV64-O0-NEXT: li a1, 2
48+
; RV64-O0-NEXT: sll a0, a0, a1
49+
; RV64-O0-NEXT: ret
50+
;
51+
; RV64-OPT-LABEL: mul_to_shift:
52+
; RV64-OPT: # %bb.0:
53+
; RV64-OPT-NEXT: slli a0, a0, 2
54+
; RV64-OPT-NEXT: ret
4955
%a = mul i32 %x, 4
5056
ret i32 %a
5157
}
58+
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
59+
; RV64: {{.*}}

llvm/test/CodeGen/RISCV/GlobalISel/iabs.ll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ define i8 @abs8(i8 %x) {
3232
;
3333
; RV64I-LABEL: abs8:
3434
; RV64I: # %bb.0:
35-
; RV64I-NEXT: slli a1, a0, 24
36-
; RV64I-NEXT: sraiw a1, a1, 24
37-
; RV64I-NEXT: sraiw a1, a1, 7
35+
; RV64I-NEXT: slli a1, a0, 56
36+
; RV64I-NEXT: srai a1, a1, 56
37+
; RV64I-NEXT: srai a1, a1, 7
3838
; RV64I-NEXT: addw a0, a0, a1
3939
; RV64I-NEXT: xor a0, a0, a1
4040
; RV64I-NEXT: ret
@@ -68,9 +68,9 @@ define i16 @abs16(i16 %x) {
6868
;
6969
; RV64I-LABEL: abs16:
7070
; RV64I: # %bb.0:
71-
; RV64I-NEXT: slli a1, a0, 16
72-
; RV64I-NEXT: sraiw a1, a1, 16
73-
; RV64I-NEXT: sraiw a1, a1, 15
71+
; RV64I-NEXT: slli a1, a0, 48
72+
; RV64I-NEXT: srai a1, a1, 48
73+
; RV64I-NEXT: srai a1, a1, 15
7474
; RV64I-NEXT: addw a0, a0, a1
7575
; RV64I-NEXT: xor a0, a0, a1
7676
; RV64I-NEXT: ret

0 commit comments

Comments
 (0)