@@ -193,15 +193,52 @@ struct RISCVCallReturnHandler : public RISCVIncomingValueHandler {
193
193
RISCVCallLowering::RISCVCallLowering (const RISCVTargetLowering &TLI)
194
194
: CallLowering(&TLI) {}
195
195
196
+ // TODO: Support all argument types.
197
+ static bool isSupportedArgumentType (Type *T, const RISCVSubtarget &Subtarget) {
198
+ // TODO: Integers larger than 2*XLen are passed indirectly which is not
199
+ // supported yet.
200
+ if (T->isIntegerTy ())
201
+ return T->getIntegerBitWidth () <= Subtarget.getXLen () * 2 ;
202
+ if (T->isPointerTy ())
203
+ return true ;
204
+ return false ;
205
+ }
206
+
207
+ // TODO: Only integer, pointer and aggregate types are supported now.
208
+ static bool isSupportedReturnType (Type *T, const RISCVSubtarget &Subtarget) {
209
+ // TODO: Integers larger than 2*XLen are passed indirectly which is not
210
+ // supported yet.
211
+ if (T->isIntegerTy ())
212
+ return T->getIntegerBitWidth () <= Subtarget.getXLen () * 2 ;
213
+ if (T->isPointerTy ())
214
+ return true ;
215
+
216
+ if (T->isArrayTy ())
217
+ return isSupportedReturnType (T->getArrayElementType (), Subtarget);
218
+
219
+ if (T->isStructTy ()) {
220
+ // For now we only allow homogeneous structs that we can manipulate with
221
+ // G_MERGE_VALUES and G_UNMERGE_VALUES
222
+ auto StructT = cast<StructType>(T);
223
+ for (unsigned i = 1 , e = StructT->getNumElements (); i != e; ++i)
224
+ if (StructT->getElementType (i) != StructT->getElementType (0 ))
225
+ return false ;
226
+ return isSupportedReturnType (StructT->getElementType (0 ), Subtarget);
227
+ }
228
+
229
+ return false ;
230
+ }
231
+
196
232
bool RISCVCallLowering::lowerReturnVal (MachineIRBuilder &MIRBuilder,
197
233
const Value *Val,
198
234
ArrayRef<Register> VRegs,
199
235
MachineInstrBuilder &Ret) const {
200
236
if (!Val)
201
237
return true ;
202
238
203
- // TODO: Only integer, pointer and aggregate types are supported now.
204
- if (!Val->getType ()->isIntOrPtrTy () && !Val->getType ()->isAggregateType ())
239
+ const RISCVSubtarget &Subtarget =
240
+ MIRBuilder.getMF ().getSubtarget <RISCVSubtarget>();
241
+ if (!isSupportedReturnType (Val->getType (), Subtarget))
205
242
return false ;
206
243
207
244
MachineFunction &MF = MIRBuilder.getMF ();
@@ -248,13 +285,11 @@ bool RISCVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
248
285
if (F.isVarArg ())
249
286
return false ;
250
287
251
- // TODO: Support all argument types.
288
+ const RISCVSubtarget &Subtarget =
289
+ MIRBuilder.getMF ().getSubtarget <RISCVSubtarget>();
252
290
for (auto &Arg : F.args ()) {
253
- if (Arg.getType ()->isIntegerTy ())
254
- continue ;
255
- if (Arg.getType ()->isPointerTy ())
256
- continue ;
257
- return false ;
291
+ if (!isSupportedArgumentType (Arg.getType (), Subtarget))
292
+ return false ;
258
293
}
259
294
260
295
MachineFunction &MF = MIRBuilder.getMF ();
@@ -292,15 +327,11 @@ bool RISCVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
292
327
const Function &F = MF.getFunction ();
293
328
CallingConv::ID CC = F.getCallingConv ();
294
329
295
- // TODO: Support all argument types.
330
+ const RISCVSubtarget &Subtarget =
331
+ MIRBuilder.getMF ().getSubtarget <RISCVSubtarget>();
296
332
for (auto &AInfo : Info.OrigArgs ) {
297
- if (AInfo.Ty ->isIntegerTy ())
298
- continue ;
299
- if (AInfo.Ty ->isPointerTy ())
300
- continue ;
301
- if (AInfo.Ty ->isFloatingPointTy ())
302
- continue ;
303
- return false ;
333
+ if (!isSupportedArgumentType (AInfo.Ty , Subtarget))
334
+ return false ;
304
335
}
305
336
306
337
SmallVector<ArgInfo, 32 > SplitArgInfos;
@@ -337,8 +368,7 @@ bool RISCVCallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
337
368
if (Info.OrigRet .Ty ->isVoidTy ())
338
369
return true ;
339
370
340
- // TODO: Only integer, pointer and aggregate types are supported now.
341
- if (!Info.OrigRet .Ty ->isIntOrPtrTy () && !Info.OrigRet .Ty ->isAggregateType ())
371
+ if (!isSupportedReturnType (Info.OrigRet .Ty , Subtarget))
342
372
return false ;
343
373
344
374
SmallVector<ArgInfo, 4 > SplitRetInfos;
0 commit comments