[llvm-branch-commits] [llvm] 3c94cee - [RISCV] Add zext.h instruction to Zbb.

Craig Topper via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Jan 22 12:56:19 PST 2021


Author: Craig Topper
Date: 2021-01-22T12:49:10-08:00
New Revision: 3c94cee63b401ca12457395bb1f4d70e161f9ec4

URL: https://github.com/llvm/llvm-project/commit/3c94cee63b401ca12457395bb1f4d70e161f9ec4
DIFF: https://github.com/llvm/llvm-project/commit/3c94cee63b401ca12457395bb1f4d70e161f9ec4.diff

LOG: [RISCV] Add zext.h instruction to Zbb.

zext.h uses the same encoding as pack rd, rs, x0 in rv32 and
packw rd, rs, x0 in rv64. Encodings without x0 as the second source
are not valid in Zbb.

I've added two new instructions with these specific encodings with
predicates that enable them when either Zbb or Zbp is enabled.

The pack spelling will only be accepted with Zbp. The disassembler
will use the zext.h instruction when either feature is enabled.

Using the pack spelling will print as pack when llvm-mc is
emitting text. We could fix this with some custom code in
processInstruction if this is important, but I'm not sure it is.

Reviewed By: asb, frasercrmck

Differential Revision: https://reviews.llvm.org/D94818

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCV.td
    llvm/lib/Target/RISCV/RISCVInstrInfoB.td
    llvm/test/CodeGen/RISCV/rv32Zbb.ll
    llvm/test/CodeGen/RISCV/rv64Zbb.ll
    llvm/test/MC/RISCV/rv32b-aliases-valid.s
    llvm/test/MC/RISCV/rv32zbb-valid.s
    llvm/test/MC/RISCV/rv32zbp-valid.s
    llvm/test/MC/RISCV/rv64b-aliases-valid.s
    llvm/test/MC/RISCV/rv64zbb-valid.s
    llvm/test/MC/RISCV/rv64zbp-valid.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td
index 8f83b164baf7..a17abd0f96da 100644
--- a/llvm/lib/Target/RISCV/RISCV.td
+++ b/llvm/lib/Target/RISCV/RISCV.td
@@ -131,7 +131,9 @@ def HasStdExtZbt : Predicate<"Subtarget->hasStdExtZbt()">,
 // subextensions. They should be enabled if either has been specified.
 def HasStdExtZbbOrZbp
     : Predicate<"Subtarget->hasStdExtZbb() || Subtarget->hasStdExtZbp()">,
-                AssemblerPredicate<(any_of FeatureExtZbb, FeatureExtZbp)>;
+                AssemblerPredicate<(any_of FeatureExtZbb, FeatureExtZbp),
+                                   "'Zbb' (Base 'B' Instructions) or "
+                                   "'Zbp' (Permutation 'B' Instructions)">;
 
 def FeatureExtZbproposedc
     : SubtargetFeature<"experimental-zbproposedc", "HasStdExtZbproposedc", "true",

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
index 120a47c3d36f..74660973e805 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
@@ -465,6 +465,22 @@ def PACKUW : ALUW_rr<0b0100100, 0b100, "packuw">, Sched<[]>;
 let Predicates = [HasStdExtZbf, IsRV64] in
 def BFPW : ALUW_rr<0b0100100, 0b111, "bfpw">, Sched<[]>;
 
+let Predicates = [HasStdExtZbbOrZbp, IsRV32] in {
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+def ZEXTH_RV32 : RVInstR<0b0000100, 0b100, OPC_OP, (outs GPR:$rd),
+                         (ins GPR:$rs1), "zext.h", "$rd, $rs1">, Sched<[]> {
+  let rs2 = 0b00000;
+}
+} // Predicates = [HasStdExtZbbOrZbp, IsRV32]
+
+let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+def ZEXTH_RV64 : RVInstR<0b0000100, 0b100, OPC_OP_32, (outs GPR:$rd),
+                         (ins GPR:$rs1), "zext.h", "$rd, $rs1">, Sched<[]> {
+  let rs2 = 0b00000;
+}
+} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
+
 //===----------------------------------------------------------------------===//
 // Future compressed instructions
 //===----------------------------------------------------------------------===//
@@ -500,14 +516,6 @@ def C_ZEXTW : RVBInstC<0b10, "c.zext.w">, Sched<[]>;
 // Pseudo Instructions
 //===----------------------------------------------------------------------===//
 
