ksyx updated this revision to Diff 413211.
ksyx added a comment.
Herald added a subscriber: jdoerfert.

Rebase and adapt to new ISAInfo module.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103313/new/

https://reviews.llvm.org/D103313

Files:
  clang/lib/Basic/Targets/RISCV.cpp
  clang/test/Driver/riscv-arch.c
  llvm/lib/Support/RISCVISAInfo.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/attributes.ll
  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{{w?}} {{[as]}}{{[0-9]}}, {{[as]}}{{[0-9]}}, {{[as]}}{{[0-9]}}
+  %5 = srem i32 %4, %a
+  ret i32 %5
+}
Index: llvm/test/CodeGen/RISCV/attributes.ll
===================================================================
--- llvm/test/CodeGen/RISCV/attributes.ll
+++ llvm/test/CodeGen/RISCV/attributes.ll
@@ -67,7 +67,7 @@
 ; RUN: llc -mtriple=riscv64 -mattr=+zkt %s -o - | FileCheck --check-prefix=RV64ZKT %s
 ; RUN: llc -mtriple=riscv64 -mattr=+zk %s -o - | FileCheck --check-prefix=RV64ZK %s
 
-; RV32M: .attribute 5, "rv32i2p0_m2p0"
+; RV32M: .attribute 5, "rv32i2p0_m2p0_zmmul0p1"
 ; RV32A: .attribute 5, "rv32i2p0_a2p0"
 ; RV32F: .attribute 5, "rv32i2p0_f2p0"
 ; RV32D: .attribute 5, "rv32i2p0_f2p0_d2p0"
@@ -101,7 +101,7 @@
 ; RV32ZKT: .attribute 5, "rv32i2p0_zkt1p0"
 ; RV32ZK: .attribute 5, "rv32i2p0_zbkb1p0_zbkc1p0_zbkx1p0_zk1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0_zkr1p0_zkt1p0"
 
-; RV64M: .attribute 5, "rv64i2p0_m2p0"
+; RV64M: .attribute 5, "rv64i2p0_m2p0_zmmul0p1"
 ; RV64A: .attribute 5, "rv64i2p0_a2p0"
 ; RV64F: .attribute 5, "rv64i2p0_f2p0"
 ; RV64D: .attribute 5, "rv64i2p0_f2p0_d2p0"
Index: llvm/lib/Target/RISCV/RISCVSubtarget.h
===================================================================
--- llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -101,6 +101,7 @@
   bool HasStdExtZks = false;
   bool HasStdExtZkt = false;
   bool HasStdExtZk = false;
+  bool HasStdExtZmmul = false;
   bool HasRV64 = false;
   bool IsRV32E = false;
   bool EnableLinkerRelax = false;
@@ -189,6 +190,7 @@
   bool hasStdExtZksed() const { return HasStdExtZksed; }
   bool hasStdExtZksh() const { return HasStdExtZksh; }
   bool hasStdExtZkr() const { return HasStdExtZkr; }
+  bool hasStdExtZmmul() const { return HasStdExtZmmul; }
   bool is64Bit() const { return HasRV64; }
   bool isRV32E() const { return IsRV32E; }
   bool enableLinkerRelax() const { return EnableLinkerRelax; }
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 {
 // Select W instructions if only the lower 32-bits of the result are used.
+let Predicates = [HasStdExtZmmul, IsRV64] in
 def : PatGprGpr<binop_allwusers<mul>, MULW>;
 
+let Predicates = [HasStdExtM, IsRV64] in {
 def : PatGprGpr<riscv_divw, DIVW>;
 def : PatGprGpr<riscv_divuw, DIVUW>;
 def : PatGprGpr<riscv_remuw, REMUW>;
@@ -96,11 +106,11 @@
           (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
 // zeroing the upper 32 bits.
 def : Pat<(i64 (mul (and GPR:$rs1, 0xffffffff), (and GPR:$rs2, 0xffffffff))),
           (MULHU (SLLI GPR:$rs1, 32), (SLLI GPR:$rs2, 32))>;
-} // 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
@@ -214,19 +214,26 @@
     setLibcallName(RTLIB::MULO_I64, nullptr);
   }
 
-  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);
@@ -236,8 +243,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/Support/RISCVISAInfo.cpp
===================================================================
--- llvm/lib/Support/RISCVISAInfo.cpp
+++ llvm/lib/Support/RISCVISAInfo.cpp
@@ -104,6 +104,8 @@
     {"zbp", RISCVExtensionVersion{0, 93}},
     {"zbr", RISCVExtensionVersion{0, 93}},
     {"zbt", RISCVExtensionVersion{0, 93}},
+
+    {"zmmul", RISCVExtensionVersion{0, 1}},
 };
 
 static bool stripExperimentalPrefix(StringRef &Ext) {
Index: clang/test/Driver/riscv-arch.c
===================================================================
--- clang/test/Driver/riscv-arch.c
+++ clang/test/Driver/riscv-arch.c
@@ -414,3 +414,22 @@
 // RUN: %clang -target riscv32-unknown-elf -march=rv32iv1p0_zvl32b1p0 -### %s -c 2>&1 | \
 // RUN:   FileCheck -check-prefix=RV32-ZVL-GOODVERS %s
 // RV32-ZVL-GOODVERS: "-target-feature" "+zvl32b"
+
+// 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/Basic/Targets/RISCV.cpp
===================================================================
--- clang/lib/Basic/Targets/RISCV.cpp
+++ clang/lib/Basic/Targets/RISCV.cpp
@@ -158,8 +158,10 @@
     Builder.defineMacro(Twine("__riscv_", ExtName), Twine(Version));
   }
 
-  if (ISAInfo->hasExtension("m")) {
+  if (ISAInfo->hasExtension("m") || ISAInfo->hasExtension("zmmul"))
     Builder.defineMacro("__riscv_mul");
+
+  if (ISAInfo->hasExtension("m")) {
     Builder.defineMacro("__riscv_div");
     Builder.defineMacro("__riscv_muldiv");
   }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to