Skip to content

Commit b0e11dc

Browse files
lenarygithub-actions[bot]
authored andcommitted
Automerge: [RISCV] Support cR Inline Asm Constraint (#124174)
This denotes RVC-compatible GPR Pairs, which are used by the Zclsd extension. C API PR: riscv-non-isa/riscv-c-api-doc#102
2 parents 23bfeb5 + 33c4407 commit b0e11dc

File tree

6 files changed

+196
-2
lines changed

6 files changed

+196
-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 'c':
104104
// A RVC register - GPR or FPR
105-
if (Name[1] == 'r' || Name[1] == 'f') {
105+
if (Name[1] == 'r' || Name[1] == 'R' || Name[1] == 'f') {
106106
Info.setAllowsRegister();
107107
Name += 1;
108108
return true;

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ double_xlen_t test_R_wide_scalar(double_xlen_t p) {
4646
return ret;
4747
}
4848

49+
double_xlen_t test_cR_wide_scalar(double_xlen_t p) {
50+
// CHECK-LABEL: define{{.*}} {{i128|i64}} @test_cR_wide_scalar(
51+
// CHECK: call {{i128|i64}} asm sideeffect "", "=^cR,^cR"({{i128|i64}} %{{.*}})
52+
double_xlen_t ret;
53+
asm volatile("" : "=cR"(ret) : "cR"(p));
54+
return ret;
55+
}
56+
4957
void test_I(void) {
5058
// CHECK-LABEL: define{{.*}} void @test_I()
5159
// CHECK: call void asm sideeffect "", "I"(i32 2047)

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21087,7 +21087,7 @@ RISCVTargetLowering::getConstraintType(StringRef Constraint) const {
2108721087
} else {
2108821088
if (Constraint == "vr" || Constraint == "vd" || Constraint == "vm")
2108921089
return C_RegisterClass;
21090-
if (Constraint == "cr" || Constraint == "cf")
21090+
if (Constraint == "cr" || Constraint == "cR" || Constraint == "cf")
2109121091
return C_RegisterClass;
2109221092
}
2109321093
return TargetLowering::getConstraintType(Constraint);
@@ -21176,6 +21176,8 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2117621176
return std::make_pair(0U, &RISCV::GPRPairCRegClass);
2117721177
if (!VT.isVector())
2117821178
return std::make_pair(0U, &RISCV::GPRCRegClass);
21179+
} else if (Constraint == "cR") {
21180+
return std::make_pair(0U, &RISCV::GPRPairCRegClass);
2117921181
} else if (Constraint == "cf") {
2118021182
if (VT == MVT::f16) {
2118121183
if (Subtarget.hasStdExtZfhmin())

llvm/test/CodeGen/RISCV/rv32-inline-asm-pairs.ll

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,73 @@ entry:
7171
%9 = load i64, ptr %3, align 8
7272
ret i64 %9
7373
}
74+
75+
define i64 @test_cR_wide_scalar_simple(i64 noundef %0) nounwind {
76+
; CHECK-LABEL: test_cR_wide_scalar_simple:
77+
; CHECK: # %bb.0: # %entry
78+
; CHECK-NEXT: #APP
79+
; CHECK-NEXT: # a2 <- a0
80+
; CHECK-NEXT: #NO_APP
81+
; CHECK-NEXT: mv a0, a2
82+
; CHECK-NEXT: mv a1, a3
83+
; CHECK-NEXT: ret
84+
entry:
85+
%1 = call i64 asm sideeffect "/* $0 <- $1 */", "=&^cR,^cR"(i64 %0)
86+
ret i64 %1
87+
}
88+
89+
define i32 @test_cR_wide_scalar_with_ops(i32 noundef %0) nounwind {
90+
; CHECK-LABEL: test_cR_wide_scalar_with_ops:
91+
; CHECK: # %bb.0: # %entry
92+
; CHECK-NEXT: mv a1, a0
93+
; CHECK-NEXT: #APP
94+
; CHECK-NEXT: # a2 <- a0
95+
; CHECK-NEXT: #NO_APP
96+
; CHECK-NEXT: or a0, a2, a3
97+
; CHECK-NEXT: ret
98+
entry:
99+
%1 = zext i32 %0 to i64
100+
%2 = shl i64 %1, 32
101+
%3 = or i64 %1, %2
102+
%4 = call i64 asm sideeffect "/* $0 <- $1 */", "=&^cR,^cR"(i64 %3)
103+
%5 = trunc i64 %4 to i32
104+
%6 = lshr i64 %4, 32
105+
%7 = trunc i64 %6 to i32
106+
%8 = or i32 %5, %7
107+
ret i32 %8
108+
}
109+
110+
define i64 @test_cR_wide_scalar_inout(ptr %0, i64 noundef %1) nounwind {
111+
; CHECK-LABEL: test_cR_wide_scalar_inout:
112+
; CHECK: # %bb.0: # %entry
113+
; CHECK-NEXT: addi sp, sp, -16
114+
; CHECK-NEXT: mv a3, a2
115+
; CHECK-NEXT: sw a0, 12(sp)
116+
; CHECK-NEXT: mv a2, a1
117+
; CHECK-NEXT: sw a1, 0(sp)
118+
; CHECK-NEXT: sw a3, 4(sp)
119+
; CHECK-NEXT: #APP
120+
; CHECK-NEXT: # a0; a2
121+
; CHECK-NEXT: #NO_APP
122+
; CHECK-NEXT: sw a0, 12(sp)
123+
; CHECK-NEXT: sw a2, 0(sp)
124+
; CHECK-NEXT: sw a3, 4(sp)
125+
; CHECK-NEXT: mv a0, a2
126+
; CHECK-NEXT: mv a1, a3
127+
; CHECK-NEXT: addi sp, sp, 16
128+
; CHECK-NEXT: ret
129+
entry:
130+
%2 = alloca ptr, align 4
131+
%3 = alloca i64, align 8
132+
store ptr %0, ptr %2, align 4
133+
store i64 %1, ptr %3, align 8
134+
%4 = load ptr, ptr %2, align 4
135+
%5 = load i64, ptr %3, align 8
136+
%6 = call { ptr, i64 } asm sideeffect "/* $0; $1 */", "=r,=^cR,0,1"(ptr %4, i64 %5)
137+
%7 = extractvalue { ptr, i64} %6, 0
138+
%8 = extractvalue { ptr, i64 } %6, 1
139+
store ptr %7, ptr %2, align 4
140+
store i64 %8, ptr %3, align 8
141+
%9 = load i64, ptr %3, align 8
142+
ret i64 %9
143+
}

llvm/test/CodeGen/RISCV/rv64-inline-asm-pairs.ll

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,73 @@ entry:
7171
%9 = load i128, ptr %3, align 16
7272
ret i128 %9
7373
}
74+
75+
define i128 @test_cR_wide_scalar_simple(i128 noundef %0) nounwind {
76+
; CHECK-LABEL: test_cR_wide_scalar_simple:
77+
; CHECK: # %bb.0: # %entry
78+
; CHECK-NEXT: #APP
79+
; CHECK-NEXT: # a2 <- a0
80+
; CHECK-NEXT: #NO_APP
81+
; CHECK-NEXT: mv a0, a2
82+
; CHECK-NEXT: mv a1, a3
83+
; CHECK-NEXT: ret
84+
entry:
85+
%1 = call i128 asm sideeffect "/* $0 <- $1 */", "=&^cR,^cR"(i128 %0)
86+
ret i128 %1
87+
}
88+
89+
define i64 @test_cR_wide_scalar_with_ops(i64 noundef %0) nounwind {
90+
; CHECK-LABEL: test_cR_wide_scalar_with_ops:
91+
; CHECK: # %bb.0: # %entry
92+
; CHECK-NEXT: mv a1, a0
93+
; CHECK-NEXT: #APP
94+
; CHECK-NEXT: # a2 <- a0
95+
; CHECK-NEXT: #NO_APP
96+
; CHECK-NEXT: or a0, a2, a3
97+
; CHECK-NEXT: ret
98+
entry:
99+
%1 = zext i64 %0 to i128
100+
%2 = shl i128 %1, 64
101+
%3 = or i128 %1, %2
102+
%4 = call i128 asm sideeffect "/* $0 <- $1 */", "=&^cR,^cR"(i128 %3)
103+
%5 = trunc i128 %4 to i64
104+
%6 = lshr i128 %4, 64
105+
%7 = trunc i128 %6 to i64
106+
%8 = or i64 %5, %7
107+
ret i64 %8
108+
}
109+
110+
define i128 @test_cR_wide_scalar_inout(ptr %0, i128 noundef %1) nounwind {
111+
; CHECK-LABEL: test_cR_wide_scalar_inout:
112+
; CHECK: # %bb.0: # %entry
113+
; CHECK-NEXT: addi sp, sp, -32
114+
; CHECK-NEXT: mv a3, a2
115+
; CHECK-NEXT: sd a0, 24(sp)
116+
; CHECK-NEXT: mv a2, a1
117+
; CHECK-NEXT: sd a1, 0(sp)
118+
; CHECK-NEXT: sd a3, 8(sp)
119+
; CHECK-NEXT: #APP
120+
; CHECK-NEXT: # a0; a2
121+
; CHECK-NEXT: #NO_APP
122+
; CHECK-NEXT: sd a0, 24(sp)
123+
; CHECK-NEXT: sd a2, 0(sp)
124+
; CHECK-NEXT: sd a3, 8(sp)
125+
; CHECK-NEXT: mv a0, a2
126+
; CHECK-NEXT: mv a1, a3
127+
; CHECK-NEXT: addi sp, sp, 32
128+
; CHECK-NEXT: ret
129+
entry:
130+
%2 = alloca ptr, align 8
131+
%3 = alloca i128, align 16
132+
store ptr %0, ptr %2, align 8
133+
store i128 %1, ptr %3, align 16
134+
%4 = load ptr, ptr %2, align 8
135+
%5 = load i128, ptr %3, align 16
136+
%6 = call { ptr, i128 } asm sideeffect "/* $0; $1 */", "=r,=^cR,0,1"(ptr %4, i128 %5)
137+
%7 = extractvalue { ptr, i128} %6, 0
138+
%8 = extractvalue { ptr, i128 } %6, 1
139+
store ptr %7, ptr %2, align 8
140+
store i128 %8, ptr %3, align 16
141+
%9 = load i128, ptr %3, align 16
142+
ret i128 %9
143+
}

llvm/test/CodeGen/RISCV/zdinx-asm-constraint.ll

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,24 @@ entry:
8282
ret void
8383
}
8484

85+
define dso_local void @zdinx_asm_cR_inout(ptr nocapture noundef writeonly %a, double noundef %b) nounwind {
86+
; CHECK-LABEL: zdinx_asm_cR_inout:
87+
; CHECK: # %bb.0: # %entry
88+
; CHECK-NEXT: mv a3, a2
89+
; CHECK-NEXT: mv a2, a1
90+
; CHECK-NEXT: #APP
91+
; CHECK-NEXT: fabs.d a2, a2
92+
; CHECK-NEXT: #NO_APP
93+
; CHECK-NEXT: sw a2, 8(a0)
94+
; CHECK-NEXT: sw a3, 12(a0)
95+
; CHECK-NEXT: ret
96+
entry:
97+
%arrayidx = getelementptr inbounds double, ptr %a, i32 1
98+
%0 = tail call double asm "fsgnjx.d $0, $1, $1", "=^cR,0"(double %b)
99+
store double %0, ptr %arrayidx, align 8
100+
ret void
101+
}
102+
85103
define dso_local void @zfinx_asm(ptr nocapture noundef writeonly %a, float noundef %b, float noundef %c) nounwind {
86104
; CHECK-LABEL: zfinx_asm:
87105
; CHECK: # %bb.0: # %entry
@@ -167,3 +185,29 @@ entry:
167185
store half %0, ptr %arrayidx, align 8
168186
ret void
169187
}
188+
189+
define dso_local void @zdinx_asm_cR(ptr nocapture noundef writeonly %a, double noundef %b, double noundef %c) nounwind {
190+
; CHECK-LABEL: zdinx_asm_cR:
191+
; CHECK: # %bb.0: # %entry
192+
; CHECK-NEXT: addi sp, sp, -16
193+
; CHECK-NEXT: sw s0, 12(sp) # 4-byte Folded Spill
194+
; CHECK-NEXT: sw s1, 8(sp) # 4-byte Folded Spill
195+
; CHECK-NEXT: mv a5, a4
196+
; CHECK-NEXT: mv s1, a2
197+
; CHECK-NEXT: mv a4, a3
198+
; CHECK-NEXT: mv s0, a1
199+
; CHECK-NEXT: #APP
200+
; CHECK-NEXT: fsgnjx.d a2, s0, a4
201+
; CHECK-NEXT: #NO_APP
202+
; CHECK-NEXT: sw a2, 8(a0)
203+
; CHECK-NEXT: sw a3, 12(a0)
204+
; CHECK-NEXT: lw s0, 12(sp) # 4-byte Folded Reload
205+
; CHECK-NEXT: lw s1, 8(sp) # 4-byte Folded Reload
206+
; CHECK-NEXT: addi sp, sp, 16
207+
; CHECK-NEXT: ret
208+
entry:
209+
%arrayidx = getelementptr inbounds double, ptr %a, i32 1
210+
%0 = tail call double asm "fsgnjx.d $0, $1, $2", "=^cR,^cR,^cR"(double %b, double %c)
211+
store double %0, ptr %arrayidx, align 8
212+
ret void
213+
}

0 commit comments

Comments
 (0)