-let Predicates = [HasStdExtZbp, IsRV32] in {
-def : InstAlias<"zext.h $rd, $rs", (PACK GPR:$rd, GPR:$rs, X0)>;
-} // Predicates = [HasStdExtZbb, IsRV32]
-
-let Predicates = [HasStdExtZbp, IsRV64] in {
-def : InstAlias<"zext.h $rd, $rs", (PACKW GPR:$rd, GPR:$rs, X0)>;
-} // Predicates = [HasStdExtZbb, IsRV64]
-
 let Predicates = [HasStdExtZba, IsRV64] in {
 // NOTE: The 0.93 spec shows zext.w as an alias of pack/packw. It has been
 // changed to add.uw in a draft after 0.94.
@@ -805,10 +813,10 @@ def : Pat<(or (and (shl GPR:$rs2, (XLenVT 8)), 0xFF00),
               (and GPR:$rs1, 0x00FF)),
           (PACKH GPR:$rs1, GPR:$rs2)>;
 
-let Predicates = [HasStdExtZbp, IsRV32] in
-def : Pat<(and GPR:$rs, 0x0000FFFF), (PACK GPR:$rs, X0)>;
-let Predicates = [HasStdExtZbp, IsRV64] in {
-def : Pat<(and GPR:$rs, 0x000000000000FFFF), (PACKW GPR:$rs, X0)>;
+let Predicates = [HasStdExtZbbOrZbp, IsRV32] in
+def : Pat<(and GPR:$rs, 0x0000FFFF), (ZEXTH_RV32 GPR:$rs)>;
+let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
+def : Pat<(and GPR:$rs, 0x000000000000FFFF), (ZEXTH_RV64 GPR:$rs)>;
 }
 
 let Predicates = [HasStdExtZbp, IsRV32] in {

diff  --git a/llvm/test/CodeGen/RISCV/rv32Zbb.ll b/llvm/test/CodeGen/RISCV/rv32Zbb.ll
index 8d03d733114d..8d773d2a7ac0 100644
--- a/llvm/test/CodeGen/RISCV/rv32Zbb.ll
+++ b/llvm/test/CodeGen/RISCV/rv32Zbb.ll
@@ -917,3 +917,48 @@ define i64 @abs_i64(i64 %x) {
   %abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true)
   ret i64 %abs
 }
+
+define i32 @zexth_i32(i32 %a) nounwind {
+; RV32I-LABEL: zexth_i32:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    lui a1, 16
+; RV32I-NEXT:    addi a1, a1, -1
+; RV32I-NEXT:    and a0, a0, a1
+; RV32I-NEXT:    ret
+;
+; RV32IB-LABEL: zexth_i32:
+; RV32IB:       # %bb.0:
+; RV32IB-NEXT:    zext.h a0, a0
+; RV32IB-NEXT:    ret
+;
+; RV32IBB-LABEL: zexth_i32:
+; RV32IBB:       # %bb.0:
+; RV32IBB-NEXT:    zext.h a0, a0
+; RV32IBB-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:    lui a1, 16
+; RV32I-NEXT:    addi a1, a1, -1
+; RV32I-NEXT:    and a0, a0, a1
+; RV32I-NEXT:    mv a1, zero
+; RV32I-NEXT:    ret
+;
+; RV32IB-LABEL: zexth_i64:
+; RV32IB:       # %bb.0:
+; RV32IB-NEXT:    zext.h a0, a0
+; RV32IB-NEXT:    mv a1, zero
+; RV32IB-NEXT:    ret
+;
+; RV32IBB-LABEL: zexth_i64:
+; RV32IBB:       # %bb.0:
+; RV32IBB-NEXT:    zext.h a0, a0
+; RV32IBB-NEXT:    mv a1, zero
+; RV32IBB-NEXT:    ret
+  %and = and i64 %a, 65535
+  ret i64 %and
+}

diff  --git a/llvm/test/CodeGen/RISCV/rv64Zbb.ll b/llvm/test/CodeGen/RISCV/rv64Zbb.ll
index 5c34f4116028..5fd8135e6786 100644
--- a/llvm/test/CodeGen/RISCV/rv64Zbb.ll
+++ b/llvm/test/CodeGen/RISCV/rv64Zbb.ll
@@ -777,3 +777,45 @@ define i64 @abs_i64(i64 %x) {
   %abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true)
   ret i64 %abs
 }
