[clang] [llvm] [RISCV] Mark {vl, vtype} as clobber in inline assembly (PR #128636)
Hank Chang via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 25 19:56:51 PST 2025
https://github.com/HankChang736 updated https://github.com/llvm/llvm-project/pull/128636
>From d7718e9ed9f03990895f0d89b87808d8c96bb67c Mon Sep 17 00:00:00 2001
From: Hank Chang <hank.chang at sifive.com>
Date: Sun, 23 Feb 2025 23:59:23 +0800
Subject: [PATCH 1/2] [RISCV] Mark {vl, vtype} as clobber in inline assembly
This patch use the hook getClobbers() in RISCV target and mark {vl, type} as clobber to prevent
Post-RA scheduler move vsetvl across inline assembly.
---
clang/lib/Basic/Targets/RISCV.h | 2 +-
.../CodeGen/RISCV/riscv-inline-asm-clobber.c | 48 ++++++++++++++-----
.../test/CodeGen/RISCV/riscv-inline-asm-rvv.c | 8 ++--
clang/test/CodeGen/RISCV/riscv-inline-asm.c | 42 ++++++++--------
.../rvv/vsetvl-cross-inline-asm-clobber.ll | 37 ++++++++++++++
.../RISCV/rvv/vsetvl-cross-inline-asm.ll | 37 ++++++++++++++
6 files changed, 136 insertions(+), 38 deletions(-)
create mode 100644 llvm/test/CodeGen/RISCV/rvv/vsetvl-cross-inline-asm-clobber.ll
create mode 100644 llvm/test/CodeGen/RISCV/rvv/vsetvl-cross-inline-asm.ll
diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index c26aa19080162..5590aa9d03c75 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -68,7 +68,7 @@ class RISCVTargetInfo : public TargetInfo {
return TargetInfo::VoidPtrBuiltinVaList;
}
- std::string_view getClobbers() const override { return ""; }
+ std::string_view getClobbers() const override { return "~{vl},~{vtype}"; }
StringRef getConstraintRegister(StringRef Constraint,
StringRef Expression) const override {
diff --git a/clang/test/CodeGen/RISCV/riscv-inline-asm-clobber.c b/clang/test/CodeGen/RISCV/riscv-inline-asm-clobber.c
index 8aa80386f205f..65cfc081fe26d 100644
--- a/clang/test/CodeGen/RISCV/riscv-inline-asm-clobber.c
+++ b/clang/test/CodeGen/RISCV/riscv-inline-asm-clobber.c
@@ -7,38 +7,62 @@
// Test RISC-V specific clobbered registers in inline assembly.
-// CHECK-LABEL: define {{.*}} void @test_fflags
-// CHECK: tail call void asm sideeffect "", "~{fflags}"()
+// CHECK-LABEL: define dso_local void @test_fflags(
+// CHECK-SAME: ) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: tail call void asm sideeffect "", "~{fflags},~{vl},~{vtype}"() #[[ATTR1:[0-9]+]], !srcloc [[META6:![0-9]+]]
+// CHECK-NEXT: ret void
+//
void test_fflags(void) {
asm volatile ("" :::"fflags");
}
-// CHECK-LABEL: define {{.*}} void @test_frm
-// CHECK: tail call void asm sideeffect "", "~{frm}"()
+// CHECK-LABEL: define dso_local void @test_frm(
+// CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: tail call void asm sideeffect "", "~{frm},~{vl},~{vtype}"() #[[ATTR1]], !srcloc [[META7:![0-9]+]]
+// CHECK-NEXT: ret void
+//
void test_frm(void) {
asm volatile ("" :::"frm");
}
-// CHECK-LABEL: define {{.*}} void @test_vtype
-// CHECK: tail call void asm sideeffect "", "~{vtype}"()
+// CHECK-LABEL: define dso_local void @test_vtype(
+// CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: tail call void asm sideeffect "", "~{vtype},~{vl},~{vtype}"() #[[ATTR1]], !srcloc [[META8:![0-9]+]]
+// CHECK-NEXT: ret void
+//
void test_vtype(void) {
asm volatile ("" :::"vtype");
}
-// CHECK-LABEL: define {{.*}} void @test_vl
-// CHECK: tail call void asm sideeffect "", "~{vl}"()
+// CHECK-LABEL: define dso_local void @test_vl(
+// CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: tail call void asm sideeffect "", "~{vl},~{vl},~{vtype}"() #[[ATTR1]], !srcloc [[META9:![0-9]+]]
+// CHECK-NEXT: ret void
+//
void test_vl(void) {
asm volatile ("" :::"vl");
}
-// CHECK-LABEL: define {{.*}} void @test_vxsat
-// CHECK: tail call void asm sideeffect "", "~{vxsat}"()
+// CHECK-LABEL: define dso_local void @test_vxsat(
+// CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: tail call void asm sideeffect "", "~{vxsat},~{vl},~{vtype}"() #[[ATTR1]], !srcloc [[META10:![0-9]+]]
+// CHECK-NEXT: ret void
+//
void test_vxsat(void) {
asm volatile ("" :::"vxsat");
}
-// CHECK-LABEL: define {{.*}} void @test_vxrm
-// CHECK: tail call void asm sideeffect "", "~{vxrm}"()
+// CHECK-LABEL: define dso_local void @test_vxrm(
+// CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT: entry:
+// CHECK-NEXT: tail call void asm sideeffect "", "~{vxrm},~{vl},~{vtype}"() #[[ATTR1]], !srcloc [[META11:![0-9]+]]
+// CHECK-NEXT: ret void
+//
void test_vxrm(void) {
asm volatile ("" :::"vxrm");
}
diff --git a/clang/test/CodeGen/RISCV/riscv-inline-asm-rvv.c b/clang/test/CodeGen/RISCV/riscv-inline-asm-rvv.c
index 879fb1238d83a..e9444c6a76d87 100644
--- a/clang/test/CodeGen/RISCV/riscv-inline-asm-rvv.c
+++ b/clang/test/CodeGen/RISCV/riscv-inline-asm-rvv.c
@@ -18,12 +18,12 @@ void test_v_reg() {
:
: "v1", "x1");
// CHECK-LABEL: define{{.*}} @test_v_reg
-// CHECK: "~{v1},~{x1}"
+// CHECK: "~{v1},~{x1},~{vl},~{vtype}"
}
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", "=^vr,^vr,^vr"(<vscale x 2 x i32> %a, <vscale x 2 x i32> %b)
+// CHECK: %0 = tail call <vscale x 2 x i32> asm sideeffect "vadd.vv $0, $1, $2", "=^vr,^vr,^vr,~{vl},~{vtype}"(<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;
@@ -31,7 +31,7 @@ vint32m1_t test_vr(vint32m1_t a, vint32m1_t b) {
vint32m1_t test_vd(vint32m1_t a, vint32m1_t b) {
// CHECK-LABEL: define{{.*}} @test_vd
-// CHECK: %0 = tail call <vscale x 2 x i32> asm sideeffect "vadd.vv $0, $1, $2", "=^vd,^vd,^vd"(<vscale x 2 x i32> %a, <vscale x 2 x i32> %b)
+// CHECK: %0 = tail call <vscale x 2 x i32> asm sideeffect "vadd.vv $0, $1, $2", "=^vd,^vd,^vd,~{vl},~{vtype}"(<vscale x 2 x i32> %a, <vscale x 2 x i32> %b)
vint32m1_t ret;
asm volatile ("vadd.vv %0, %1, %2" : "=vd"(ret) : "vd"(a), "vd"(b));
return ret;
@@ -39,7 +39,7 @@ vint32m1_t test_vd(vint32m1_t a, vint32m1_t b) {
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", "=^vm,^vm,^vm"(<vscale x 64 x i1> %a, <vscale x 64 x i1> %b)
+// CHECK: %0 = tail call <vscale x 64 x i1> asm sideeffect "vmand.mm $0, $1, $2", "=^vm,^vm,^vm,~{vl},~{vtype}"(<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;
diff --git a/clang/test/CodeGen/RISCV/riscv-inline-asm.c b/clang/test/CodeGen/RISCV/riscv-inline-asm.c
index f2031e0adcbcb..1a8ccb7ea5a68 100644
--- a/clang/test/CodeGen/RISCV/riscv-inline-asm.c
+++ b/clang/test/CodeGen/RISCV/riscv-inline-asm.c
@@ -7,17 +7,17 @@
long test_r(long x) {
// CHECK-LABEL: define{{.*}} {{i64|i32}} @test_r(
-// CHECK: call {{i64|i32}} asm sideeffect "", "=r,r"({{i64|i32}} %{{.*}})
+// CHECK: call {{i64|i32}} asm sideeffect "", "=r,r,~{vl},~{vtype}"({{i64|i32}} %{{.*}})
long ret;
asm volatile ("" : "=r"(ret) : "r"(x));
-// CHECK: call {{i64|i32}} asm sideeffect "", "=r,r"({{i64|i32}} %{{.*}})
+// CHECK: call {{i64|i32}} asm sideeffect "", "=r,r,~{vl},~{vtype}"({{i64|i32}} %{{.*}})
asm volatile ("" : "=r"(ret) : "r"(x));
return ret;
}
long test_cr(long x) {
// CHECK-LABEL: define{{.*}} {{i64|i32}} @test_cr(
-// CHECK: call {{i64|i32}} asm sideeffect "", "=^cr,^cr"({{i64|i32}} %{{.*}})
+// CHECK: call {{i64|i32}} asm sideeffect "", "=^cr,^cr,~{vl},~{vtype}"({{i64|i32}} %{{.*}})
long ret;
asm volatile ("" : "=cr"(ret) : "cr"(x));
return ret;
@@ -27,9 +27,9 @@ float cf;
double cd;
void test_cf(float f, double d) {
// CHECK-LABEL: define{{.*}} void @test_cf(
-// CHECK: call float asm sideeffect "", "=^cf,^cf"(float %{{.*}})
+// CHECK: call float asm sideeffect "", "=^cf,^cf,~{vl},~{vtype}"(float %{{.*}})
asm volatile("" : "=cf"(cf) : "cf"(f));
-// CHECK: call double asm sideeffect "", "=^cf,^cf"(double %{{.*}})
+// CHECK: call double asm sideeffect "", "=^cf,^cf,~{vl},~{vtype}"(double %{{.*}})
asm volatile("" : "=cf"(cd) : "cf"(d));
}
@@ -40,7 +40,7 @@ typedef __int128_t double_xlen_t;
#endif
double_xlen_t test_R_wide_scalar(double_xlen_t p) {
// CHECK-LABEL: define{{.*}} {{i128|i64}} @test_R_wide_scalar(
-// CHECK: call {{i128|i64}} asm sideeffect "", "=R,R"({{i128|i64}} %{{.*}})
+// CHECK: call {{i128|i64}} asm sideeffect "", "=R,R,~{vl},~{vtype}"({{i128|i64}} %{{.*}})
double_xlen_t ret;
asm volatile("" : "=R"(ret) : "R"(p));
return ret;
@@ -48,7 +48,7 @@ double_xlen_t test_R_wide_scalar(double_xlen_t p) {
double_xlen_t test_cR_wide_scalar(double_xlen_t p) {
// CHECK-LABEL: define{{.*}} {{i128|i64}} @test_cR_wide_scalar(
-// CHECK: call {{i128|i64}} asm sideeffect "", "=^cR,^cR"({{i128|i64}} %{{.*}})
+// CHECK: call {{i128|i64}} asm sideeffect "", "=^cR,^cR,~{vl},~{vtype}"({{i128|i64}} %{{.*}})
double_xlen_t ret;
asm volatile("" : "=cR"(ret) : "cR"(p));
return ret;
@@ -56,23 +56,23 @@ double_xlen_t test_cR_wide_scalar(double_xlen_t p) {
void test_I(void) {
// CHECK-LABEL: define{{.*}} void @test_I()
-// CHECK: call void asm sideeffect "", "I"(i32 2047)
+// CHECK: call void asm sideeffect "", "I,~{vl},~{vtype}"(i32 2047)
asm volatile ("" :: "I"(2047));
-// CHECK: call void asm sideeffect "", "I"(i32 -2048)
+// CHECK: call void asm sideeffect "", "I,~{vl},~{vtype}"(i32 -2048)
asm volatile ("" :: "I"(-2048));
}
void test_J(void) {
// CHECK-LABEL: define{{.*}} void @test_J()
-// CHECK: call void asm sideeffect "", "J"(i32 0)
+// CHECK: call void asm sideeffect "", "J,~{vl},~{vtype}"(i32 0)
asm volatile ("" :: "J"(0));
}
void test_K(void) {
// CHECK-LABEL: define{{.*}} void @test_K()
-// CHECK: call void asm sideeffect "", "K"(i32 31)
+// CHECK: call void asm sideeffect "", "K,~{vl},~{vtype}"(i32 31)
asm volatile ("" :: "K"(31));
-// CHECK: call void asm sideeffect "", "K"(i32 0)
+// CHECK: call void asm sideeffect "", "K,~{vl},~{vtype}"(i32 0)
asm volatile ("" :: "K"(0));
}
@@ -81,16 +81,16 @@ double d;
void test_f(void) {
// CHECK-LABEL: define{{.*}} void @test_f()
// CHECK: [[FLT_ARG:%[a-zA-Z_0-9]+]] = load float, ptr @f
-// CHECK: call void asm sideeffect "", "f"(float [[FLT_ARG]])
+// CHECK: call void asm sideeffect "", "f,~{vl},~{vtype}"(float [[FLT_ARG]])
asm volatile ("" :: "f"(f));
// CHECK: [[FLT_ARG:%[a-zA-Z_0-9]+]] = load double, ptr @d
-// CHECK: call void asm sideeffect "", "f"(double [[FLT_ARG]])
+// CHECK: call void asm sideeffect "", "f,~{vl},~{vtype}"(double [[FLT_ARG]])
asm volatile ("" :: "f"(d));
}
void test_A(int *p) {
// CHECK-LABEL: define{{.*}} void @test_A(ptr noundef %p)
-// CHECK: call void asm sideeffect "", "*A"(ptr elementtype(i32) %p)
+// CHECK: call void asm sideeffect "", "*A,~{vl},~{vtype}"(ptr elementtype(i32) %p)
asm volatile("" :: "A"(*p));
}
@@ -98,9 +98,9 @@ extern int var, arr[2][2];
struct Pair { int a, b; } pair;
// CHECK-LABEL: test_s(
-// CHECK: call void asm sideeffect "// $0 $1 $2", "s,s,s"(ptr nonnull @var, ptr nonnull getelementptr inbounds nuw (i8, ptr @arr, {{.*}}), ptr nonnull @test_s)
-// CHECK: call void asm sideeffect "// $0", "s"(ptr nonnull getelementptr inbounds nuw (i8, ptr @pair, {{.*}}))
-// CHECK: call void asm sideeffect "// $0 $1 $2", "S,S,S"(ptr nonnull @var, ptr nonnull getelementptr inbounds nuw (i8, ptr @arr, {{.*}}), ptr nonnull @test_s)
+// CHECK: call void asm sideeffect "// $0 $1 $2", "s,s,s,~{vl},~{vtype}"(ptr nonnull @var, ptr nonnull getelementptr inbounds nuw (i8, ptr @arr, {{.*}}), ptr nonnull @test_s)
+// CHECK: call void asm sideeffect "// $0", "s,~{vl},~{vtype}"(ptr nonnull getelementptr inbounds nuw (i8, ptr @pair, {{.*}}))
+// CHECK: call void asm sideeffect "// $0 $1 $2", "S,S,S,~{vl},~{vtype}"(ptr nonnull @var, ptr nonnull getelementptr inbounds nuw (i8, ptr @arr, {{.*}}), ptr nonnull @test_s)
void test_s(void) {
asm("// %0 %1 %2" :: "s"(&var), "s"(&arr[1][1]), "s"(test_s));
asm("// %0" :: "s"(&pair.b));
@@ -109,9 +109,9 @@ void test_s(void) {
}
// CHECK-LABEL: test_modifiers(
-// CHECK: call void asm sideeffect "// ${0:i} ${1:i}", "r,r"({{i32|i64}} %val, i32 37)
-// CHECK: call void asm sideeffect "// ${0:z} ${1:z}", "i,i"(i32 0, i32 1)
-// CHECK: call void asm sideeffect "// ${0:N}", "r"({{i32|i64}} %val)
+// CHECK: call void asm sideeffect "// ${0:i} ${1:i}", "r,r,~{vl},~{vtype}"({{i32|i64}} %val, i32 37)
+// CHECK: call void asm sideeffect "// ${0:z} ${1:z}", "i,i,~{vl},~{vtype}"(i32 0, i32 1)
+// CHECK: call void asm sideeffect "// ${0:N}", "r,~{vl},~{vtype}"({{i32|i64}} %val)
void test_modifiers(long val) {
asm volatile("// %i0 %i1" :: "r"(val), "r"(37));
asm volatile("// %z0 %z1" :: "i"(0), "i"(1));
diff --git a/llvm/test/CodeGen/RISCV/rvv/vsetvl-cross-inline-asm-clobber.ll b/llvm/test/CodeGen/RISCV/rvv/vsetvl-cross-inline-asm-clobber.ll
new file mode 100644
index 0000000000000..75d8b4c5437b1
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/vsetvl-cross-inline-asm-clobber.ll
@@ -0,0 +1,37 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=riscv64 -mcpu=sifive-x280 -verify-machineinstrs < %s | FileCheck %s
+
+define void @foo(<vscale x 8 x half> %0, <vscale x 8 x half> %1) {
+; CHECK-LABEL: foo:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma
+; CHECK-NEXT: vmv.v.i v12, 0
+; CHECK-NEXT: lui a0, 1
+; CHECK-NEXT: addiw a0, a0, -1096
+; CHECK-NEXT: vmv.v.i v16, 0
+; CHECK-NEXT: vsetvli zero, a0, e8, m1, ta, ma
+; CHECK-NEXT: #APP
+; CHECK-NEXT: vfmadd.vv v16, v12, v12
+; CHECK-NEXT: #NO_APP
+; CHECK-NEXT: #APP
+; CHECK-NEXT: vfmadd.vv v16, v12, v12
+; CHECK-NEXT: #NO_APP
+; CHECK-NEXT: vsetvli zero, a0, e16, m2, ta, ma
+; CHECK-NEXT: vse16.v v8, (zero)
+; CHECK-NEXT: ret
+entry:
+ %2 = tail call i64 @llvm.riscv.vsetvli.i64(i64 3000, i64 0, i64 0)
+ %3 = tail call <vscale x 8 x float> asm sideeffect "vfmadd.vv $0, $1, $2", "=^vr,^vr,^vr,0,~{vl},~{vtype}"(<vscale x 8 x float> zeroinitializer, <vscale x 8 x float> zeroinitializer, <vscale x 8 x float> zeroinitializer)
+ %4 = tail call <vscale x 8 x float> asm sideeffect "vfmadd.vv $0, $1, $2", "=^vr,^vr,^vr,0,~{vl},~{vtype}"(<vscale x 8 x float> zeroinitializer, <vscale x 8 x float> zeroinitializer, <vscale x 8 x float> %3)
+ tail call void @llvm.riscv.vse.nxv8f16.i64(<vscale x 8 x half> %0, ptr null, i64 %2)
+ ret void
+}
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
+declare i64 @llvm.riscv.vsetvli.i64(i64, i64 immarg, i64 immarg) #0
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: write)
+declare void @llvm.riscv.vse.nxv8f16.i64(<vscale x 8 x half>, ptr nocapture, i64) #1
+
+attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: write) }
diff --git a/llvm/test/CodeGen/RISCV/rvv/vsetvl-cross-inline-asm.ll b/llvm/test/CodeGen/RISCV/rvv/vsetvl-cross-inline-asm.ll
new file mode 100644
index 0000000000000..e60ce90d5ed8b
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/vsetvl-cross-inline-asm.ll
@@ -0,0 +1,37 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=riscv64 -mcpu=sifive-x280 -verify-machineinstrs < %s | FileCheck %s
+
+define void @foo(<vscale x 8 x half> %0, <vscale x 8 x half> %1) {
+; CHECK-LABEL: foo:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, ma
+; CHECK-NEXT: vmv.v.i v12, 0
+; CHECK-NEXT: lui a0, 1
+; CHECK-NEXT: addiw a0, a0, -1096
+; CHECK-NEXT: vmv.v.i v16, 0
+; CHECK-NEXT: vsetvli zero, a0, e8, m1, ta, ma
+; CHECK-NEXT: #APP
+; CHECK-NEXT: vfmadd.vv v16, v12, v12
+; CHECK-NEXT: #NO_APP
+; CHECK-NEXT: vsetvli zero, a0, e16, m2, ta, ma
+; CHECK-NEXT: #APP
+; CHECK-NEXT: vfmadd.vv v16, v12, v12
+; CHECK-NEXT: #NO_APP
+; CHECK-NEXT: vse16.v v8, (zero)
+; CHECK-NEXT: ret
+entry:
+ %2 = tail call i64 @llvm.riscv.vsetvli.i64(i64 3000, i64 0, i64 0)
+ %3 = tail call <vscale x 8 x float> asm sideeffect "vfmadd.vv $0, $1, $2", "=^vr,^vr,^vr,0"(<vscale x 8 x float> zeroinitializer, <vscale x 8 x float> zeroinitializer, <vscale x 8 x float> zeroinitializer)
+ %4 = tail call <vscale x 8 x float> asm sideeffect "vfmadd.vv $0, $1, $2", "=^vr,^vr,^vr,0"(<vscale x 8 x float> zeroinitializer, <vscale x 8 x float> zeroinitializer, <vscale x 8 x float> %3)
+ tail call void @llvm.riscv.vse.nxv8f16.i64(<vscale x 8 x half> %0, ptr null, i64 %2)
+ ret void
+}
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(none)
+declare i64 @llvm.riscv.vsetvli.i64(i64, i64 immarg, i64 immarg) #0
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: write)
+declare void @llvm.riscv.vse.nxv8f16.i64(<vscale x 8 x half>, ptr nocapture, i64) #1
+
+attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }
+attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: write) }
>From 4258fae851fe5edf67c7d6848efaa0d03337c7ea Mon Sep 17 00:00:00 2001
From: Hank Chang <hank.chang at sifive.com>
Date: Wed, 26 Feb 2025 11:53:13 +0800
Subject: [PATCH 2/2] Update with suggestion from Pengcheng Wang
---
clang/lib/Basic/Targets/RISCV.h | 6 ++-
.../CodeGen/RISCV/riscv-inline-asm-clobber.c | 12 +++---
clang/test/CodeGen/RISCV/riscv-inline-asm.c | 42 +++++++++----------
3 files changed, 32 insertions(+), 28 deletions(-)
diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index 5590aa9d03c75..8b99a5f2bc42d 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -68,7 +68,11 @@ class RISCVTargetInfo : public TargetInfo {
return TargetInfo::VoidPtrBuiltinVaList;
}
- std::string_view getClobbers() const override { return "~{vl},~{vtype}"; }
+ std::string_view getClobbers() const override {
+ if (ISAInfo->hasExtension("zve32x"))
+ return "~{vl},~{vtype}";
+ return "";
+ }
StringRef getConstraintRegister(StringRef Constraint,
StringRef Expression) const override {
diff --git a/clang/test/CodeGen/RISCV/riscv-inline-asm-clobber.c b/clang/test/CodeGen/RISCV/riscv-inline-asm-clobber.c
index 65cfc081fe26d..dd0902750f89d 100644
--- a/clang/test/CodeGen/RISCV/riscv-inline-asm-clobber.c
+++ b/clang/test/CodeGen/RISCV/riscv-inline-asm-clobber.c
@@ -10,7 +10,7 @@
// CHECK-LABEL: define dso_local void @test_fflags(
// CHECK-SAME: ) local_unnamed_addr #[[ATTR0:[0-9]+]] {
// CHECK-NEXT: entry:
-// CHECK-NEXT: tail call void asm sideeffect "", "~{fflags},~{vl},~{vtype}"() #[[ATTR1:[0-9]+]], !srcloc [[META6:![0-9]+]]
+// CHECK-NEXT: tail call void asm sideeffect "", "~{fflags}"() #[[ATTR1:[0-9]+]], !srcloc [[META6:![0-9]+]]
// CHECK-NEXT: ret void
//
void test_fflags(void) {
@@ -20,7 +20,7 @@ void test_fflags(void) {
// CHECK-LABEL: define dso_local void @test_frm(
// CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: entry:
-// CHECK-NEXT: tail call void asm sideeffect "", "~{frm},~{vl},~{vtype}"() #[[ATTR1]], !srcloc [[META7:![0-9]+]]
+// CHECK-NEXT: tail call void asm sideeffect "", "~{frm}"() #[[ATTR1]], !srcloc [[META7:![0-9]+]]
// CHECK-NEXT: ret void
//
void test_frm(void) {
@@ -30,7 +30,7 @@ void test_frm(void) {
// CHECK-LABEL: define dso_local void @test_vtype(
// CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: entry:
-// CHECK-NEXT: tail call void asm sideeffect "", "~{vtype},~{vl},~{vtype}"() #[[ATTR1]], !srcloc [[META8:![0-9]+]]
+// CHECK-NEXT: tail call void asm sideeffect "", "~{vtype}"() #[[ATTR1]], !srcloc [[META8:![0-9]+]]
// CHECK-NEXT: ret void
//
void test_vtype(void) {
@@ -40,7 +40,7 @@ void test_vtype(void) {
// CHECK-LABEL: define dso_local void @test_vl(
// CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: entry:
-// CHECK-NEXT: tail call void asm sideeffect "", "~{vl},~{vl},~{vtype}"() #[[ATTR1]], !srcloc [[META9:![0-9]+]]
+// CHECK-NEXT: tail call void asm sideeffect "", "~{vl}"() #[[ATTR1]], !srcloc [[META9:![0-9]+]]
// CHECK-NEXT: ret void
//
void test_vl(void) {
@@ -50,7 +50,7 @@ void test_vl(void) {
// CHECK-LABEL: define dso_local void @test_vxsat(
// CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: entry:
-// CHECK-NEXT: tail call void asm sideeffect "", "~{vxsat},~{vl},~{vtype}"() #[[ATTR1]], !srcloc [[META10:![0-9]+]]
+// CHECK-NEXT: tail call void asm sideeffect "", "~{vxsat}"() #[[ATTR1]], !srcloc [[META10:![0-9]+]]
// CHECK-NEXT: ret void
//
void test_vxsat(void) {
@@ -60,7 +60,7 @@ void test_vxsat(void) {
// CHECK-LABEL: define dso_local void @test_vxrm(
// CHECK-SAME: ) local_unnamed_addr #[[ATTR0]] {
// CHECK-NEXT: entry:
-// CHECK-NEXT: tail call void asm sideeffect "", "~{vxrm},~{vl},~{vtype}"() #[[ATTR1]], !srcloc [[META11:![0-9]+]]
+// CHECK-NEXT: tail call void asm sideeffect "", "~{vxrm}"() #[[ATTR1]], !srcloc [[META11:![0-9]+]]
// CHECK-NEXT: ret void
//
void test_vxrm(void) {
diff --git a/clang/test/CodeGen/RISCV/riscv-inline-asm.c b/clang/test/CodeGen/RISCV/riscv-inline-asm.c
index 1a8ccb7ea5a68..f2031e0adcbcb 100644
--- a/clang/test/CodeGen/RISCV/riscv-inline-asm.c
+++ b/clang/test/CodeGen/RISCV/riscv-inline-asm.c
@@ -7,17 +7,17 @@
long test_r(long x) {
// CHECK-LABEL: define{{.*}} {{i64|i32}} @test_r(
-// CHECK: call {{i64|i32}} asm sideeffect "", "=r,r,~{vl},~{vtype}"({{i64|i32}} %{{.*}})
+// CHECK: call {{i64|i32}} asm sideeffect "", "=r,r"({{i64|i32}} %{{.*}})
long ret;
asm volatile ("" : "=r"(ret) : "r"(x));
-// CHECK: call {{i64|i32}} asm sideeffect "", "=r,r,~{vl},~{vtype}"({{i64|i32}} %{{.*}})
+// CHECK: call {{i64|i32}} asm sideeffect "", "=r,r"({{i64|i32}} %{{.*}})
asm volatile ("" : "=r"(ret) : "r"(x));
return ret;
}
long test_cr(long x) {
// CHECK-LABEL: define{{.*}} {{i64|i32}} @test_cr(
-// CHECK: call {{i64|i32}} asm sideeffect "", "=^cr,^cr,~{vl},~{vtype}"({{i64|i32}} %{{.*}})
+// CHECK: call {{i64|i32}} asm sideeffect "", "=^cr,^cr"({{i64|i32}} %{{.*}})
long ret;
asm volatile ("" : "=cr"(ret) : "cr"(x));
return ret;
@@ -27,9 +27,9 @@ float cf;
double cd;
void test_cf(float f, double d) {
// CHECK-LABEL: define{{.*}} void @test_cf(
-// CHECK: call float asm sideeffect "", "=^cf,^cf,~{vl},~{vtype}"(float %{{.*}})
+// CHECK: call float asm sideeffect "", "=^cf,^cf"(float %{{.*}})
asm volatile("" : "=cf"(cf) : "cf"(f));
-// CHECK: call double asm sideeffect "", "=^cf,^cf,~{vl},~{vtype}"(double %{{.*}})
+// CHECK: call double asm sideeffect "", "=^cf,^cf"(double %{{.*}})
asm volatile("" : "=cf"(cd) : "cf"(d));
}
@@ -40,7 +40,7 @@ typedef __int128_t double_xlen_t;
#endif
double_xlen_t test_R_wide_scalar(double_xlen_t p) {
// CHECK-LABEL: define{{.*}} {{i128|i64}} @test_R_wide_scalar(
-// CHECK: call {{i128|i64}} asm sideeffect "", "=R,R,~{vl},~{vtype}"({{i128|i64}} %{{.*}})
+// CHECK: call {{i128|i64}} asm sideeffect "", "=R,R"({{i128|i64}} %{{.*}})
double_xlen_t ret;
asm volatile("" : "=R"(ret) : "R"(p));
return ret;
@@ -48,7 +48,7 @@ double_xlen_t test_R_wide_scalar(double_xlen_t p) {
double_xlen_t test_cR_wide_scalar(double_xlen_t p) {
// CHECK-LABEL: define{{.*}} {{i128|i64}} @test_cR_wide_scalar(
-// CHECK: call {{i128|i64}} asm sideeffect "", "=^cR,^cR,~{vl},~{vtype}"({{i128|i64}} %{{.*}})
+// CHECK: call {{i128|i64}} asm sideeffect "", "=^cR,^cR"({{i128|i64}} %{{.*}})
double_xlen_t ret;
asm volatile("" : "=cR"(ret) : "cR"(p));
return ret;
@@ -56,23 +56,23 @@ double_xlen_t test_cR_wide_scalar(double_xlen_t p) {
void test_I(void) {
// CHECK-LABEL: define{{.*}} void @test_I()
-// CHECK: call void asm sideeffect "", "I,~{vl},~{vtype}"(i32 2047)
+// CHECK: call void asm sideeffect "", "I"(i32 2047)
asm volatile ("" :: "I"(2047));
-// CHECK: call void asm sideeffect "", "I,~{vl},~{vtype}"(i32 -2048)
+// CHECK: call void asm sideeffect "", "I"(i32 -2048)
asm volatile ("" :: "I"(-2048));
}
void test_J(void) {
// CHECK-LABEL: define{{.*}} void @test_J()
-// CHECK: call void asm sideeffect "", "J,~{vl},~{vtype}"(i32 0)
+// CHECK: call void asm sideeffect "", "J"(i32 0)
asm volatile ("" :: "J"(0));
}
void test_K(void) {
// CHECK-LABEL: define{{.*}} void @test_K()
-// CHECK: call void asm sideeffect "", "K,~{vl},~{vtype}"(i32 31)
+// CHECK: call void asm sideeffect "", "K"(i32 31)
asm volatile ("" :: "K"(31));
-// CHECK: call void asm sideeffect "", "K,~{vl},~{vtype}"(i32 0)
+// CHECK: call void asm sideeffect "", "K"(i32 0)
asm volatile ("" :: "K"(0));
}
@@ -81,16 +81,16 @@ double d;
void test_f(void) {
// CHECK-LABEL: define{{.*}} void @test_f()
// CHECK: [[FLT_ARG:%[a-zA-Z_0-9]+]] = load float, ptr @f
-// CHECK: call void asm sideeffect "", "f,~{vl},~{vtype}"(float [[FLT_ARG]])
+// CHECK: call void asm sideeffect "", "f"(float [[FLT_ARG]])
asm volatile ("" :: "f"(f));
// CHECK: [[FLT_ARG:%[a-zA-Z_0-9]+]] = load double, ptr @d
-// CHECK: call void asm sideeffect "", "f,~{vl},~{vtype}"(double [[FLT_ARG]])
+// CHECK: call void asm sideeffect "", "f"(double [[FLT_ARG]])
asm volatile ("" :: "f"(d));
}
void test_A(int *p) {
// CHECK-LABEL: define{{.*}} void @test_A(ptr noundef %p)
-// CHECK: call void asm sideeffect "", "*A,~{vl},~{vtype}"(ptr elementtype(i32) %p)
+// CHECK: call void asm sideeffect "", "*A"(ptr elementtype(i32) %p)
asm volatile("" :: "A"(*p));
}
@@ -98,9 +98,9 @@ extern int var, arr[2][2];
struct Pair { int a, b; } pair;
// CHECK-LABEL: test_s(
-// CHECK: call void asm sideeffect "// $0 $1 $2", "s,s,s,~{vl},~{vtype}"(ptr nonnull @var, ptr nonnull getelementptr inbounds nuw (i8, ptr @arr, {{.*}}), ptr nonnull @test_s)
-// CHECK: call void asm sideeffect "// $0", "s,~{vl},~{vtype}"(ptr nonnull getelementptr inbounds nuw (i8, ptr @pair, {{.*}}))
-// CHECK: call void asm sideeffect "// $0 $1 $2", "S,S,S,~{vl},~{vtype}"(ptr nonnull @var, ptr nonnull getelementptr inbounds nuw (i8, ptr @arr, {{.*}}), ptr nonnull @test_s)
+// CHECK: call void asm sideeffect "// $0 $1 $2", "s,s,s"(ptr nonnull @var, ptr nonnull getelementptr inbounds nuw (i8, ptr @arr, {{.*}}), ptr nonnull @test_s)
+// CHECK: call void asm sideeffect "// $0", "s"(ptr nonnull getelementptr inbounds nuw (i8, ptr @pair, {{.*}}))
+// CHECK: call void asm sideeffect "// $0 $1 $2", "S,S,S"(ptr nonnull @var, ptr nonnull getelementptr inbounds nuw (i8, ptr @arr, {{.*}}), ptr nonnull @test_s)
void test_s(void) {
asm("// %0 %1 %2" :: "s"(&var), "s"(&arr[1][1]), "s"(test_s));
asm("// %0" :: "s"(&pair.b));
@@ -109,9 +109,9 @@ void test_s(void) {
}
// CHECK-LABEL: test_modifiers(
-// CHECK: call void asm sideeffect "// ${0:i} ${1:i}", "r,r,~{vl},~{vtype}"({{i32|i64}} %val, i32 37)
-// CHECK: call void asm sideeffect "// ${0:z} ${1:z}", "i,i,~{vl},~{vtype}"(i32 0, i32 1)
-// CHECK: call void asm sideeffect "// ${0:N}", "r,~{vl},~{vtype}"({{i32|i64}} %val)
+// CHECK: call void asm sideeffect "// ${0:i} ${1:i}", "r,r"({{i32|i64}} %val, i32 37)
+// CHECK: call void asm sideeffect "// ${0:z} ${1:z}", "i,i"(i32 0, i32 1)
+// CHECK: call void asm sideeffect "// ${0:N}", "r"({{i32|i64}} %val)
void test_modifiers(long val) {
asm volatile("// %i0 %i1" :: "r"(val), "r"(37));
asm volatile("// %z0 %z1" :: "i"(0), "i"(1));
More information about the cfe-commits
mailing list