Skip to content

Commit ba60709

Browse files
committed
[RISCV] Support inline assembly 'f' constraint for Zfinx.
This would allow some inline assembly code work with either F or Zfinx. This appears to match gcc behavior. This will need to be adjust to exclude X0 after #112563.
1 parent 47d9ca8 commit ba60709

File tree

4 files changed

+211
-12
lines changed

4 files changed

+211
-12
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20392,12 +20392,24 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2039220392
return std::make_pair(0U, &RISCV::GPRPairRegClass);
2039320393
return std::make_pair(0U, &RISCV::GPRNoX0RegClass);
2039420394
case 'f':
20395-
if (Subtarget.hasStdExtZfhmin() && VT == MVT::f16)
20396-
return std::make_pair(0U, &RISCV::FPR16RegClass);
20397-
if (Subtarget.hasStdExtF() && VT == MVT::f32)
20398-
return std::make_pair(0U, &RISCV::FPR32RegClass);
20399-
if (Subtarget.hasStdExtD() && VT == MVT::f64)
20400-
return std::make_pair(0U, &RISCV::FPR64RegClass);
20395+
if (VT == MVT::f16) {
20396+
if (Subtarget.hasStdExtZfhmin())
20397+
return std::make_pair(0U, &RISCV::FPR16RegClass);
20398+
if (Subtarget.hasStdExtZhinxmin())
20399+
return std::make_pair(0U, &RISCV::GPRF16RegClass);
20400+
} else if (VT == MVT::f32) {
20401+
if (Subtarget.hasStdExtF())
20402+
return std::make_pair(0U, &RISCV::FPR32RegClass);
20403+
if (Subtarget.hasStdExtZfinx())
20404+
return std::make_pair(0U, &RISCV::GPRF32RegClass);
20405+
} else if (VT == MVT::f64) {
20406+
if (Subtarget.hasStdExtD())
20407+
return std::make_pair(0U, &RISCV::FPR64RegClass);
20408+
if (Subtarget.hasStdExtZdinx() && !Subtarget.is64Bit())
20409+
return std::make_pair(0U, &RISCV::GPRPairRegClass);
20410+
if (Subtarget.hasStdExtZdinx() && Subtarget.is64Bit())
20411+
return std::make_pair(0U, &RISCV::GPRNoX0RegClass);
20412+
}
2040120413
break;
2040220414
default:
2040320415
break;
@@ -20440,12 +20452,24 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2044020452
if (!VT.isVector())
2044120453
return std::make_pair(0U, &RISCV::GPRCRegClass);
2044220454
} else if (Constraint == "cf") {
20443-
if (Subtarget.hasStdExtZfhmin() && VT == MVT::f16)
20444-
return std::make_pair(0U, &RISCV::FPR16CRegClass);
20445-
if (Subtarget.hasStdExtF() && VT == MVT::f32)
20446-
return std::make_pair(0U, &RISCV::FPR32CRegClass);
20447-
if (Subtarget.hasStdExtD() && VT == MVT::f64)
20448-
return std::make_pair(0U, &RISCV::FPR64CRegClass);
20455+
if (VT == MVT::f16) {
20456+
if (Subtarget.hasStdExtZfhmin())
20457+
return std::make_pair(0U, &RISCV::FPR16CRegClass);
20458+
if (Subtarget.hasStdExtZhinxmin())
20459+
return std::make_pair(0U, &RISCV::GPRF16CRegClass);
20460+
} else if (VT == MVT::f32) {
20461+
if (Subtarget.hasStdExtF())
20462+
return std::make_pair(0U, &RISCV::FPR32CRegClass);
20463+
if (Subtarget.hasStdExtZfinx())
20464+
return std::make_pair(0U, &RISCV::GPRF32CRegClass);
20465+
} else if (VT == MVT::f64) {
20466+
if (Subtarget.hasStdExtD())
20467+
return std::make_pair(0U, &RISCV::FPR64CRegClass);
20468+
if (Subtarget.hasStdExtZdinx() && !Subtarget.is64Bit())
20469+
return std::make_pair(0U, &RISCV::GPRPairCRegClass);
20470+
if (Subtarget.hasStdExtZdinx() && Subtarget.is64Bit())
20471+
return std::make_pair(0U, &RISCV::GPRCRegClass);
20472+
}
2044920473
}
2045020474

