[RISCV] Add isel patterns for grevi, shfli, and unshfli to brev8/zip/unzip instructions.
authorCraig Topper <craig.topper@sifive.com>
Fri, 21 Jan 2022 04:43:48 +0000 (20:43 -0800)
committerCraig Topper <craig.topper@sifive.com>
Fri, 21 Jan 2022 04:43:52 +0000 (20:43 -0800)
Zbkb supports some encodings of the general grevi, shfli, and
unshfli instructions legal, so we added separate instructions for
those encodings to improve the diagnostics for assembler and
disassembler. To be consistent we should always use these separate
instructions whenever those specific encodings of grevi/shfli/unshfli
occur. So this patch adds specific isel patterns to override the generic
isel patterns for these cases. Similar was done for rev8 and zext.h
for Zbb previously.

llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
llvm/test/CodeGen/RISCV/rv32zbp-intrinsic.ll
llvm/test/CodeGen/RISCV/rv32zbp.ll
llvm/test/CodeGen/RISCV/rv64zbp.ll

index f8030b3..aae646f 100644 (file)
@@ -687,6 +687,7 @@ def : InstAlias<"zip4 $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b1100)>;
 def : InstAlias<"unzip4 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1100)>;
 def : InstAlias<"zip2 $rd, $rs",   (SHFLI   GPR:$rd, GPR:$rs, 0b1110)>;
 def : InstAlias<"unzip2 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1110)>;
+// zip and unzip are considered instructions rather than an alias.
 
 def : InstAlias<"orc16 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b10000)>;
 def : InstAlias<"orc8 $rd, $rs",  (GORCI GPR:$rd, GPR:$rs, 0b11000)>;
@@ -865,6 +866,9 @@ def : PatGprImm<riscv_shfl, SHFLI, shfl_uimm>;
 def : PatGprImm<riscv_unshfl, UNSHFLI, shfl_uimm>;
 def : PatGprImm<riscv_grev, GREVI, uimmlog2xlen>;
 def : PatGprImm<riscv_gorc, GORCI, uimmlog2xlen>;
+
+// We treat brev8 as a separate instruction, so match it directly.
+def : Pat<(riscv_grev GPR:$rs1, 7), (BREV8 GPR:$rs1)>;
 } // Predicates = [HasStdExtZbp]
 
 let Predicates = [HasStdExtZbp, IsRV64] in
@@ -876,6 +880,10 @@ def : Pat<(i32 (rotl (riscv_grev GPR:$rs1, 24), (i32 16))), (GREVI GPR:$rs1, 8)>
 
 // We treat rev8 as a separate instruction, so match it directly.
 def : Pat<(i32 (riscv_grev GPR:$rs1, 24)), (REV8_RV32 GPR:$rs1)>;
+
+// We treat zip and unzip as separate instructions, so match it directly.
+def : Pat<(i32 (riscv_shfl GPR:$rs1, 15)), (ZIP_RV32 GPR:$rs1)>;
+def : Pat<(i32 (riscv_unshfl GPR:$rs1, 15)), (UNZIP_RV32 GPR:$rs1)>;
 } // Predicates = [HasStdExtZbp, IsRV32]
 
 let Predicates = [HasStdExtZbp, IsRV64] in {
index 6285804..4f1dd3d 100644 (file)
@@ -92,6 +92,15 @@ define i32 @shfli32(i32 %a) nounwind {
  ret i32 %tmp
 }
 
+define i32 @zipi32(i32 %a) nounwind {
+; RV32ZBP-LABEL: zipi32:
+; RV32ZBP:       # %bb.0:
+; RV32ZBP-NEXT:    zip a0, a0
+; RV32ZBP-NEXT:    ret
+  %tmp = call i32 @llvm.riscv.shfl.i32(i32 %a, i32 15)
+ ret i32 %tmp
+}
+
 declare i32 @llvm.riscv.unshfl.i32(i32 %a, i32 %b)
 
 define i32 @unshfl32(i32 %a, i32 %b) nounwind {
@@ -122,6 +131,15 @@ define i32 @unshfli32(i32 %a) nounwind {
  ret i32 %tmp
 }
 
+define i32 @unzipi32(i32 %a) nounwind {
+; RV32ZBP-LABEL: unzipi32:
+; RV32ZBP:       # %bb.0:
+; RV32ZBP-NEXT:    unzip a0, a0
+; RV32ZBP-NEXT:    ret
+  %tmp = call i32 @llvm.riscv.unshfl.i32(i32 %a, i32 15)
+ ret i32 %tmp
+}
+
 declare i32 @llvm.riscv.xperm.n.i32(i32 %a, i32 %b)
 
 define i32 @xpermn32(i32 %a, i32 %b) nounwind {
index 1e2b032..026a27b 100644 (file)
@@ -1491,7 +1491,7 @@ define i32 @grev7_i32(i32 %a) nounwind {
 ;
 ; RV32ZBP-LABEL: grev7_i32:
 ; RV32ZBP:       # %bb.0:
-; RV32ZBP-NEXT:    grevi a0, a0, 7
+; RV32ZBP-NEXT:    rev.b a0, a0
 ; RV32ZBP-NEXT:    ret
   %and1 = shl i32 %a, 1
   %shl1 = and i32 %and1, -1431655766
@@ -1560,8 +1560,8 @@ define i64 @grev7_i64(i64 %a) nounwind {
 ;
 ; RV32ZBP-LABEL: grev7_i64:
 ; RV32ZBP:       # %bb.0:
-; RV32ZBP-NEXT:    grevi a0, a0, 7
-; RV32ZBP-NEXT:    grevi a1, a1, 7
+; RV32ZBP-NEXT:    rev.b a0, a0
+; RV32ZBP-NEXT:    rev.b a1, a1
 ; RV32ZBP-NEXT:    ret
   %and1 = shl i64 %a, 1
   %shl1 = and i64 %and1, -6148914691236517206
@@ -2175,7 +2175,7 @@ define zeroext i8 @bitreverse_i8(i8 zeroext %a) nounwind {
 ;
 ; RV32ZBP-LABEL: bitreverse_i8:
 ; RV32ZBP:       # %bb.0:
-; RV32ZBP-NEXT:    grevi a0, a0, 7
+; RV32ZBP-NEXT:    rev.b a0, a0
 ; RV32ZBP-NEXT:    ret
   %1 = tail call i8 @llvm.bitreverse.i8(i8 %a)
   ret i8 %1
@@ -2450,7 +2450,7 @@ define i32 @bitreverse_bswap_i32(i32 %a) {
 ;
 ; RV32ZBP-LABEL: bitreverse_bswap_i32:
 ; RV32ZBP:       # %bb.0:
-; RV32ZBP-NEXT:    grevi a0, a0, 7
+; RV32ZBP-NEXT:    rev.b a0, a0
 ; RV32ZBP-NEXT:    ret
   %1 = call i32 @llvm.bitreverse.i32(i32 %a)
   %2 = call i32 @llvm.bswap.i32(i32 %1)
@@ -2539,8 +2539,8 @@ define i64 @bitreverse_bswap_i64(i64 %a) {
 ;
 ; RV32ZBP-LABEL: bitreverse_bswap_i64:
 ; RV32ZBP:       # %bb.0:
-; RV32ZBP-NEXT:    grevi a0, a0, 7
-; RV32ZBP-NEXT:    grevi a1, a1, 7
+; RV32ZBP-NEXT:    rev.b a0, a0
+; RV32ZBP-NEXT:    rev.b a1, a1
 ; RV32ZBP-NEXT:    ret
   %1 = call i64 @llvm.bitreverse.i64(i64 %a)
   %2 = call i64 @llvm.bswap.i64(i64 %1)
index 5b74675..674ffcf 100644 (file)
@@ -1438,7 +1438,7 @@ define i64 @grev7_i64(i64 %a) nounwind {
 ;
 ; RV64ZBP-LABEL: grev7_i64:
 ; RV64ZBP:       # %bb.0:
-; RV64ZBP-NEXT:    grevi a0, a0, 7
+; RV64ZBP-NEXT:    rev.b a0, a0
 ; RV64ZBP-NEXT:    ret
   %and1 = shl i64 %a, 1
   %shl1 = and i64 %and1, -6148914691236517206
@@ -2481,7 +2481,7 @@ define i64 @bitreverse_bswap_i64(i64 %a) {
 ;
 ; RV64ZBP-LABEL: bitreverse_bswap_i64:
 ; RV64ZBP:       # %bb.0:
-; RV64ZBP-NEXT:    grevi a0, a0, 7
+; RV64ZBP-NEXT:    rev.b a0, a0
 ; RV64ZBP-NEXT:    ret
   %1 = call i64 @llvm.bitreverse.i64(i64 %a)
   %2 = call i64 @llvm.bswap.i64(i64 %1)