[llvm] cad7263 - [RISCV] Support zext.h mnemonic with Zbkb. (#96821)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 27 09:31:29 PDT 2024
Author: Craig Topper
Date: 2024-06-27T09:31:26-07:00
New Revision: cad72632eb0d612fe18c38ac4526d80a6b800f96
URL: https://github.com/llvm/llvm-project/commit/cad72632eb0d612fe18c38ac4526d80a6b800f96
DIFF: https://github.com/llvm/llvm-project/commit/cad72632eb0d612fe18c38ac4526d80a6b800f96.diff
LOG: [RISCV] Support zext.h mnemonic with Zbkb. (#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.
Added:
Modified:
llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
llvm/test/CodeGen/RISCV/rv32zbkb.ll
llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zbkb.ll
llvm/test/CodeGen/RISCV/rv64zbkb.ll
llvm/test/MC/RISCV/rv32zbkb-only-valid.s
llvm/test/MC/RISCV/rv32zbkb-valid.s
llvm/test/MC/RISCV/rv64zbkb-valid.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
index 8a0bbf6abd334..afde89dc95ca9 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
@@ -415,22 +415,17 @@ let Predicates = [HasStdExtZbkb, IsRV64], IsSignExtendingOpW = 1 in
def PACKW : ALUW_rr<0b0000100, 0b100, "packw">,
Sched<[WritePACK32, ReadPACK32, ReadPACK32]>;
-let Predicates = [HasStdExtZbb, IsRV32] in {
+let Predicates = [HasStdExtZbbOrZbkb, IsRV32] in {
def ZEXT_H_RV32 : RVBUnary<0b000010000000, 0b100, OPC_OP, "zext.h">,
Sched<[WriteIALU, ReadIALU]>;
-} // Predicates = [HasStdExtZbb, IsRV32]
-
-let Predicates = [HasStdExtZbb, IsRV64], IsSignExtendingOpW = 1 in {
-def ZEXT_H_RV64 : RVBUnary<0b000010000000, 0b100, OPC_OP_32, "zext.h">,
- Sched<[WriteIALU, ReadIALU]>;
-} // Predicates = [HasStdExtZbb, IsRV64]
-
-let Predicates = [HasStdExtZbbOrZbkb, IsRV32] in {
def REV8_RV32 : RVBUnary<0b011010011000, 0b101, OPC_OP_IMM, "rev8">,
Sched<[WriteREV8, ReadREV8]>;
} // Predicates = [HasStdExtZbbOrZbkb, IsRV32]
let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in {
+let IsSignExtendingOpW = 1 in
+def ZEXT_H_RV64 : RVBUnary<0b000010000000, 0b100, OPC_OP_32, "zext.h">,
+ Sched<[WriteIALU, ReadIALU]>;
def REV8_RV64 : RVBUnary<0b011010111000, 0b101, OPC_OP_IMM, "rev8">,
Sched<[WriteREV8, ReadREV8]>;
} // Predicates = [HasStdExtZbbOrZbkb, IsRV64]
@@ -637,9 +632,9 @@ def : Pat<(i64 (or (sext_inreg (shl GPR:$rs2, (i64 16)), i32),
(PACKW GPR:$rs1, GPR:$rs2)>;
} // Predicates = [HasStdExtZbkb, IsRV64]
-let Predicates = [HasStdExtZbb, IsRV32] in
+let Predicates = [HasStdExtZbbOrZbkb, IsRV32] in
def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (ZEXT_H_RV32 GPR:$rs)>;
-let Predicates = [HasStdExtZbb, IsRV64] in
+let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in
def : Pat<(i64 (and GPR:$rs, 0xFFFF)), (ZEXT_H_RV64 GPR:$rs)>;
let Predicates = [HasStdExtZba] in {
@@ -748,9 +743,11 @@ def : PatGpr<ctpop, CPOPW, i32>;
def : Pat<(i32 (sext_inreg GPR:$rs1, i8)), (SEXT_B GPR:$rs1)>;
def : Pat<(i32 (sext_inreg GPR:$rs1, i16)), (SEXT_H GPR:$rs1)>;
+} // Predicates = [HasStdExtZbb, IsRV64]
+let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in {
def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (ZEXT_H_RV64 GPR:$rs)>;
-} // Predicates = [HasStdExtZbb, IsRV64]
+} // Predicates = [HasStdExtZbbOrZbkb, IsRV64]
let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in {
def : Pat<(i32 (and GPR:$rs1, (not GPR:$rs2))), (ANDN GPR:$rs1, GPR:$rs2)>;
diff --git a/llvm/test/CodeGen/RISCV/rv32zbkb.ll b/llvm/test/CodeGen/RISCV/rv32zbkb.ll
index 33116d16595a4..b194c0ed52dfb 100644
--- a/llvm/test/CodeGen/RISCV/rv32zbkb.ll
+++ b/llvm/test/CodeGen/RISCV/rv32zbkb.ll
@@ -255,3 +255,67 @@ define void @packh_i16_3(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, ptr %p) {
store i16 %8, ptr %p
ret void
}
+
+define i32 @zexth_i32(i32 %a) nounwind {
+; RV32I-LABEL: zexth_i32:
+; RV32I: # %bb.0:
+; RV32I-NEXT: slli a0, a0, 16
+; RV32I-NEXT: srli a0, a0, 16
+; RV32I-NEXT: ret
+;
+; RV32ZBKB-LABEL: zexth_i32:
+; RV32ZBKB: # %bb.0:
+; RV32ZBKB-NEXT: zext.h a0, a0
+; RV32ZBKB-NEXT: ret
+ %and = and i32 %a, 65535
+ ret i32 %and
+}
+
+define i64 @zexth_i64(i64 %a) nounwind {
+; RV32I-LABEL: zexth_i64:
+; RV32I: # %bb.0:
+; RV32I-NEXT: slli a0, a0, 16
+; RV32I-NEXT: srli a0, a0, 16
+; RV32I-NEXT: li a1, 0
+; RV32I-NEXT: ret
+;
+; RV32ZBKB-LABEL: zexth_i64:
+; RV32ZBKB: # %bb.0:
+; RV32ZBKB-NEXT: zext.h a0, a0
+; RV32ZBKB-NEXT: li a1, 0
+; RV32ZBKB-NEXT: ret
+ %and = and i64 %a, 65535
+ ret i64 %and
+}
+
+define i32 @zext_i16_to_i32(i16 %a) nounwind {
+; RV32I-LABEL: zext_i16_to_i32:
+; RV32I: # %bb.0:
+; RV32I-NEXT: slli a0, a0, 16
+; RV32I-NEXT: srli a0, a0, 16
+; RV32I-NEXT: ret
+;
+; RV32ZBKB-LABEL: zext_i16_to_i32:
+; RV32ZBKB: # %bb.0:
+; RV32ZBKB-NEXT: zext.h a0, a0
+; RV32ZBKB-NEXT: ret
+ %1 = zext i16 %a to i32
+ ret i32 %1
+}
+
+define i64 @zext_i16_to_i64(i16 %a) nounwind {
+; RV32I-LABEL: zext_i16_to_i64:
+; RV32I: # %bb.0:
+; RV32I-NEXT: slli a0, a0, 16
+; RV32I-NEXT: srli a0, a0, 16
+; RV32I-NEXT: li a1, 0
+; RV32I-NEXT: ret
+;
+; RV32ZBKB-LABEL: zext_i16_to_i64:
+; RV32ZBKB: # %bb.0:
+; RV32ZBKB-NEXT: zext.h a0, a0
+; RV32ZBKB-NEXT: li a1, 0
+; RV32ZBKB-NEXT: ret
+ %1 = zext i16 %a to i64
+ ret i64 %1
+}
diff --git a/llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zbkb.ll b/llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zbkb.ll
index 806f2e0838e29..8e26598380d4a 100644
--- a/llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zbkb.ll
+++ b/llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zbkb.ll
@@ -308,3 +308,63 @@ define i64 @pack_i64_imm() {
; RV64ZBKB-NEXT: ret
ret i64 1157442765409226768 ; 0x0101010101010101
}
+
+define i32 @zexth_i32(i32 %a) nounwind {
+; RV64I-LABEL: zexth_i32:
+; RV64I: # %bb.0:
+; RV64I-NEXT: slli a0, a0, 48
+; RV64I-NEXT: srli a0, a0, 48
+; RV64I-NEXT: ret
+;
+; RV64ZBKB-LABEL: zexth_i32:
+; RV64ZBKB: # %bb.0:
+; RV64ZBKB-NEXT: zext.h a0, a0
+; RV64ZBKB-NEXT: ret
+ %and = and i32 %a, 65535
+ ret i32 %and
+}
+
+define i64 @zexth_i64(i64 %a) nounwind {
+; RV64I-LABEL: zexth_i64:
+; RV64I: # %bb.0:
+; RV64I-NEXT: slli a0, a0, 48
+; RV64I-NEXT: srli a0, a0, 48
+; RV64I-NEXT: ret
+;
+; RV64ZBKB-LABEL: zexth_i64:
+; RV64ZBKB: # %bb.0:
+; RV64ZBKB-NEXT: zext.h a0, a0
+; RV64ZBKB-NEXT: ret
+ %and = and i64 %a, 65535
+ ret i64 %and
+}
+
+define i32 @zext_i16_to_i32(i16 %a) nounwind {
+; RV64I-LABEL: zext_i16_to_i32:
+; RV64I: # %bb.0:
+; RV64I-NEXT: slli a0, a0, 48
+; RV64I-NEXT: srli a0, a0, 48
+; RV64I-NEXT: ret
+;
+; RV64ZBKB-LABEL: zext_i16_to_i32:
+; RV64ZBKB: # %bb.0:
+; RV64ZBKB-NEXT: zext.h a0, a0
+; RV64ZBKB-NEXT: ret
+ %1 = zext i16 %a to i32
+ ret i32 %1
+}
+
+define i64 @zext_i16_to_i64(i16 %a) nounwind {
+; RV64I-LABEL: zext_i16_to_i64:
+; RV64I: # %bb.0:
+; RV64I-NEXT: slli a0, a0, 48
+; RV64I-NEXT: srli a0, a0, 48
+; RV64I-NEXT: ret
+;
+; RV64ZBKB-LABEL: zext_i16_to_i64:
+; RV64ZBKB: # %bb.0:
+; RV64ZBKB-NEXT: zext.h a0, a0
+; RV64ZBKB-NEXT: ret
+ %1 = zext i16 %a to i64
+ ret i64 %1
+}
diff --git a/llvm/test/CodeGen/RISCV/rv64zbkb.ll b/llvm/test/CodeGen/RISCV/rv64zbkb.ll
index db1330b0a63bd..4aa6cd42ab099 100644
--- a/llvm/test/CodeGen/RISCV/rv64zbkb.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zbkb.ll
@@ -332,3 +332,63 @@ define i64 @pack_i64_imm() {
; RV64ZBKB-NEXT: ret
ret i64 1157442765409226768 ; 0x0101010101010101
}
+
+define i32 @zexth_i32(i32 %a) nounwind {
+; RV64I-LABEL: zexth_i32:
+; RV64I: # %bb.0:
+; RV64I-NEXT: slli a0, a0, 48
+; RV64I-NEXT: srli a0, a0, 48
+; RV64I-NEXT: ret
+;
+; RV64ZBKB-LABEL: zexth_i32:
+; RV64ZBKB: # %bb.0:
+; RV64ZBKB-NEXT: zext.h a0, a0
+; RV64ZBKB-NEXT: ret
+ %and = and i32 %a, 65535
+ ret i32 %and
+}
+
+define i64 @zexth_i64(i64 %a) nounwind {
+; RV64I-LABEL: zexth_i64:
+; RV64I: # %bb.0:
+; RV64I-NEXT: slli a0, a0, 48
+; RV64I-NEXT: srli a0, a0, 48
+; RV64I-NEXT: ret
+;
+; RV64ZBKB-LABEL: zexth_i64:
+; RV64ZBKB: # %bb.0:
+; RV64ZBKB-NEXT: zext.h a0, a0
+; RV64ZBKB-NEXT: ret
+ %and = and i64 %a, 65535
+ ret i64 %and
+}
+
+define i32 @zext_i16_to_i32(i16 %a) nounwind {
+; RV64I-LABEL: zext_i16_to_i32:
+; RV64I: # %bb.0:
+; RV64I-NEXT: slli a0, a0, 48
+; RV64I-NEXT: srli a0, a0, 48
+; RV64I-NEXT: ret
+;
+; RV64ZBKB-LABEL: zext_i16_to_i32:
+; RV64ZBKB: # %bb.0:
+; RV64ZBKB-NEXT: zext.h a0, a0
+; RV64ZBKB-NEXT: ret
+ %1 = zext i16 %a to i32
+ ret i32 %1
+}
+
+define i64 @zext_i16_to_i64(i16 %a) nounwind {
+; RV64I-LABEL: zext_i16_to_i64:
+; RV64I: # %bb.0:
+; RV64I-NEXT: slli a0, a0, 48
+; RV64I-NEXT: srli a0, a0, 48
+; RV64I-NEXT: ret
+;
+; RV64ZBKB-LABEL: zext_i16_to_i64:
+; RV64ZBKB: # %bb.0:
+; RV64ZBKB-NEXT: zext.h a0, a0
+; RV64ZBKB-NEXT: ret
+ %1 = zext i16 %a to i64
+ ret i64 %1
+}
diff --git a/llvm/test/MC/RISCV/rv32zbkb-only-valid.s b/llvm/test/MC/RISCV/rv32zbkb-only-valid.s
index a04ff04ba3f10..3120365fc3545 100644
--- a/llvm/test/MC/RISCV/rv32zbkb-only-valid.s
+++ b/llvm/test/MC/RISCV/rv32zbkb-only-valid.s
@@ -2,7 +2,7 @@
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zbkb < %s \
# RUN: | llvm-objdump --mattr=+zbkb -d -r - \
-# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN: | FileCheck --check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
# CHECK-ASM-AND-OBJ: rev8 t0, t1
# CHECK-ASM: encoding: [0x93,0x52,0x83,0x69]
@@ -14,3 +14,13 @@ zip t0, t1
# CHECK-S-OBJ-NOALIAS: unzip t0, t1
# CHECK-ASM: encoding: [0x93,0x52,0xf3,0x08]
unzip t0, t1
+
+# Test the encoding used for zext.h for RV32.
+# CHECK-ASM: pack t0, t1, zero
+# CHECK-OBJ: zext.h t0, t1
+# CHECK-ASM: encoding: [0xb3,0x42,0x03,0x08]
+pack t0, t1, x0
+
+# CHECK-ASM-AND-OBJ: zext.h t0, t1
+# CHECK-ASM: encoding: [0xb3,0x42,0x03,0x08]
+zext.h t0, t1
diff --git a/llvm/test/MC/RISCV/rv32zbkb-valid.s b/llvm/test/MC/RISCV/rv32zbkb-valid.s
index 9849430a46f82..0e5ee4cb5fd6e 100644
--- a/llvm/test/MC/RISCV/rv32zbkb-valid.s
+++ b/llvm/test/MC/RISCV/rv32zbkb-valid.s
@@ -36,11 +36,6 @@ xnor t0, t1, t2
# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x08]
pack t0, t1, t2
-# Test the encoding used for zext.h for RV32.
-# CHECK-ASM-AND-OBJ: pack t0, t1, zero
-# CHECK-ASM: encoding: [0xb3,0x42,0x03,0x08]
-pack t0, t1, x0
-
# CHECK-ASM-AND-OBJ: packh t0, t1, t2
# CHECK-ASM: encoding: [0xb3,0x72,0x73,0x08]
packh t0, t1, t2
diff --git a/llvm/test/MC/RISCV/rv64zbkb-valid.s b/llvm/test/MC/RISCV/rv64zbkb-valid.s
index fc0541c86ebed..f885c4a56172a 100644
--- a/llvm/test/MC/RISCV/rv64zbkb-valid.s
+++ b/llvm/test/MC/RISCV/rv64zbkb-valid.s
@@ -2,7 +2,7 @@
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zbkb < %s \
# RUN: | llvm-objdump --mattr=+zbkb --no-print-imm-hex -d -r - \
-# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN: | FileCheck --check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
# CHECK-ASM-AND-OBJ: rev8 t0, t1
# CHECK-ASM: encoding: [0x93,0x52,0x83,0x6b]
@@ -28,7 +28,17 @@ roriw t0, t1, 0
# CHECK-ASM: encoding: [0xbb,0x42,0x73,0x08]
packw t0, t1, t2
-# Test the encoding used for zext.h
-# CHECK-ASM-AND-OBJ: packw t0, t1, zero
+# Test the encoding used for zext.h on RV64
+# CHECK-ASM: packw t0, t1, zero
+# CHECK-OBJ: zext.h t0, t1
# CHECK-ASM: encoding: [0xbb,0x42,0x03,0x08]
packw t0, t1, zero
+
+# Test the encoding used for zext.h on RV32
+# CHECK-ASM-AND-OBJ: pack t0, t1, zero
+# CHECK-ASM: encoding: [0xb3,0x42,0x03,0x08]
+pack t0, t1, zero
+
+# CHECK-ASM-AND-OBJ: zext.h t0, t1
+# CHECK-ASM: encoding: [0xbb,0x42,0x03,0x08]
+zext.h t0, t1
More information about the llvm-commits
mailing list