2045120475
// Clang will correctly decode the usage of register name aliases into their

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,51 @@ define double @constraint_double_abi_name(double %a) nounwind {
9090
%2 = tail call double asm "fadd.d $0, $1, $2", "={t1},{a0},{s0}"(double %a, double %1)
9191
ret double %2
9292
}
93+
94+
define double @constraint_f_double(double %a) nounwind {
95+
; RV32FINX-LABEL: constraint_f_double:
96+
; RV32FINX: # %bb.0:
97+
; RV32FINX-NEXT: lui a2, %hi(gd)
98+
; RV32FINX-NEXT: lw a3, %lo(gd+4)(a2)
99+
; RV32FINX-NEXT: lw a2, %lo(gd)(a2)
100+
; RV32FINX-NEXT: #APP
101+
; RV32FINX-NEXT: fadd.d a0, a0, a2
102+
; RV32FINX-NEXT: #NO_APP
103+
; RV32FINX-NEXT: ret
104+
;
105+
; RV64FINX-LABEL: constraint_f_double:
106+
; RV64FINX: # %bb.0:
107+
; RV64FINX-NEXT: lui a1, %hi(gd)
108+
; RV64FINX-NEXT: ld a1, %lo(gd)(a1)
109+
; RV64FINX-NEXT: #APP
110+
; RV64FINX-NEXT: fadd.d a0, a0, a1
111+
; RV64FINX-NEXT: #NO_APP
112+
; RV64FINX-NEXT: ret
113+
%1 = load double, ptr @gd
114+
%2 = tail call double asm "fadd.d $0, $1, $2", "=f,f,f"(double %a, double %1)
115+
ret double %2
116+
}
117+
118+
define double @constraint_cf_double(double %a) nounwind {
119+
; RV32FINX-LABEL: constraint_cf_double:
120+
; RV32FINX: # %bb.0:
121+
; RV32FINX-NEXT: lui a2, %hi(gd)
122+
; RV32FINX-NEXT: lw a3, %lo(gd+4)(a2)
123+
; RV32FINX-NEXT: lw a2, %lo(gd)(a2)
124+
; RV32FINX-NEXT: #APP
125+
; RV32FINX-NEXT: fadd.d a0, a0, a2
126+
; RV32FINX-NEXT: #NO_APP
127+
; RV32FINX-NEXT: ret
128+
;
129+
; RV64FINX-LABEL: constraint_cf_double:
130+
; RV64FINX: # %bb.0:
131+
; RV64FINX-NEXT: lui a1, %hi(gd)
132+
; RV64FINX-NEXT: ld a1, %lo(gd)(a1)
133+
; RV64FINX-NEXT: #APP
134+
; RV64FINX-NEXT: fadd.d a0, a0, a1
135+
; RV64FINX-NEXT: #NO_APP
136+
; RV64FINX-NEXT: ret
137+
%1 = load double, ptr @gd
138+
%2 = tail call double asm "fadd.d $0, $1, $2", "=^cf,^cf,^cf"(double %a, double %1)
139+
ret double %2
140+
}

llvm/test/CodeGen/RISCV/inline-asm-zfinx-constraint-r.ll

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,48 @@ define float @constraint_float_abi_name(float %a) nounwind {
8787
ret float %2
8888
}
8989

