Skip to content

Commit 495816c

Browse files
committed
[RISCV] Add i16->i32 G_ZEXT/G_SEXT patterns for RV64.
Because we support s16 and s32 types for FP some operations like G_PHI, G_SELECT, G_FREEZE can exist with s16 and s32 operands even when they will be assigned to the GPR reg bank. These instructions can be surrounded with G_ZEXT and G_SEXT that convert from s16 to s32 so we need to be able to select them.
1 parent 52646d0 commit 495816c

File tree

3 files changed

+151
-6
lines changed

3 files changed

+151
-6
lines changed

llvm/lib/Target/RISCV/RISCVGISel.td

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -223,17 +223,23 @@ let Predicates = [IsRV32, NoStdExtZbb, NoStdExtZbkb] in
223223
def : Pat<(XLenVT (zext (i16 GPR:$src))),
224224
(SRLI (XLenVT (SLLI GPR:$src, 16)), 16)>;
225225

226-
let Predicates = [IsRV64, NoStdExtZbb, NoStdExtZbkb] in
226+
let Predicates = [IsRV64, NoStdExtZbb, NoStdExtZbkb] in {
227227
def : Pat<(i64 (zext (i16 GPR:$src))),
228228
(SRLI (XLenVT (SLLI GPR:$src, 48)), 48)>;
229+
def : Pat<(i32 (zext (i16 GPR:$src))),
230+
(SRLI (XLenVT (SLLI GPR:$src, 48)), 48)>;
231+
}
229232

230233
let Predicates = [IsRV32, NoStdExtZbb] in
231234
def : Pat<(XLenVT (sext (i16 GPR:$src))),
232235
(SRAI (XLenVT (SLLI GPR:$src, 16)), 16)>;
233236

234-
let Predicates = [IsRV64, NoStdExtZbb] in
237+
let Predicates = [IsRV64, NoStdExtZbb] in {
235238
def : Pat<(i64 (sext (i16 GPR:$src))),
236239
(SRAI (XLenVT (SLLI GPR:$src, 48)), 48)>;
240+
def : Pat<(i32 (sext (i16 GPR:$src))),
241+
(SRAI (XLenVT (SLLI GPR:$src, 48)), 48)>;
242+
}
237243

238244
//===----------------------------------------------------------------------===//
239245
// Zb* RV64 patterns not used by SelectionDAG.
@@ -243,15 +249,21 @@ let Predicates = [HasStdExtZba, IsRV64] in {
243249
def : Pat<(zext (i32 GPR:$src)), (ADD_UW GPR:$src, (XLenVT X0))>;
244250
}
245251

246-
let Predicates= [HasStdExtZbb] in
247-
def : Pat<(XLenVT (sext (i16 GPR:$rs))), (SEXT_H GPR:$rs)>;
252+
let Predicates = [HasStdExtZbb] in
253+
def : Pat<(i32 (sext (i16 GPR:$rs))), (SEXT_H GPR:$rs)>;
254+
let Predicates = [HasStdExtZbb, IsRV64] in
255+
def : Pat<(i64 (sext (i16 GPR:$rs))), (SEXT_H GPR:$rs)>;
248256

249257
let Predicates = [HasStdExtZbb, IsRV32] in
250258
def : Pat<(i32 (zext (i16 GPR:$rs))), (ZEXT_H_RV32 GPR:$rs)>;
251-
let Predicates = [HasStdExtZbb, IsRV64] in
259+
let Predicates = [HasStdExtZbb, IsRV64] in {
252260
def : Pat<(i64 (zext (i16 GPR:$rs))), (ZEXT_H_RV64 GPR:$rs)>;
261+
def : Pat<(i32 (zext (i16 GPR:$rs))), (ZEXT_H_RV64 GPR:$rs)>;
262+
}
253263

