Skip to content

Commit dc4cf1c

Browse files
toppercAlexisPerry
authored andcommitted
[RISCV] Support zext.h mnemonic with Zbkb. (llvm#96821)
Zbkb adds generic pack insructions. The zext.h encodings from Zbb are subsets of the generic encodings with rs2=x0. zext.h is pack on RV32 and packw on RV64. Previously we only supported zext.h as a single instruction mnemonic in the assembler when Zbb was enabled. Otherwise we would emit it as 2 shifts. This patches recognizes it when either Zbkb or Zbb is enabled. This patch also enables the zext.h isel patterns when Zbkb is enabled without Zbb.
1 parent dacdb3a commit dc4cf1c

File tree

7 files changed

+217
-21
lines changed

7 files changed

+217
-21
lines changed

llvm/lib/Target/RISCV/RISCVInstrInfoZb.td

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -415,22 +415,17 @@ let Predicates = [HasStdExtZbkb, IsRV64], IsSignExtendingOpW = 1 in
415415
def PACKW : ALUW_rr<0b0000100, 0b100, "packw">,
416416
Sched<[WritePACK32, ReadPACK32, ReadPACK32]>;
417417

418-
let Predicates = [HasStdExtZbb, IsRV32] in {
418+
let Predicates = [HasStdExtZbbOrZbkb, IsRV32] in {
419419
def ZEXT_H_RV32 : RVBUnary<0b000010000000, 0b100, OPC_OP, "zext.h">,
420420
Sched<[WriteIALU, ReadIALU]>;
421-
} // Predicates = [HasStdExtZbb, IsRV32]
422-
423-
let Predicates = [HasStdExtZbb, IsRV64], IsSignExtendingOpW = 1 in {
424-
def ZEXT_H_RV64 : RVBUnary<0b000010000000, 0b100, OPC_OP_32, "zext.h">,
425-
Sched<[WriteIALU, ReadIALU]>;
426-
} // Predicates = [HasStdExtZbb, IsRV64]
427-
428-
let Predicates = [HasStdExtZbbOrZbkb, IsRV32] in {
429421
def REV8_RV32 : RVBUnary<0b011010011000, 0b101, OPC_OP_IMM, "rev8">,
430422
Sched<[WriteREV8, ReadREV8]>;
431423
} // Predicates = [HasStdExtZbbOrZbkb, IsRV32]
432424

433425
let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in {
426+
let IsSignExtendingOpW = 1 in
427+
def ZEXT_H_RV64 : RVBUnary<0b000010000000, 0b100, OPC_OP_32, "zext.h">,
428+
Sched<[WriteIALU, ReadIALU]>;
434429
def REV8_RV64 : RVBUnary<0b011010111000, 0b101, OPC_OP_IMM, "rev8">,
435430
Sched<[WriteREV8, ReadREV8]>;
436431
} // Predicates = [HasStdExtZbbOrZbkb, IsRV64]
@@ -637,9 +632,9 @@ def : Pat<(i64 (or (sext_inreg (shl GPR:$rs2, (i64 16)), i32),
637632
(PACKW GPR:$rs1, GPR:$rs2)>;
638633
} // Predicates = [HasStdExtZbkb, IsRV64]
639634

640-
let Predicates = [HasStdExtZbb, IsRV32] in
635+
let Predicates = [HasStdExtZbbOrZbkb, IsRV32] in
641636
def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (ZEXT_H_RV32 GPR:$rs)>;
642-
let Predicates = [HasStdExtZbb, IsRV64] in
637+
let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in
643638
def : Pat<(i64 (and GPR:$rs, 0xFFFF)), (ZEXT_H_RV64 GPR:$rs)>;
644639

645640
let Predicates = [HasStdExtZba] in {
@@ -748,9 +743,11 @@ def : PatGpr<ctpop, CPOPW, i32>;
748743

749744
def : Pat<(i32 (sext_inreg GPR:$rs1, i8)), (SEXT_B GPR:$rs1)>;
750745
def : Pat<(i32 (sext_inreg GPR:$rs1, i16)), (SEXT_H GPR:$rs1)>;
746+
} // Predicates = [HasStdExtZbb, IsRV64]
751747

748+
let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in {
752749
def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (ZEXT_H_RV64 GPR:$rs)>;
753-
} // Predicates = [HasStdExtZbb, IsRV64]
750+
} // Predicates = [HasStdExtZbbOrZbkb, IsRV64]
754751

755752
let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in {
756753
def : Pat<(i32 (and GPR:$rs1, (not GPR:$rs2))), (ANDN GPR:$rs1, GPR:$rs2)>;

llvm/test/CodeGen/RISCV/rv32zbkb.ll

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,3 +255,67 @@ define void @packh_i16_3(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, ptr %p) {
255255
store i16 %8, ptr %p
256256
ret void
257257
}
258+
259+
define i32 @zexth_i32(i32 %a) nounwind {
260+
; RV32I-LABEL: zexth_i32:
261+
; RV32I: # %bb.0:
262+
; RV32I-NEXT: slli a0, a0, 16
263+
; RV32I-NEXT: srli a0, a0, 16
264+
; RV32I-NEXT: ret
265+
;
266+
; RV32ZBKB-LABEL: zexth_i32:
267+
; RV32ZBKB: # %bb.0:
268+
; RV32ZBKB-NEXT: zext.h a0, a0
269+
; RV32ZBKB-NEXT: ret
270+
%and = and i32 %a, 65535
271+
ret i32 %and
272+
}
273+
274+
define i64 @zexth_i64(i64 %a) nounwind {
275+
; RV32I-LABEL: zexth_i64:
276+
; RV32I: # %bb.0:
277+
; RV32I-NEXT: slli a0, a0, 16
278+
; RV32I-NEXT: srli a0, a0, 16
279+
; RV32I-NEXT: li a1, 0
280+
; RV32I-NEXT: ret
281+
;
282+
; RV32ZBKB-LABEL: zexth_i64:
283+
; RV32ZBKB: # %bb.0:
284+
; RV32ZBKB-NEXT: zext.h a0, a0
285+
; RV32ZBKB-NEXT: li a1, 0
286+
; RV32ZBKB-NEXT: ret
287+
%and = and i64 %a, 65535
288+
ret i64 %and
289+
}
290+
291+
define i32 @zext_i16_to_i32(i16 %a) nounwind {
292+
; RV32I-LABEL: zext_i16_to_i32:
293+
; RV32I: # %bb.0:
294+
; RV32I-NEXT: slli a0, a0, 16
295+
; RV32I-NEXT: srli a0, a0, 16
296+
; RV32I-NEXT: ret
297+
;
298+
; RV32ZBKB-LABEL: zext_i16_to_i32:
299+
; RV32ZBKB: # %bb.0:
300+
; RV32ZBKB-NEXT: zext.h a0, a0
301+
; RV32ZBKB-NEXT: ret
302+
%1 = zext i16 %a to i32
303+
ret i32 %1
304+
}
305+
306+
define i64 @zext_i16_to_i64(i16 %a) nounwind {
307+
; RV32I-LABEL: zext_i16_to_i64:
308+
; RV32I: # %bb.0:
309+
; RV32I-NEXT: slli a0, a0, 16
310+
; RV32I-NEXT: srli a0, a0, 16
311+
; RV32I-NEXT: li a1, 0
312+
; RV32I-NEXT: ret
313+
;
314+
; RV32ZBKB-LABEL: zext_i16_to_i64:
315+
; RV32ZBKB: # %bb.0:
316+
; RV32ZBKB-NEXT: zext.h a0, a0
317+
; RV32ZBKB-NEXT: li a1, 0
318+
; RV32ZBKB-NEXT: ret
319+
%1 = zext i16 %a to i64
320+
ret i64 %1
321+
}

llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zbkb.ll

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,3 +308,63 @@ define i64 @pack_i64_imm() {
308308
; RV64ZBKB-NEXT: ret
309309
ret i64 1157442765409226768 ; 0x0101010101010101
310310
}
311+
312+
define i32 @zexth_i32(i32 %a) nounwind {
313+
; RV64I-LABEL: zexth_i32:
314+
; RV64I: # %bb.0:
315+
; RV64I-NEXT: slli a0, a0, 48
316+
; RV64I-NEXT: srli a0, a0, 48
317+
; RV64I-NEXT: ret
318+
;
319+
; RV64ZBKB-LABEL: zexth_i32:
320+
; RV64ZBKB: # %bb.0:
321+
; RV64ZBKB-NEXT: zext.h a0, a0
322+
; RV64ZBKB-NEXT: ret
323+
%and = and i32 %a, 65535
324+
ret i32 %and
325+
}
326+
327+
define i64 @zexth_i64(i64 %a) nounwind {
328+
; RV64I-LABEL: zexth_i64:
329+
; RV64I: # %bb.0:
330+
; RV64I-NEXT: slli a0, a0, 48
331+
; RV64I-NEXT: srli a0, a0, 48
332+
; RV64I-NEXT: ret
333+
;
334+
; RV64ZBKB-LABEL: zexth_i64:
335+
; RV64ZBKB: # %bb.0:
336+
; RV64ZBKB-NEXT: zext.h a0, a0
337+
; RV64ZBKB-NEXT: ret
338+
%and = and i64 %a, 65535
339+
ret i64 %and
340+
}
341+
342+
define i32 @zext_i16_to_i32(i16 %a) nounwind {
343+
; RV64I-LABEL: zext_i16_to_i32:
344+
; RV64I: # %bb.0:
345+
; RV64I-NEXT: slli a0, a0, 48
346+
; RV64I-NEXT: srli a0, a0, 48
347+
; RV64I-NEXT: ret
348+
;
349+
; RV64ZBKB-LABEL: zext_i16_to_i32:
350+
; RV64ZBKB: # %bb.0:
351+
; RV64ZBKB-NEXT: zext.h a0, a0
352+
; RV64ZBKB-NEXT: ret
353+
%1 = zext i16 %a to i32
354+
ret i32 %1
355+
}
356+
357+
define i64 @zext_i16_to_i64(i16 %a) nounwind {
358+
; RV64I-LABEL: zext_i16_to_i64:
359+
; RV64I: # %bb.0:
360+
; RV64I-NEXT: slli a0, a0, 48
361+
; RV64I-NEXT: srli a0, a0, 48
362+
; RV64I-NEXT: ret
363+
;
364+
; RV64ZBKB-LABEL: zext_i16_to_i64:
365+
; RV64ZBKB: # %bb.0:
366+
; RV64ZBKB-NEXT: zext.h a0, a0
367+
; RV64ZBKB-NEXT: ret
368+
%1 = zext i16 %a to i64
369+
ret i64 %1
370+
}

llvm/test/CodeGen/RISCV/rv64zbkb.ll

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,3 +332,63 @@ define i64 @pack_i64_imm() {
332332
; RV64ZBKB-NEXT: ret
333333
ret i64 1157442765409226768 ; 0x0101010101010101
334334
}
335+
336+
define i32 @zexth_i32(i32 %a) nounwind {
337+
; RV64I-LABEL: zexth_i32:
338+
; RV64I: # %bb.0:
339+
; RV64I-NEXT: slli a0, a0, 48
340+
; RV64I-NEXT: srli a0, a0, 48
341+
; RV64I-NEXT: ret
342+
;
343+
; RV64ZBKB-LABEL: zexth_i32:
344+
; RV64ZBKB: # %bb.0:
345+
; RV64ZBKB-NEXT: zext.h a0, a0
346+
; RV64ZBKB-NEXT: ret
347+
%and = and i32 %a, 65535
348+
ret i32 %and
349+
}
350+
351+
define i64 @zexth_i64(i64 %a) nounwind {
352+
; RV64I-LABEL: zexth_i64:
353+
; RV64I: # %bb.0:
354+
; RV64I-NEXT: slli a0, a0, 48
355+
; RV64I-NEXT: srli a0, a0, 48
356+
; RV64I-NEXT: ret
357+
;
358+
; RV64ZBKB-LABEL: zexth_i64:
359+
; RV64ZBKB: # %bb.0:
360+
; RV64ZBKB-NEXT: zext.h a0, a0
361+
; RV64ZBKB-NEXT: ret
362+
%and = and i64 %a, 65535
363+
ret i64 %and
364+
}
365+
366+
define i32 @zext_i16_to_i32(i16 %a) nounwind {
367+
; RV64I-LABEL: zext_i16_to_i32:
368+
; RV64I: # %bb.0:
369+
; RV64I-NEXT: slli a0, a0, 48
370+
; RV64I-NEXT: srli a0, a0, 48
371+
; RV64I-NEXT: ret
372+
;
373+
; RV64ZBKB-LABEL: zext_i16_to_i32:
374+
; RV64ZBKB: # %bb.0:
375+
; RV64ZBKB-NEXT: zext.h a0, a0
376+
; RV64ZBKB-NEXT: ret
377+
%1 = zext i16 %a to i32
378+
ret i32 %1
379+
}
380+
381+
define i64 @zext_i16_to_i64(i16 %a) nounwind {
382+
; RV64I-LABEL: zext_i16_to_i64:
383+
; RV64I: # %bb.0:
384+
; RV64I-NEXT: slli a0, a0, 48
385+
; RV64I-NEXT: srli a0, a0, 48
386+
; RV64I-NEXT: ret
387+
;
388+
; RV64ZBKB-LABEL: zext_i16_to_i64:
389+
; RV64ZBKB: # %bb.0:
390+
; RV64ZBKB-NEXT: zext.h a0, a0
391+
; RV64ZBKB-NEXT: ret
392+
%1 = zext i16 %a to i64
393+
ret i64 %1
394+
}

llvm/test/MC/RISCV/rv32zbkb-only-valid.s

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
33
# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zbkb < %s \
44
# RUN: | llvm-objdump --mattr=+zbkb -d -r - \
5-
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
5+
# RUN: | FileCheck --check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
66

77
# CHECK-ASM-AND-OBJ: rev8 t0, t1
88
# CHECK-ASM: encoding: [0x93,0x52,0x83,0x69]
@@ -14,3 +14,13 @@ zip t0, t1
1414
# CHECK-S-OBJ-NOALIAS: unzip t0, t1
1515
# CHECK-ASM: encoding: [0x93,0x52,0xf3,0x08]
1616
unzip t0, t1
17+
18+
# Test the encoding used for zext.h for RV32.
19+
# CHECK-ASM: pack t0, t1, zero
20+
# CHECK-OBJ: zext.h t0, t1
21+
# CHECK-ASM: encoding: [0xb3,0x42,0x03,0x08]
22+
pack t0, t1, x0
23+
24+
# CHECK-ASM-AND-OBJ: zext.h t0, t1
25+
# CHECK-ASM: encoding: [0xb3,0x42,0x03,0x08]
26+
zext.h t0, t1

llvm/test/MC/RISCV/rv32zbkb-valid.s

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,6 @@ xnor t0, t1, t2
3636
# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x08]
3737
pack t0, t1, t2
3838

39-
# Test the encoding used for zext.h for RV32.
40-
# CHECK-ASM-AND-OBJ: pack t0, t1, zero
41-
# CHECK-ASM: encoding: [0xb3,0x42,0x03,0x08]
42-
pack t0, t1, x0
43-
4439
# CHECK-ASM-AND-OBJ: packh t0, t1, t2
4540
# CHECK-ASM: encoding: [0xb3,0x72,0x73,0x08]
4641
packh t0, t1, t2

llvm/test/MC/RISCV/rv64zbkb-valid.s

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
33
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zbkb < %s \
44
# RUN: | llvm-objdump --mattr=+zbkb --no-print-imm-hex -d -r - \
5-
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
5+
# RUN: | FileCheck --check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
66

77
# CHECK-ASM-AND-OBJ: rev8 t0, t1
88
# CHECK-ASM: encoding: [0x93,0x52,0x83,0x6b]
@@ -28,7 +28,17 @@ roriw t0, t1, 0
2828
# CHECK-ASM: encoding: [0xbb,0x42,0x73,0x08]
2929
packw t0, t1, t2
3030

31-
# Test the encoding used for zext.h
32-
# CHECK-ASM-AND-OBJ: packw t0, t1, zero
31+
# Test the encoding used for zext.h on RV64
32+
# CHECK-ASM: packw t0, t1, zero
33+
# CHECK-OBJ: zext.h t0, t1
3334
# CHECK-ASM: encoding: [0xbb,0x42,0x03,0x08]
3435
packw t0, t1, zero
36+
37+
# Test the encoding used for zext.h on RV32
38+
# CHECK-ASM-AND-OBJ: pack t0, t1, zero
39+
# CHECK-ASM: encoding: [0xb3,0x42,0x03,0x08]
40+
pack t0, t1, zero
41+
42+
# CHECK-ASM-AND-OBJ: zext.h t0, t1
43+
# CHECK-ASM: encoding: [0xbb,0x42,0x03,0x08]
44+
zext.h t0, t1

0 commit comments

Comments
 (0)