90+
define float @constraint_f_float(float %a) nounwind {
91+
; RV32FINX-LABEL: constraint_f_float:
92+
; RV32FINX: # %bb.0:
93+
; RV32FINX-NEXT: lui a1, %hi(gf)
94+
; RV32FINX-NEXT: lw a1, %lo(gf)(a1)
95+
; RV32FINX-NEXT: #APP
96+
; RV32FINX-NEXT: fadd.s a0, a0, a1
97+
; RV32FINX-NEXT: #NO_APP
98+
; RV32FINX-NEXT: ret
99+
;
100+
; RV64FINX-LABEL: constraint_f_float:
101+
; RV64FINX: # %bb.0:
102+
; RV64FINX-NEXT: lui a1, %hi(gf)
103+
; RV64FINX-NEXT: lw a1, %lo(gf)(a1)
104+
; RV64FINX-NEXT: #APP
105+
; RV64FINX-NEXT: fadd.s a0, a0, a1
106+
; RV64FINX-NEXT: #NO_APP
107+
; RV64FINX-NEXT: ret
108+
%1 = load float, ptr @gf
109+
%2 = tail call float asm "fadd.s $0, $1, $2", "=f,f,f"(float %a, float %1)
110+
ret float %2
111+
}
112+
113+
define float @constraint_cf_float(float %a) nounwind {
114+
; RV32FINX-LABEL: constraint_cf_float:
115+
; RV32FINX: # %bb.0:
116+
; RV32FINX-NEXT: lui a1, %hi(gf)
117+
; RV32FINX-NEXT: lw a1, %lo(gf)(a1)
118+
; RV32FINX-NEXT: #APP
119+
; RV32FINX-NEXT: fadd.s a0, a0, a1
120+
; RV32FINX-NEXT: #NO_APP
121+
; RV32FINX-NEXT: ret
122+
;
123+
; RV64FINX-LABEL: constraint_cf_float:
124+
; RV64FINX: # %bb.0:
125+
; RV64FINX-NEXT: lui a1, %hi(gf)
126+
; RV64FINX-NEXT: lw a1, %lo(gf)(a1)
127+
; RV64FINX-NEXT: #APP
128+
; RV64FINX-NEXT: fadd.s a0, a0, a1
129+
; RV64FINX-NEXT: #NO_APP
130+
; RV64FINX-NEXT: ret
131+
%1 = load float, ptr @gf
132+
%2 = tail call float asm "fadd.s $0, $1, $2", "=^cf,cf,cf"(float %a, float %1)
133+
ret float %2
134+
}