254264
let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV32] in
255265
def : Pat<(i32 (zext (i16 GPR:$rs))), (PACK GPR:$rs, (XLenVT X0))>;
256-
let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV64] in
266+
let Predicates = [HasStdExtZbkb, NoStdExtZbb, IsRV64] in {
257267
def : Pat<(i64 (zext (i16 GPR:$rs))), (PACKW GPR:$rs, (XLenVT X0))>;
268+
def : Pat<(i32 (zext (i16 GPR:$rs))), (PACKW GPR:$rs, (XLenVT X0))>;
269+
}

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

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,3 +1271,69 @@ define i64 @bswap_i64(i64 %a) {
12711271
%1 = call i64 @llvm.bswap.i64(i64 %a)
12721272
ret i64 %1
12731273
}
1274+
1275+
; This creates a i16->i32 G_ZEXT that we need to be able to select
1276+
define i32 @zext_i16_i32(i1 %z, ptr %x, i32 %y) {
1277+
; RV64I-LABEL: zext_i16_i32:
1278+
; RV64I: # %bb.0:
1279+
; RV64I-NEXT: andi a3, a0, 1
1280+
; RV64I-NEXT: bnez a3, .LBB35_2
1281+
; RV64I-NEXT: # %bb.1:
1282+
; RV64I-NEXT: mv a0, a2
1283+
; RV64I-NEXT: ret
1284+
; RV64I-NEXT: .LBB35_2:
1285+
; RV64I-NEXT: lh a0, 0(a1)
1286+
; RV64I-NEXT: slli a0, a0, 48
1287+
; RV64I-NEXT: srli a0, a0, 48
1288+
; RV64I-NEXT: ret
1289+
;
1290+
; RV64ZBB-LABEL: zext_i16_i32:
1291+
; RV64ZBB: # %bb.0:
1292+
; RV64ZBB-NEXT: andi a3, a0, 1
1293+
; RV64ZBB-NEXT: bnez a3, .LBB35_2
1294+
; RV64ZBB-NEXT: # %bb.1:
1295+
; RV64ZBB-NEXT: mv a0, a2
1296+
; RV64ZBB-NEXT: ret
1297+
; RV64ZBB-NEXT: .LBB35_2:
1298+
; RV64ZBB-NEXT: lh a0, 0(a1)
1299+
; RV64ZBB-NEXT: zext.h a0, a0
1300+
; RV64ZBB-NEXT: ret
1301+
%w = load i16, ptr %x
1302+
%a = freeze i16 %w
1303+
%b = zext i16 %a to i32
1304+
%c = select i1 %z, i32 %b, i32 %y
1305+
ret i32 %c
1306+
}
1307+
1308+
; This creates a i16->i32 G_SEXT that we need to be able to select
1309+
define i32 @sext_i16_i32(i1 %z, ptr %x, i32 %y) {
1310+
; RV64I-LABEL: sext_i16_i32:
1311+
; RV64I: # %bb.0:
1312+
; RV64I-NEXT: andi a3, a0, 1
1313+
; RV64I-NEXT: bnez a3, .LBB36_2
1314+
; RV64I-NEXT: # %bb.1:
1315+
; RV64I-NEXT: mv a0, a2
1316+
; RV64I-NEXT: ret
1317+
; RV64I-NEXT: .LBB36_2:
1318+
; RV64I-NEXT: lh a0, 0(a1)
1319+
; RV64I-NEXT: slli a0, a0, 48
1320+
; RV64I-NEXT: srai a0, a0, 48
1321+
; RV64I-NEXT: ret
1322+
;
1323+
; RV64ZBB-LABEL: sext_i16_i32:
1324+
; RV64ZBB: # %bb.0:
1325+
; RV64ZBB-NEXT: andi a3, a0, 1
1326+
; RV64ZBB-NEXT: bnez a3, .LBB36_2
1327+
; RV64ZBB-NEXT: # %bb.1:
1328+
; RV64ZBB-NEXT: mv a0, a2
1329+
; RV64ZBB-NEXT: ret
1330+
; RV64ZBB-NEXT: .LBB36_2:
1331+
; RV64ZBB-NEXT: lh a0, 0(a1)
1332+
; RV64ZBB-NEXT: sext.h a0, a0
1333+
; RV64ZBB-NEXT: ret
1334+
%w = load i16, ptr %x
1335+
%a = freeze i16 %w
1336+
%b = sext i16 %a to i32
1337+
%c = select i1 %z, i32 %b, i32 %y
1338+
ret i32 %c
1339+
}

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

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,3 +442,70 @@ define i64 @zext_i16_to_i64(i16 %a) nounwind {
442442
%1 = zext i16 %a to i64
443443
ret i64 %1
444444
}
445+
446+
; This creates a i16->i32 G_ZEXT that we need to be able to select
447+
define i32 @zext_i16_i32_2(i1 %z, ptr %x, i32 %y) {
448+
; RV64I-LABEL: zext_i16_i32_2:
449+
; RV64I: # %bb.0:
450+
; RV64I-NEXT: andi a3, a0, 1
451+
; RV64I-NEXT: bnez a3, .LBB20_2
452+
; RV64I-NEXT: # %bb.1:
453+
; RV64I-NEXT: mv a0, a2
454+
; RV64I-NEXT: ret
455+
; RV64I-NEXT: .LBB20_2:
456+
; RV64I-NEXT: lh a0, 0(a1)
457+
; RV64I-NEXT: slli a0, a0, 48
458+
; RV64I-NEXT: srli a0, a0, 48
459+
; RV64I-NEXT: ret
460+
;
461+
; RV64ZBKB-LABEL: zext_i16_i32_2:
462+
; RV64ZBKB: # %bb.0:
463+
; RV64ZBKB-NEXT: andi a3, a0, 1
464+
; RV64ZBKB-NEXT: bnez a3, .LBB20_2
465+
; RV64ZBKB-NEXT: # %bb.1:
466+
; RV64ZBKB-NEXT: mv a0, a2
467+
; RV64ZBKB-NEXT: ret
468+
; RV64ZBKB-NEXT: .LBB20_2:
469+
; RV64ZBKB-NEXT: lh a0, 0(a1)
470+
; RV64ZBKB-NEXT: zext.h a0, a0
471+
; RV64ZBKB-NEXT: ret
472+
%w = load i16, ptr %x
473+
%a = freeze i16 %w
474+
%b = zext i16 %a to i32
475+
%c = select i1 %z, i32 %b, i32 %y
476+
ret i32 %c
477+
}
478+
479+
; This creates a i16->i32 G_SEXT that we need to be able to select
480+
define i32 @sext_i16_i32(i1 %z, ptr %x, i32 %y) {
481+
; RV64I-LABEL: sext_i16_i32:
482+
; RV64I: # %bb.0:
483+
; RV64I-NEXT: andi a3, a0, 1
484+
; RV64I-NEXT: bnez a3, .LBB21_2
485+
; RV64I-NEXT: # %bb.1:
486+
; RV64I-NEXT: mv a0, a2
487+
; RV64I-NEXT: ret
488+
; RV64I-NEXT: .LBB21_2:
489+
; RV64I-NEXT: lh a0, 0(a1)
490+
; RV64I-NEXT: slli a0, a0, 48
491+
; RV64I-NEXT: srai a0, a0, 48
492+
; RV64I-NEXT: ret
493+
;
494+
; RV64ZBKB-LABEL: sext_i16_i32:
495+
; RV64ZBKB: # %bb.0:
496+
; RV64ZBKB-NEXT: andi a3, a0, 1
497+
; RV64ZBKB-NEXT: bnez a3, .LBB21_2
498+
; RV64ZBKB-NEXT: # %bb.1:
499+
; RV64ZBKB-NEXT: mv a0, a2
500+
; RV64ZBKB-NEXT: ret
501+
; RV64ZBKB-NEXT: .LBB21_2:
502+
; RV64ZBKB-NEXT: lh a0, 0(a1)
503+
; RV64ZBKB-NEXT: slli a0, a0, 48
504+
; RV64ZBKB-NEXT: srai a0, a0, 48
505+
; RV64ZBKB-NEXT: ret
506+
%w = load i16, ptr %x
507+
%a = freeze i16 %w
508+
%b = sext i16 %a to i32
509+
%c = select i1 %z, i32 %b, i32 %y
510+
ret i32 %c
511+
}

0 commit comments

Comments
 (0)