+
+define i32 @zexth_i32(i32 %a) nounwind {
+; RV64I-LABEL: zexth_i32:
+; RV64I:       # %bb.0:
+; RV64I-NEXT:    lui a1, 16
+; RV64I-NEXT:    addiw a1, a1, -1
+; RV64I-NEXT:    and a0, a0, a1
+; RV64I-NEXT:    ret
+;
+; RV64IB-LABEL: zexth_i32:
+; RV64IB:       # %bb.0:
+; RV64IB-NEXT:    zext.h a0, a0
+; RV64IB-NEXT:    ret
+;
+; RV64IBB-LABEL: zexth_i32:
+; RV64IBB:       # %bb.0:
+; RV64IBB-NEXT:    zext.h a0, a0
+; RV64IBB-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:    lui a1, 16
+; RV64I-NEXT:    addiw a1, a1, -1
+; RV64I-NEXT:    and a0, a0, a1
+; RV64I-NEXT:    ret
+;
+; RV64IB-LABEL: zexth_i64:
+; RV64IB:       # %bb.0:
+; RV64IB-NEXT:    zext.h a0, a0
+; RV64IB-NEXT:    ret
+;
+; RV64IBB-LABEL: zexth_i64:
+; RV64IBB:       # %bb.0:
+; RV64IBB-NEXT:    zext.h a0, a0
+; RV64IBB-NEXT:    ret
+  %and = and i64 %a, 65535
+  ret i64 %and
+}

diff  --git a/llvm/test/MC/RISCV/rv32b-aliases-valid.s b/llvm/test/MC/RISCV/rv32b-aliases-valid.s
index 9ff9a5f60903..a291c381109a 100644
--- a/llvm/test/MC/RISCV/rv32b-aliases-valid.s
+++ b/llvm/test/MC/RISCV/rv32b-aliases-valid.s
@@ -19,7 +19,7 @@
 # CHECK-S-OBJ: andi t0, t1, 255
 zext.b x5, x6
 
-# CHECK-S-OBJ-NOALIAS: pack t0, t1, zero
+# CHECK-S-OBJ-NOALIAS: zext.h t0, t1
 # CHECK-S-OBJ: zext.h t0, t1
 zext.h x5, x6
 

diff  --git a/llvm/test/MC/RISCV/rv32zbb-valid.s b/llvm/test/MC/RISCV/rv32zbb-valid.s
index dd8a4a408a8b..28c38436274e 100644
--- a/llvm/test/MC/RISCV/rv32zbb-valid.s
+++ b/llvm/test/MC/RISCV/rv32zbb-valid.s
@@ -6,10 +6,10 @@
 # RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
 
 # With Bitmanip base extension:
-# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zbb -show-encoding \
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zbb -riscv-no-aliases -show-encoding \
 # RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
 # RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zbb < %s \
-# RUN:     | llvm-objdump --mattr=+experimental-zbb -d -r - \
+# RUN:     | llvm-objdump --mattr=+experimental-zbb -M no-aliases -d -r - \
 # RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
 
 # CHECK-ASM-AND-OBJ: clz t0, t1
@@ -39,3 +39,6 @@ max t0, t1, t2
 # CHECK-ASM-AND-OBJ: maxu t0, t1, t2
 # CHECK-ASM: encoding: [0xb3,0x72,0x73,0x0a]
 maxu t0, t1, t2
+# 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/rv32zbp-valid.s b/llvm/test/MC/RISCV/rv32zbp-valid.s
index d791ebe518a5..270c8e242193 100644
--- a/llvm/test/MC/RISCV/rv32zbp-valid.s
+++ b/llvm/test/MC/RISCV/rv32zbp-valid.s
@@ -3,14 +3,14 @@
 # RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
 # RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-b < %s \
 # RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
-# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN:     | FileCheck --check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
 
 # With Bitmanip permutation extension:
 # RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zbp -show-encoding \
 # RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
 # RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zbp < %s \
 # RUN:     | llvm-objdump --mattr=+experimental-zbp -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: slo t0, t1, t2
 # CHECK-ASM: encoding: [0xb3,0x12,0x73,0x20]
@@ -57,3 +57,10 @@ packu t0, t1, t2
 # CHECK-ASM-AND-OBJ: packh t0, t1, t2
 # CHECK-ASM: encoding: [0xb3,0x72,0x73,0x08]
 packh t0, t1, t2
+# CHECK-ASM-AND-OBJ: zext.h t0, t1
+# CHECK-ASM: encoding: [0xb3,0x42,0x03,0x08]
+zext.h t0, t1
+# CHECK-ASM: pack t0, t1, zero
+# CHECK-OBJ: zext.h t0, t1
+# CHECK-ASM: encoding: [0xb3,0x42,0x03,0x08]
+pack t0, t1, x0

diff  --git a/llvm/test/MC/RISCV/rv64b-aliases-valid.s b/llvm/test/MC/RISCV/rv64b-aliases-valid.s
index 4b58c3b791f4..eb9b7b66986c 100644
--- a/llvm/test/MC/RISCV/rv64b-aliases-valid.s
+++ b/llvm/test/MC/RISCV/rv64b-aliases-valid.s
@@ -19,7 +19,7 @@
 # CHECK-S-OBJ: andi t0, t1, 255
 zext.b x5, x6
 
-# CHECK-S-OBJ-NOALIAS: packw t0, t1, zero
+# CHECK-S-OBJ-NOALIAS: zext.h t0, t1
 # CHECK-S-OBJ: zext.h t0, t1
 zext.h x5, x6
 

diff  --git a/llvm/test/MC/RISCV/rv64zbb-valid.s b/llvm/test/MC/RISCV/rv64zbb-valid.s
index 6d43895a96cd..c2809ea0ca72 100644
--- a/llvm/test/MC/RISCV/rv64zbb-valid.s
+++ b/llvm/test/MC/RISCV/rv64zbb-valid.s
@@ -6,10 +6,10 @@
 # RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
 
 # With Bitmanip base extension:
-# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbb -show-encoding \
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbb -riscv-no-aliases -show-encoding \
 # RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
 # RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zbb < %s \
-# RUN:     | llvm-objdump --mattr=+experimental-zbb -d -r - \
+# RUN:     | llvm-objdump --mattr=+experimental-zbb -M no-aliases -d -r - \
 # RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
 
 # CHECK-ASM-AND-OBJ: clzw t0, t1
@@ -21,3 +21,6 @@ ctzw t0, t1
 # CHECK-ASM-AND-OBJ: cpopw t0, t1
 # CHECK-ASM: encoding: [0x9b,0x12,0x23,0x60]
 cpopw t0, t1
+# CHECK-ASM-AND-OBJ: zext.h t0, t1
+# CHECK-ASM: encoding: [0xbb,0x42,0x03,0x08]
+zext.h t0, t1

diff  --git a/llvm/test/MC/RISCV/rv64zbp-valid.s b/llvm/test/MC/RISCV/rv64zbp-valid.s
index af0ab74a3eea..9a6cca1e62b3 100644
--- a/llvm/test/MC/RISCV/rv64zbp-valid.s
+++ b/llvm/test/MC/RISCV/rv64zbp-valid.s
@@ -3,14 +3,14 @@
 # RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
 # RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-b < %s \
 # RUN:     | llvm-objdump --mattr=+experimental-b -d -r - \
-# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN:     | FileCheck --check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s
 
 # With Bitmanip permutation extension:
 # RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbp -show-encoding \
 # RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
 # RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zbp < %s \
 # RUN:     | llvm-objdump --mattr=+experimental-zbp -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: slow t0, t1, t2
 # CHECK-ASM: encoding: [0xbb,0x12,0x73,0x20]
@@ -48,3 +48,10 @@ packw t0, t1, t2
 # CHECK-ASM-AND-OBJ: packuw t0, t1, t2
 # CHECK-ASM: encoding: [0xbb,0x42,0x73,0x48]
 packuw t0, t1, t2
+# CHECK-ASM-AND-OBJ: zext.h t0, t1
+# CHECK-ASM: encoding: [0xbb,0x42,0x03,0x08]
+zext.h t0, t1
+# CHECK-ASM: packw t0, t1, zero
+# CHECK-OBJ: zext.h t0, t1
+# CHECK-ASM: encoding: [0xbb,0x42,0x03,0x08]
+packw t0, t1, x0


        


More information about the llvm-branch-commits mailing list