[RISCV] Add inline asm constraint 'vr' and 'vm' in Clang for RISC-V 'V'.
authorHsiangkai Wang <kai.wang@sifive.com>
Mon, 29 Mar 2021 10:27:27 +0000 (18:27 +0800)
committerHsiangkai Wang <kai.wang@sifive.com>
Tue, 30 Mar 2021 01:47:27 +0000 (09:47 +0800)
Add asm constraint 'vr' for vector registers.
Add asm constraint 'vm' for vector mask registers.

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

clang/lib/Basic/Targets/RISCV.cpp
clang/lib/Basic/Targets/RISCV.h
clang/test/CodeGen/RISCV/riscv-inline-asm-rvv.c [new file with mode: 0644]

index aee5aba..4ca4141 100644 (file)
@@ -31,7 +31,13 @@ ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const {
       "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
       "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
       "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
-      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"};
+      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+
+      // Vector registers
+      "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",
+      "v8",  "v9",  "v10", "v11", "v12", "v13", "v14", "v15",
+      "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
+      "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"};
   return llvm::makeArrayRef(GCCRegNames);
 }
 
@@ -81,7 +87,29 @@ bool RISCVTargetInfo::validateAsmConstraint(
     // An address that is held in a general-purpose register.
     Info.setAllowsMemory();
     return true;
+  case 'v':
+    // A vector register.
+    if (Name[1] == 'r' || Name[1] == 'm') {
+      Info.setAllowsRegister();
+      Name += 1;
+      return true;
+    }
+    return false;
+  }
+}
+
+std::string RISCVTargetInfo::convertConstraint(const char *&Constraint) const {
+  std::string R;
+  switch (*Constraint) {
+  case 'v':
+    R = std::string("v");
+    Constraint += 1;
+    break;
+  default:
+    R = TargetInfo::convertConstraint(Constraint);
+    break;
   }
+  return R;
 }
 
 void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
index 8df6e05..4fc8cd1 100644 (file)
@@ -97,6 +97,8 @@ public:
   bool validateAsmConstraint(const char *&Name,
                              TargetInfo::ConstraintInfo &Info) const override;
 
+  std::string convertConstraint(const char *&Constraint) const override;
+
   bool hasFeature(StringRef Feature) const override;
 
   bool handleTargetFeatures(std::vector<std::string> &Features,
diff --git a/clang/test/CodeGen/RISCV/riscv-inline-asm-rvv.c b/clang/test/CodeGen/RISCV/riscv-inline-asm-rvv.c
new file mode 100644 (file)
index 0000000..1455877
--- /dev/null
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple riscv32 -target-feature +experimental-v \
+// RUN:     -O2 -emit-llvm %s -o - \
+// RUN:     | FileCheck %s
+// RUN: %clang_cc1 -triple riscv64 -target-feature +experimental-v \
+// RUN:     -O2 -emit-llvm %s -o - \
+// RUN:     | FileCheck %s
+
+// Test RISC-V V-extension specific inline assembly constraints.
+#include <riscv_vector.h>
+
+void test_v_reg() {
+  asm volatile(
+      "vsetvli x1, x0, e32,m2,tu,mu\n"
+      "vadd.vv v1, v2, v3, v0.t"
+      :
+      :
+      : "v1", "x1");
+// CHECK-LABEL: define{{.*}} @test_v_reg
+// CHECK: "~{v1},~{x1}"
+}
+
+vint32m1_t test_vr(vint32m1_t a, vint32m1_t b) {
+// CHECK-LABEL: define{{.*}} @test_vr
+// CHECK: %0 = tail call <vscale x 2 x i32> asm sideeffect "vadd.vv $0, $1, $2", "=v,v,v"(<vscale x 2 x i32> %a, <vscale x 2 x i32> %b)
+  vint32m1_t ret;
+  asm volatile ("vadd.vv %0, %1, %2" : "=vr"(ret) : "vr"(a), "vr"(b));
+  return ret;
+}
+
+vbool1_t test_vm(vbool1_t a, vbool1_t b) {
+// CHECK-LABEL: define{{.*}} @test_vm
+// CHECK: %0 = tail call <vscale x 64 x i1> asm sideeffect "vmand.mm $0, $1, $2", "=v,v,v"(<vscale x 64 x i1> %a, <vscale x 64 x i1> %b)
+  vbool1_t ret;
+  asm volatile ("vmand.mm %0, %1, %2" : "=vm"(ret) : "vm"(a), "vm"(b));
+  return ret;
+}