ksyx updated this revision to Diff 351083.
ksyx added a comment.
add: zmmul arch string test
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D103313/new/
https://reviews.llvm.org/D103313
Files:
clang/lib/Basic/Targets/RISCV.cpp
clang/lib/Basic/Targets/RISCV.h
clang/lib/Driver/ToolChains/Arch/RISCV.cpp
clang/test/Driver/riscv-arch.c
llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
llvm/lib/Target/RISCV/RISCV.td
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/lib/Target/RISCV/RISCVInstrInfoM.td
llvm/lib/Target/RISCV/RISCVSubtarget.h
llvm/test/CodeGen/RISCV/zmmul.ll
llvm/test/MC/RISCV/rv32i-invalid.s
llvm/test/MC/RISCV/rv32zmmul-invaild.s
llvm/test/MC/RISCV/rv32zmmul-valid.s
llvm/test/MC/RISCV/rv64zmmul-invalid.s
llvm/test/MC/RISCV/rv64zmmul-valid.s
Index: llvm/test/MC/RISCV/rv64zmmul-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv64zmmul-valid.s
@@ -0,0 +1,5 @@
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zmmul -riscv-no-aliases 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK-INST %s
+
+# CHECK-INST: mulw ra, sp, gp
+mulw ra, sp, gp
Index: llvm/test/MC/RISCV/rv64zmmul-invalid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv64zmmul-invalid.s
@@ -0,0 +1,14 @@
+# RUN: not llvm-mc %s -triple=riscv64 -mattr=+experimental-zmmul -riscv-no-aliases 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK-ERROR %s
+
+# CHECK-ERROR: 5:1: error: instruction requires the following: 'M' (Integer Multiplication and Division)
+divw tp, t0, t1
+
+# CHECK-ERROR: 8:1: error: instruction requires the following: 'M' (Integer Multiplication and Division)
+divuw t2, s0, s2
+
+# CHECK-ERROR: 11:1: error: instruction requires the following: 'M' (Integer Multiplication and Division)
+remw a0, a1, a2
+
+# CHECK-ERROR: 14:1: error: instruction requires the following: 'M' (Integer Multiplication and Division)
+remuw a3, a4, a5
Index: llvm/test/MC/RISCV/rv32zmmul-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv32zmmul-valid.s
@@ -0,0 +1,14 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zmmul -riscv-no-aliases 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK-INST %s
+
+# CHECK-INST: mul a4, ra, s0
+mul a4, ra, s0
+
+# CHECK-INST: mulh ra, zero, zero
+mulh x1, x0, x0
+
+# CHECK-INST: mulhsu t0, t2, t1
+mulhsu t0, t2, t1
+
+# CHECK-INST: mulhu a5, a4, a3
+mulhu a5, a4, a3
Index: llvm/test/MC/RISCV/rv32zmmul-invaild.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv32zmmul-invaild.s
@@ -0,0 +1,14 @@
+# RUN: not llvm-mc %s -triple=riscv32 -mattr=+experimental-zmmul -riscv-no-aliases 2>&1 \
+# RUN: | FileCheck -check-prefixes=CHECK-ERROR %s
+
+# CHECK-ERROR: 5:1: error: instruction requires the following: 'M' (Integer Multiplication and Division)
+div s0, s0, s0
+
+# CHECK-ERROR: 8:1: error: instruction requires the following: 'M' (Integer Multiplication and Division)
+divu gp, a0, a1
+
+# CHECK-ERROR: 11:1: error: instruction requires the following: 'M' (Integer Multiplication and Division)
+rem s2, s2, s8
+
+# CHECK-ERROR: 14:1: error: instruction requires the following: 'M' (Integer Multiplication and Division)
+remu x18, x18, x24
Index: llvm/test/MC/RISCV/rv32i-invalid.s
===================================================================
--- llvm/test/MC/RISCV/rv32i-invalid.s
+++ llvm/test/MC/RISCV/rv32i-invalid.s
@@ -169,7 +169,7 @@
xor s2, s2 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
# Instruction not in the base ISA
-mul a4, ra, s0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'M' (Integer Multiplication and Division)
+div a4, ra, s0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'M' (Integer Multiplication and Division)
amomaxu.w s5, s4, (s3) # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'A' (Atomic Instructions)
fadd.s ft0, ft1, ft2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'F' (Single-Precision Floating-Point)
fadd.h ft0, ft1, ft2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zfh' (Half-Precision Floating-Point)
Index: llvm/test/CodeGen/RISCV/zmmul.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/RISCV/zmmul.ll
@@ -0,0 +1,41 @@
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zmmul -verify-machineinstrs < %s \
+; RUN: | not FileCheck -check-prefix=CHECK-DIV %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-zmmul -verify-machineinstrs < %s \
+; RUN: | not FileCheck -check-prefix=CHECK-DIV %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zmmul -verify-machineinstrs < %s \
+; RUN: | not FileCheck -check-prefix=CHECK-REM %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-zmmul -verify-machineinstrs < %s \
+; RUN: | not FileCheck -check-prefix=CHECK-REM %s
+
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zmmul -verify-machineinstrs < %s \
+; RUN: | not FileCheck -check-prefix=CHECK-UDIV %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-zmmul -verify-machineinstrs < %s \
+; RUN: | not FileCheck -check-prefix=CHECK-UDIV %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zmmul -verify-machineinstrs < %s \
+; RUN: | not FileCheck -check-prefix=CHECK-UREM %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-zmmul -verify-machineinstrs < %s \
+; RUN: | not FileCheck -check-prefix=CHECK-UREM %s
+
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zmmul -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=CHECK-MUL %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-zmmul -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=CHECK-MUL %s
+
+; RUN: llc -mtriple=riscv32 -mattr=+m -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefixes=CHECK-MUL,CHECK-UDIV,CHECK-DIV,CHECK-UREM,CHECK-REM %s
+; RUN: llc -mtriple=riscv64 -mattr=+m -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefixes=CHECK-MUL,CHECK-UDIV,CHECK-DIV,CHECK-UREM,CHECK-REM %s
+
+define i32 @foo(i32 %a, i32 %b) {
+; CHECK-UDIV: divu{{w?}} {{[as]}}{{[0-9]}}, {{[as]}}{{[0-9]}}, {{[as]}}{{[0-9]}}
+ %1 = udiv i32 %a, %b
+; CHECK-DIV: div{{w?}} {{[as]}}{{[0-9]}}, {{[as]}}{{[0-9]}}, {{[as]}}{{[0-9]}}
+ %2 = sdiv i32 %a, %1
+; CHECK-MUL: mul{{w?}} {{[as]}}{{[0-9]}}, {{[as]}}{{[0-9]}}, {{[as]}}{{[0-9]}}
+ %3 = mul i32 %b, %2
+; CHECK-UREM: remu{{w?}} {{[as]}}{{[0-9]}}, {{[as]}}{{[0-9]}}, {{[as]}}{{[0-9]}}
+ %4 = urem i32 %3, %b
+; CHECK-REM: rem {{[as]}}{{[0-9]}}, {{[as]}}{{[0-9]}}, {{[as]}}{{[0-9]}}
+ %5 = srem i32 %4, %a
+ ret i32 %5
+}
Index: llvm/lib/Target/RISCV/RISCVSubtarget.h
===================================================================
--- llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -35,6 +35,7 @@
class RISCVSubtarget : public RISCVGenSubtargetInfo {
virtual void anchor();
bool HasStdExtM = false;
+ bool HasStdExtZmmul = false;
bool HasStdExtA = false;
bool HasStdExtF = false;
bool HasStdExtD = false;
@@ -103,6 +104,7 @@
}
bool enableMachineScheduler() const override { return true; }
bool hasStdExtM() const { return HasStdExtM; }
+ bool hasStdExtZmmul() const { return HasStdExtZmmul; }
bool hasStdExtA() const { return HasStdExtA; }
bool hasStdExtF() const { return HasStdExtF; }
bool hasStdExtD() const { return HasStdExtD; }
Index: llvm/lib/Target/RISCV/RISCVInstrInfoM.td
===================================================================
--- llvm/lib/Target/RISCV/RISCVInstrInfoM.td
+++ llvm/lib/Target/RISCV/RISCVInstrInfoM.td
@@ -24,7 +24,7 @@
// Instructions
//===----------------------------------------------------------------------===//
-let Predicates = [HasStdExtM] in {
+let Predicates = [HasStdExtZmmul] in {
def MUL : ALU_rr<0b0000001, 0b000, "mul">,
Sched<[WriteIMul, ReadIMul, ReadIMul]>;
def MULH : ALU_rr<0b0000001, 0b001, "mulh">,
@@ -33,6 +33,9 @@
Sched<[WriteIMul, ReadIMul, ReadIMul]>;
def MULHU : ALU_rr<0b0000001, 0b011, "mulhu">,
Sched<[WriteIMul, ReadIMul, ReadIMul]>;
+} // Predicates = [HasStdExtZmmul]
+
+let Predicates = [HasStdExtM] in {
def DIV : ALU_rr<0b0000001, 0b100, "div">,
Sched<[WriteIDiv, ReadIDiv, ReadIDiv]>;
def DIVU : ALU_rr<0b0000001, 0b101, "divu">,
@@ -43,9 +46,12 @@
Sched<[WriteIDiv, ReadIDiv, ReadIDiv]>;
} // Predicates = [HasStdExtM]
-let Predicates = [HasStdExtM, IsRV64] in {
+let Predicates = [HasStdExtZmmul, IsRV64] in {
def MULW : ALUW_rr<0b0000001, 0b000, "mulw">,
Sched<[WriteIMul32, ReadIMul32, ReadIMul32]>;
+} // Predicates = [HasStdExtZmmul, IsRV64]
+
+let Predicates = [HasStdExtM, IsRV64] in {
def DIVW : ALUW_rr<0b0000001, 0b100, "divw">,
Sched<[WriteIDiv32, ReadIDiv32, ReadIDiv32]>;
def DIVUW : ALUW_rr<0b0000001, 0b101, "divuw">,
@@ -60,21 +66,25 @@
// Pseudo-instructions and codegen patterns
//===----------------------------------------------------------------------===//
-let Predicates = [HasStdExtM] in {
+let Predicates = [HasStdExtZmmul] in {
def : PatGprGpr<mul, MUL>;
def : PatGprGpr<mulhs, MULH>;
def : PatGprGpr<mulhu, MULHU>;
def : PatGprGpr<riscv_mulhsu, MULHSU>;
+} // Predicates = [HasStdExtZmmul]
+
+let Predicates = [HasStdExtM] in {
def : PatGprGpr<sdiv, DIV>;
def : PatGprGpr<udiv, DIVU>;
def : PatGprGpr<srem, REM>;
def : PatGprGpr<urem, REMU>;
} // Predicates = [HasStdExtM]
-let Predicates = [HasStdExtM, IsRV64] in {
+let Predicates = [HasStdExtZmmul] in
def : Pat<(sext_inreg (mul GPR:$rs1, GPR:$rs2), i32),
(MULW GPR:$rs1, GPR:$rs2)>;
+let Predicates = [HasStdExtM, IsRV64] in {
def : PatGprGpr<riscv_divw, DIVW>;
def : PatGprGpr<riscv_divuw, DIVUW>;
def : PatGprGpr<riscv_remuw, REMUW>;
@@ -96,7 +106,7 @@
(REMW GPR:$rs1, GPR:$rs2)>;
} // Predicates = [HasStdExtM, IsRV64]
-let Predicates = [HasStdExtM, IsRV64, NotHasStdExtZba] in {
+let Predicates = [HasStdExtZmmul, IsRV64, NotHasStdExtZba] in {
// Special case for calculating the full 64-bit product of a 32x32 unsigned
// multiply where the inputs aren't known to be zero extended. We can shift the
// inputs left by 32 and use a MULHU. This saves two SRLIs needed to finish
@@ -112,4 +122,4 @@
def : Pat<(sext_inreg (mul (and GPR:$rs1, 0xffffffff),
(and GPR:$rs2, 0xffffffff)), i32),
(ADDIW (MULHU (SLLI GPR:$rs1, 32), (SLLI GPR:$rs2, 32)), 0)>;
-} // Predicates = [HasStdExtM, IsRV64, NotHasStdExtZba]
+} // Predicates = [HasStdExtZmmul, IsRV64, NotHasStdExtZba]
Index: llvm/lib/Target/RISCV/RISCVISelLowering.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -201,19 +201,26 @@
setOperationAction(ISD::USUBSAT, MVT::i32, Custom);
}
- if (!Subtarget.hasStdExtM()) {
+ if (!Subtarget.hasStdExtZmmul()) {
setOperationAction(ISD::MUL, XLenVT, Expand);
setOperationAction(ISD::MULHS, XLenVT, Expand);
setOperationAction(ISD::MULHU, XLenVT, Expand);
+ } else {
+ if (Subtarget.is64Bit()) {
+ setOperationAction(ISD::MUL, MVT::i32, Custom);
+ setOperationAction(ISD::MUL, MVT::i128, Custom);
+ } else {
+ setOperationAction(ISD::MUL, MVT::i64, Custom);
+ }
+ }
+
+ if (!Subtarget.hasStdExtM()) {
setOperationAction(ISD::SDIV, XLenVT, Expand);
setOperationAction(ISD::UDIV, XLenVT, Expand);
setOperationAction(ISD::SREM, XLenVT, Expand);
setOperationAction(ISD::UREM, XLenVT, Expand);
} else {
if (Subtarget.is64Bit()) {
- setOperationAction(ISD::MUL, MVT::i32, Custom);
- setOperationAction(ISD::MUL, MVT::i128, Custom);
-
setOperationAction(ISD::SDIV, MVT::i8, Custom);
setOperationAction(ISD::UDIV, MVT::i8, Custom);
setOperationAction(ISD::UREM, MVT::i8, Custom);
@@ -223,8 +230,6 @@
setOperationAction(ISD::SDIV, MVT::i32, Custom);
setOperationAction(ISD::UDIV, MVT::i32, Custom);
setOperationAction(ISD::UREM, MVT::i32, Custom);
- } else {
- setOperationAction(ISD::MUL, MVT::i64, Custom);
}
}
Index: llvm/lib/Target/RISCV/RISCV.td
===================================================================
--- llvm/lib/Target/RISCV/RISCV.td
+++ llvm/lib/Target/RISCV/RISCV.td
@@ -12,9 +12,17 @@
// RISC-V subtarget features and instruction predicates.
//===----------------------------------------------------------------------===//
+def FeatureStdExtZmmul
+ : SubtargetFeature<"experimental-zmmul", "HasStdExtZmmul", "true",
+ "'Zmmul' (Integer Multiplication)">;
+def HasStdExtZmmul : Predicate<"Subtarget->hasStdExtZmmul()">,
+ AssemblerPredicate<(all_of FeatureStdExtZmmul),
+ "'Zmmul' (Integer Multiplication)">;
+
def FeatureStdExtM
: SubtargetFeature<"m", "HasStdExtM", "true",
- "'M' (Integer Multiplication and Division)">;
+ "'M' (Integer Multiplication and Division)",
+ [FeatureStdExtZmmul]>;
def HasStdExtM : Predicate<"Subtarget->hasStdExtM()">,
AssemblerPredicate<(all_of FeatureStdExtM),
"'M' (Integer Multiplication and Division)">;
Index: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
===================================================================
--- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -2056,6 +2056,7 @@
clearFeatureBits(RISCV::FeatureExtZbr, "experimental-zbr");
clearFeatureBits(RISCV::FeatureExtZbs, "experimental-zbs");
clearFeatureBits(RISCV::FeatureExtZbt, "experimental-zbt");
+ clearFeatureBits(RISCV::FeatureStdExtZmmul, "experimental-zmmul");
clearFeatureBits(RISCV::FeatureExtZvamo, "experimental-zvamo");
clearFeatureBits(RISCV::FeatureStdExtZvlsseg, "experimental-zvlsseg");
@@ -2114,6 +2115,8 @@
setFeatureBits(RISCV::FeatureExtZbt, "experimental-zbt");
else if (Ext == "zfh")
setFeatureBits(RISCV::FeatureExtZfh, "experimental-zfh");
+ else if (Ext == "zmmul")
+ setFeatureBits(RISCV::FeatureStdExtZmmul, "experimental-zmmul");
else if (Ext == "zvamo")
setFeatureBits(RISCV::FeatureExtZvamo, "experimental-zvamo");
else if (Ext == "zvlsseg")
Index: clang/test/Driver/riscv-arch.c
===================================================================
--- clang/test/Driver/riscv-arch.c
+++ clang/test/Driver/riscv-arch.c
@@ -488,3 +488,22 @@
// RUN: %clang -target riscv32-unknown-elf -march=rv32izvlsseg0p10 -menable-experimental-extensions -### %s -c 2>&1 | \
// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZVLSSEG-GOODVERS %s
// RV32-EXPERIMENTAL-ZVLSSEG-GOODVERS: "-target-feature" "+experimental-zvlsseg"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32i_zmmul -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-ZMMUL-NOFLAG %s
+// RV32-EXPERIMENTAL-ZMMUL-NOFLAG: error: invalid arch name 'rv32i_zmmul'
+// RV32-EXPERIMENTAL-ZMMUL-NOFLAG: requires '-menable-experimental-extensions'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32i_zmmul -menable-experimental-extensions -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-ZMMUL-NOVERS %s
+// RV32-EXPERIMENTAL-ZMMUL-NOVERS: error: invalid arch name 'rv32i_zmmul'
+// RV32-EXPERIMENTAL-ZMMUL-NOVERS: experimental extension requires explicit version number
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32i_zmmul2p0 -menable-experimental-extensions -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-ZMMUL-BADVERS %s
+// RV32-EXPERIMENTAL-ZMMUL-BADVERS: error: invalid arch name 'rv32i_zmmul2p0'
+// RV32-EXPERIMENTAL-ZMMUL-BADVERS: unsupported version number 2.0 for experimental extension
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32i_zmmul0p1 -menable-experimental-extensions -### %s \
+// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-ZMMUL-GOODVERS %s
+// RV32-EXPERIMENTAL-ZMMUL-GOODVERS: "-target-feature" "+experimental-zmmul"
Index: clang/lib/Driver/ToolChains/Arch/RISCV.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -66,6 +66,8 @@
return RISCVExtensionVersion{"0", "10"};
if (Ext == "zfh")
return RISCVExtensionVersion{"0", "1"};
+ if (Ext == "zmmul")
+ return RISCVExtensionVersion{"0", "1"};
return None;
}
Index: clang/lib/Basic/Targets/RISCV.h
===================================================================
--- clang/lib/Basic/Targets/RISCV.h
+++ clang/lib/Basic/Targets/RISCV.h
@@ -44,6 +44,7 @@
bool HasZbs = false;
bool HasZbt = false;
bool HasZfh = false;
+ bool HasZmmul = false;
bool HasZvamo = false;
bool HasZvlsseg = false;
Index: clang/lib/Basic/Targets/RISCV.cpp
===================================================================
--- clang/lib/Basic/Targets/RISCV.cpp
+++ clang/lib/Basic/Targets/RISCV.cpp
@@ -141,9 +141,12 @@
Builder.defineMacro("__riscv_arch_test");
Builder.defineMacro("__riscv_i", "2000000");
+ if (HasZmmul || HasM) {
+ Builder.defineMacro("__riscv_mul");
+ }
+
if (HasM) {
Builder.defineMacro("__riscv_m", "2000000");
- Builder.defineMacro("__riscv_mul");
Builder.defineMacro("__riscv_div");
Builder.defineMacro("__riscv_muldiv");
}
@@ -276,6 +279,7 @@
.Case("experimental-zbs", HasZbs)
.Case("experimental-zbt", HasZbt)
.Case("experimental-zfh", HasZfh)
+ .Case("experimental-zmmul", HasZmmul)
.Case("experimental-zvamo", HasZvamo)
.Case("experimental-zvlsseg", HasZvlsseg)
.Default(false);
@@ -323,6 +327,8 @@
HasZbt = true;
else if (Feature == "+experimental-zfh")
HasZfh = true;
+ else if (Feature == "+experimental-zmmul")
+ HasZmmul = true;
else if (Feature == "+experimental-zvamo")
HasZvamo = true;
else if (Feature == "+experimental-zvlsseg")
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits