-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[RISCV][VCIX] Add vcix_state to GNU inline assembly register set #106914
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang Author: Brandon Wu (4vtomat) Changes[RISCV][VCIX] Add vcix_state to GNU inline assembly register set Resolved #106700. Full diff: https://github.com/llvm/llvm-project/pull/106914.diff 3 Files Affected:
diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp
index b89109e7725d44..da6ecfb4e4022b 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -44,7 +44,7 @@ ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const {
"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
// CSRs
- "fflags", "frm", "vtype", "vl", "vxsat", "vxrm"
+ "fflags", "frm", "vtype", "vl", "vxsat", "vxrm", "vcix_state"
};
// clang-format on
return llvm::ArrayRef(GCCRegNames);
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
index 4d5c0a7bef9416..03f05c0baea3b0 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
@@ -664,5 +664,9 @@ def FRM : RISCVReg<0, "frm">;
// Shadow Stack register
def SSP : RISCVReg<0, "ssp">;
-// Dummy VCIX state register
+// Dummy VCIX state register and its register class
def VCIX_STATE : RISCVReg<0, "vcix_state">;
+def : RISCVRegisterClass<[XLenVT], 32, (add VCIX_STATE)> {
+ let RegInfos = XLenRI;
+ let isAllocatable = 0;
+}
diff --git a/llvm/test/CodeGen/RISCV/inline-asm-xsfvcp.ll b/llvm/test/CodeGen/RISCV/inline-asm-xsfvcp.ll
new file mode 100644
index 00000000000000..0013461d873281
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/inline-asm-xsfvcp.ll
@@ -0,0 +1,22 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+v,+xsfvcp \
+; RUN: -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK
+; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+v,+xsfvcp \
+; RUN: -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK
+
+; VCIX instructions can not reorder between each other.
+define void @test_reorder(<vscale x 1 x i64> %vreg) {
+; CHECK-LABEL: test_reorder:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vsetivli zero, 0, e64, m1, ta, ma
+; CHECK-NEXT: sf.vc.iv 0, 0, v8, 0
+; CHECK-NEXT: #APP
+; CHECK-NEXT: sf.vc.vv 3, 0, v8, v8
+; CHECK-EMPTY:
+; CHECK-NEXT: #NO_APP
+; CHECK-NEXT: ret
+entry:
+ call void @llvm.riscv.sf.vc.iv.se.iXLen.nxv1i64.iXLen.iXLen(iXLen 0, iXLen 0, <vscale x 1 x i64> %vreg, iXLen 0, iXLen 0)
+ call iXLen asm sideeffect "sf.vc.vv 0x3, 0x0, $1, $1;", "=r,^vr,~{memory},~{vl},~{vcix_state}"(<vscale x 1 x i64> %vreg)
+ ret void
+}
|
@llvm/pr-subscribers-backend-risc-v Author: Brandon Wu (4vtomat) Changes[RISCV][VCIX] Add vcix_state to GNU inline assembly register set Resolved #106700. Full diff: https://github.com/llvm/llvm-project/pull/106914.diff 3 Files Affected:
diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp
index b89109e7725d44..da6ecfb4e4022b 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -44,7 +44,7 @@ ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const {
"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
// CSRs
- "fflags", "frm", "vtype", "vl", "vxsat", "vxrm"
+ "fflags", "frm", "vtype", "vl", "vxsat", "vxrm", "vcix_state"
};
// clang-format on
return llvm::ArrayRef(GCCRegNames);
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
index 4d5c0a7bef9416..03f05c0baea3b0 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
@@ -664,5 +664,9 @@ def FRM : RISCVReg<0, "frm">;
// Shadow Stack register
def SSP : RISCVReg<0, "ssp">;
-// Dummy VCIX state register
+// Dummy VCIX state register and its register class
def VCIX_STATE : RISCVReg<0, "vcix_state">;
+def : RISCVRegisterClass<[XLenVT], 32, (add VCIX_STATE)> {
+ let RegInfos = XLenRI;
+ let isAllocatable = 0;
+}
diff --git a/llvm/test/CodeGen/RISCV/inline-asm-xsfvcp.ll b/llvm/test/CodeGen/RISCV/inline-asm-xsfvcp.ll
new file mode 100644
index 00000000000000..0013461d873281
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/inline-asm-xsfvcp.ll
@@ -0,0 +1,22 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+v,+xsfvcp \
+; RUN: -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK
+; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+v,+xsfvcp \
+; RUN: -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK
+
+; VCIX instructions can not reorder between each other.
+define void @test_reorder(<vscale x 1 x i64> %vreg) {
+; CHECK-LABEL: test_reorder:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vsetivli zero, 0, e64, m1, ta, ma
+; CHECK-NEXT: sf.vc.iv 0, 0, v8, 0
+; CHECK-NEXT: #APP
+; CHECK-NEXT: sf.vc.vv 3, 0, v8, v8
+; CHECK-EMPTY:
+; CHECK-NEXT: #NO_APP
+; CHECK-NEXT: ret
+entry:
+ call void @llvm.riscv.sf.vc.iv.se.iXLen.nxv1i64.iXLen.iXLen(iXLen 0, iXLen 0, <vscale x 1 x i64> %vreg, iXLen 0, iXLen 0)
+ call iXLen asm sideeffect "sf.vc.vv 0x3, 0x0, $1, $1;", "=r,^vr,~{memory},~{vl},~{vcix_state}"(<vscale x 1 x i64> %vreg)
+ ret void
+}
|
def VCIX_STATE : RISCVReg<0, "vcix_state">; | ||
def : RISCVRegisterClass<[XLenVT], 32, (add VCIX_STATE)> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need a RegisterClass for it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In getRegForInlineAsmConstraint
if there would be no value in AssignedRegs
when calling getRegistersForValue
for the vcix_state
constraint, thus it would be deprecated when constructing selectionDAG.
I would suggest it should prefix with a vendor prefix, either |
Do you mean change the current |
Yes, because it's SiFive specific register, other vendor may add other status register like VCIX in future, so I would like to add prefix to make sure all further similar stuff will follow same rule if possible |
Sure! I will do it in another patch since it's separate thing than this patch. |
5f821a2
to
c8ae503
Compare
clang/lib/Basic/Targets/RISCV.cpp
Outdated
@@ -44,7 +44,7 @@ ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const { | |||
"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", | |||
|
|||
// CSRs | |||
"fflags", "frm", "vtype", "vl", "vxsat", "vxrm" | |||
"fflags", "frm", "vtype", "vl", "vxsat", "vxrm", "sf_vcix_state" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sf.vcix_state
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is machine register name lol, if we use sf.vcix_state
, it can't recognize.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we stay with the sf_
prefix then? Or is there some simple workaround?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean by "This is a machine instruction name [...] it can't recognize"? That's the name it's given in TableGen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#include <riscv_vector.h>
#include <sifive_vector.h>
int foo(__rvv_uint64m1_t vreg) {
auto vl = __riscv_vsetvl_e64m1(1);
// This VCIX instruction gets scheduled after the asm block below.
__riscv_sf_vc_iv_se_u64m1(0, 0, vreg, 0, vl);
asm volatile(
R"(
vsetivli zero, 2, e64, m1, ta, ma
sf.vc.vv 0x3, 0x0, %[vreg], %[vreg];
)"
: "=r"(vl)
: [vreg]"vr"(vreg)
: "memory", "vl", "sf_vcix_state");
return 0;
}
Use the code above as an example, it compiles to the llvm:
define dso_local noundef signext i32 @_Z3foou16__rvv_uint64m1_t(<vscale x 1 x i64> %vreg) local_unnamed_addr #0 {
entry:
%0 = tail call i64 @llvm.riscv.vsetvli.i64(i64 1, i64 3, i64 0)
tail call void @llvm.riscv.sf.vc.iv.se.i64.nxv1i64.i64.i64(i64 0, i64 0, <vscale x 1 x i64> %vreg, i64 0, i64 %0)
%1 = tail call i64 asm sideeffect "\0A vsetivli zero, 2, e64, m1, ta, ma\0A sf.vc.vv 0x3, 0x0, $1, $1;\0A ", "=r,^vr,~{memory},~{vl},~{sf_vcix_state}"(<vscale x 1 x i64> %vreg)
ret i32 0
}
if we change sf_vcix_state
to sf.vcix_state
, the code doesn't work as expected, the instruction is still reordered, so I doubt that the name here is the defining name of the register in RISCVRegisterInfo.td
rather than the actually name of the register.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think here is the root cause:
llvm-project/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
Lines 1106 to 1111 in 1e3a24d
// FIXME: We are assuming that the assembly name is equal to the TableGen | |
// name converted to lower case | |
// | |
// The TableGen name is the name of the definition for this register in the | |
// target's tablegen files. For example, the TableGen name of | |
// def EAX : Register <...>; is "EAX" |
Maybe we should overwrite this function for RISCV?
What do you think @jrtc27 @kito-cheng ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jrtc27 @kito-cheng Friendly ping 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@4vtomat we should override that function for this register.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, let me add it!
c8ae503
to
5370538
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Thanks everyone! 😄 Is there anything still blocking us from merging this? |
Actually no, let me merge it later today, thanks! |
5370538
to
87bbba7
Compare
Resolved llvm#106700. This enables inline asm to have vcix_state to be a clobbered register thus disable reordering between VCIX intrinsics and inline asm.
87bbba7
to
aff3876
Compare
Awesome, thank you! 😄 |
…m#106914) riscv-non-isa/riscv-toolchain-conventions#56 Resolved llvm#106700. This enables inline asm to have vcix_state to be a clobbered register thus disable reordering between VCIX intrinsics and inline asm.
riscv-non-isa/riscv-toolchain-conventions#56
Resolved #106700.
This enables inline asm to have vcix_state to be a clobbered register
thus disable reordering between VCIX intrinsics and inline asm.