llvm/test/CodeGen/RISCV/inline-asm-zhinx-constraint-r.ll

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,85 @@ define half @constraint_half_abi_name(half %a) nounwind {
156156
%2 = tail call half asm "fadd.s $0, $1, $2", "={t0},{a0},{s0}"(half %a, half %1)
157157
ret half %2
158158
}
159+
160+
define half @constraint_f_half(half %a) nounwind {
161+
; RV32ZHINX-LABEL: constraint_f_half:
162+
; RV32ZHINX: # %bb.0:
163+
; RV32ZHINX-NEXT: lui a1, %hi(gh)
164+
; RV32ZHINX-NEXT: lh a1, %lo(gh)(a1)
165+
; RV32ZHINX-NEXT: #APP
166+
; RV32ZHINX-NEXT: fadd.h a0, a0, a1
167+
; RV32ZHINX-NEXT: #NO_APP
168+
; RV32ZHINX-NEXT: ret
169+
;
170+
; RV64ZHINX-LABEL: constraint_f_half:
171+
; RV64ZHINX: # %bb.0:
172+
; RV64ZHINX-NEXT: lui a1, %hi(gh)
173+
; RV64ZHINX-NEXT: lh a1, %lo(gh)(a1)
174+
; RV64ZHINX-NEXT: #APP
175+
; RV64ZHINX-NEXT: fadd.h a0, a0, a1
176+
; RV64ZHINX-NEXT: #NO_APP
177+
; RV64ZHINX-NEXT: ret
178+
;
179+
; RV32DINXZHINX-LABEL: constraint_f_half:
180+
; RV32DINXZHINX: # %bb.0:
181+
; RV32DINXZHINX-NEXT: lui a1, %hi(gh)
182+
; RV32DINXZHINX-NEXT: lh a1, %lo(gh)(a1)
183+
; RV32DINXZHINX-NEXT: #APP
184+
; RV32DINXZHINX-NEXT: fadd.h a0, a0, a1
185+
; RV32DINXZHINX-NEXT: #NO_APP
186+
; RV32DINXZHINX-NEXT: ret
187+
;
188+
; RV64DINXZHINX-LABEL: constraint_f_half:
189+
; RV64DINXZHINX: # %bb.0:
190+
; RV64DINXZHINX-NEXT: lui a1, %hi(gh)
191+
; RV64DINXZHINX-NEXT: lh a1, %lo(gh)(a1)
192+
; RV64DINXZHINX-NEXT: #APP
193+
; RV64DINXZHINX-NEXT: fadd.h a0, a0, a1
194+
; RV64DINXZHINX-NEXT: #NO_APP
195+
; RV64DINXZHINX-NEXT: ret
196+
%1 = load half, ptr @gh
197+
%2 = tail call half asm "fadd.h $0, $1, $2", "=f,f,f"(half %a, half %1)
198+
ret half %2
199+
}
200+
201+
define half @constraint_cf_half(half %a) nounwind {
202+
; RV32ZHINX-LABEL: constraint_cf_half:
203+
; RV32ZHINX: # %bb.0:
204+
; RV32ZHINX-NEXT: lui a1, %hi(gh)
205+
; RV32ZHINX-NEXT: lh a1, %lo(gh)(a1)
206+
; RV32ZHINX-NEXT: #APP
207+
; RV32ZHINX-NEXT: fadd.h a0, a0, a1
208+
; RV32ZHINX-NEXT: #NO_APP
209+
; RV32ZHINX-NEXT: ret
210+
;
211+
; RV64ZHINX-LABEL: constraint_cf_half:
212+
; RV64ZHINX: # %bb.0:
213+
; RV64ZHINX-NEXT: lui a1, %hi(gh)
214+
; RV64ZHINX-NEXT: lh a1, %lo(gh)(a1)
215+
; RV64ZHINX-NEXT: #APP
216+
; RV64ZHINX-NEXT: fadd.h a0, a0, a1
217+
; RV64ZHINX-NEXT: #NO_APP
218+
; RV64ZHINX-NEXT: ret
219+
;
220+
; RV32DINXZHINX-LABEL: constraint_cf_half:
221+
; RV32DINXZHINX: # %bb.0:
222+
; RV32DINXZHINX-NEXT: lui a1, %hi(gh)
223+
; RV32DINXZHINX-NEXT: lh a1, %lo(gh)(a1)
224+
; RV32DINXZHINX-NEXT: #APP
225+
; RV32DINXZHINX-NEXT: fadd.h a0, a0, a1
226+
; RV32DINXZHINX-NEXT: #NO_APP
227+
; RV32DINXZHINX-NEXT: ret
228+
;
229+
; RV64DINXZHINX-LABEL: constraint_cf_half:
230+
; RV64DINXZHINX: # %bb.0:
231+
; RV64DINXZHINX-NEXT: lui a1, %hi(gh)
232+
; RV64DINXZHINX-NEXT: lh a1, %lo(gh)(a1)
233+
; RV64DINXZHINX-NEXT: #APP
234+
; RV64DINXZHINX-NEXT: fadd.h a0, a0, a1
235+
; RV64DINXZHINX-NEXT: #NO_APP
236+
; RV64DINXZHINX-NEXT: ret
237+
%1 = load half, ptr @gh
238+
%2 = tail call half asm "fadd.h $0, $1, $2", "=^cf,^cf,^cf"(half %a, half %1)
239+
ret half %2
240+
}

0 commit comments

Comments
 (0)