Skip to content

Commit dba54fb

Browse files
authored
[RISCV] Add support for inline asm constraint vd (#111653)
It constrains vector registers excluding v0. Refer to https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html RISC-V part. This patch also adds a testcase for constraints vr, vd and vm.
1 parent cd12ffb commit dba54fb

File tree

4 files changed

+89
-2
lines changed

4 files changed

+89
-2
lines changed

clang/lib/Basic/Targets/RISCV.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ bool RISCVTargetInfo::validateAsmConstraint(
102102
return true;
103103
case 'v':
104104
// A vector register.
105-
if (Name[1] == 'r' || Name[1] == 'm') {
105+
if (Name[1] == 'r' || Name[1] == 'd' || Name[1] == 'm') {
106106
Info.setAllowsRegister();
107107
Name += 1;
108108
return true;

clang/test/CodeGen/RISCV/riscv-inline-asm-rvv.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ vint32m1_t test_vr(vint32m1_t a, vint32m1_t b) {
2929
return ret;
3030
}
3131

32+
vint32m1_t test_vd(vint32m1_t a, vint32m1_t b) {
33+
// CHECK-LABEL: define{{.*}} @test_vd
34+
// 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)
35+
vint32m1_t ret;
36+
asm volatile ("vadd.vv %0, %1, %2" : "=vd"(ret) : "vd"(a), "vd"(b));
37+
return ret;
38+
}
39+
3240
vbool1_t test_vm(vbool1_t a, vbool1_t b) {
3341
// CHECK-LABEL: define{{.*}} @test_vm
3442
// 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)

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20227,7 +20227,7 @@ RISCVTargetLowering::getConstraintType(StringRef Constraint) const {
2022720227
return C_Other;
2022820228
}
2022920229
} else {
20230-
if (Constraint == "vr" || Constraint == "vm")
20230+
if (Constraint == "vr" || Constraint == "vd" || Constraint == "vm")
2023120231
return C_RegisterClass;
2023220232
}
2023320233
return TargetLowering::getConstraintType(Constraint);
@@ -20275,6 +20275,19 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2027520275
if (TRI->isTypeLegalForClass(*RC, VT.SimpleTy))
2027620276
return std::make_pair(0U, RC);
2027720277
}
20278+
} else if (Constraint == "vd") {
20279+
for (const auto *RC :
20280+
{&RISCV::VRNoV0RegClass, &RISCV::VRM2NoV0RegClass,
20281+
&RISCV::VRM4NoV0RegClass, &RISCV::VRM8NoV0RegClass,
20282+
&RISCV::VRN2M1NoV0RegClass, &RISCV::VRN3M1NoV0RegClass,
20283+
&RISCV::VRN4M1NoV0RegClass, &RISCV::VRN5M1NoV0RegClass,
20284+
&RISCV::VRN6M1NoV0RegClass, &RISCV::VRN7M1NoV0RegClass,
20285+
&RISCV::VRN8M1NoV0RegClass, &RISCV::VRN2M2NoV0RegClass,
20286+
&RISCV::VRN3M2NoV0RegClass, &RISCV::VRN4M2NoV0RegClass,
20287+
&RISCV::VRN2M4NoV0RegClass}) {
20288+
if (TRI->isTypeLegalForClass(*RC, VT.SimpleTy))
20289+
return std::make_pair(0U, RC);
20290+
}
2027820291
} else if (Constraint == "vm") {
2027920292
if (TRI->isTypeLegalForClass(RISCV::VMV0RegClass, VT.SimpleTy))
2028020293
return std::make_pair(0U, &RISCV::VMV0RegClass);
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=riscv32 -mattr=+v -verify-machineinstrs < %s \
3+
; RUN: | FileCheck -check-prefix=RV32I %s
4+
; RUN: llc -mtriple=riscv64 -mattr=+v -verify-machineinstrs < %s \
5+
; RUN: | FileCheck -check-prefix=RV64I %s
6+
7+
define <vscale x 1 x i8> @constraint_vr(<vscale x 1 x i8> %0, <vscale x 1 x i8> %1) nounwind {
8+
; RV32I-LABEL: constraint_vr:
9+
; RV32I: # %bb.0:
10+
; RV32I-NEXT: #APP
11+
; RV32I-NEXT: vadd.vv v8, v8, v9
12+
; RV32I-NEXT: #NO_APP
13+
; RV32I-NEXT: ret
14+
;
15+
; RV64I-LABEL: constraint_vr:
16+
; RV64I: # %bb.0:
17+
; RV64I-NEXT: #APP
18+
; RV64I-NEXT: vadd.vv v8, v8, v9
19+
; RV64I-NEXT: #NO_APP
20+
; RV64I-NEXT: ret
21+
%a = tail call <vscale x 1 x i8> asm "vadd.vv $0, $1, $2", "=^vr,^vr,^vr"(
22+
<vscale x 1 x i8> %0, <vscale x 1 x i8> %1)
23+
ret <vscale x 1 x i8> %a
24+
}
25+
26+
define <vscale x 1 x i8> @constraint_vd(<vscale x 1 x i8> %0, <vscale x 1 x i8> %1) nounwind {
27+
; RV32I-LABEL: constraint_vd:
28+
; RV32I: # %bb.0:
29+
; RV32I-NEXT: #APP
30+
; RV32I-NEXT: vadd.vv v8, v8, v9
31+
; RV32I-NEXT: #NO_APP
32+
; RV32I-NEXT: ret
33+
;
34+
; RV64I-LABEL: constraint_vd:
35+
; RV64I: # %bb.0:
36+
; RV64I-NEXT: #APP
37+
; RV64I-NEXT: vadd.vv v8, v8, v9
38+
; RV64I-NEXT: #NO_APP
39+
; RV64I-NEXT: ret
40+
%a = tail call <vscale x 1 x i8> asm "vadd.vv $0, $1, $2", "=^vd,^vr,^vr"(
41+
<vscale x 1 x i8> %0, <vscale x 1 x i8> %1)
42+
ret <vscale x 1 x i8> %a
43+
}
44+
45+
define <vscale x 1 x i1> @constraint_vm(<vscale x 1 x i1> %0, <vscale x 1 x i1> %1) nounwind {
46+
; RV32I-LABEL: constraint_vm:
47+
; RV32I: # %bb.0:
48+
; RV32I-NEXT: vmv1r.v v9, v0
49+
; RV32I-NEXT: vmv1r.v v0, v8
50+
; RV32I-NEXT: #APP
51+
; RV32I-NEXT: vadd.vv v0, v9, v0
52+
; RV32I-NEXT: #NO_APP
53+
; RV32I-NEXT: ret
54+
;
55+
; RV64I-LABEL: constraint_vm:
56+
; RV64I: # %bb.0:
57+
; RV64I-NEXT: vmv1r.v v9, v0
58+
; RV64I-NEXT: vmv1r.v v0, v8
59+
; RV64I-NEXT: #APP
60+
; RV64I-NEXT: vadd.vv v0, v9, v0
61+
; RV64I-NEXT: #NO_APP
62+
; RV64I-NEXT: ret
63+
%a = tail call <vscale x 1 x i1> asm "vadd.vv $0, $1, $2", "=^vr,^vr,^vm"(
64+
<vscale x 1 x i1> %0, <vscale x 1 x i1> %1)
65+
ret <vscale x 1 x i1> %a
66+
}

0 commit comments

Comments
 (0)