@@ -165,6 +165,21 @@ void X86_64ABIInfo::classify(mlir::Type Ty, uint64_t OffsetBase, Class &Lo,
165165 Current = Class::SSE;
166166 return ;
167167
168+ } else if (mlir::isa<LongDoubleType>(Ty)) {
169+ const llvm::fltSemantics *LDF =
170+ &getContext ().getTargetInfo ().getLongDoubleFormat ();
171+ if (LDF == &llvm::APFloat::IEEEquad ()) {
172+ Lo = Class::SSE;
173+ Hi = Class::SSEUp;
174+ } else if (LDF == &llvm::APFloat::x87DoubleExtended ()) {
175+ Lo = Class::X87;
176+ Hi = Class::X87Up;
177+ } else if (LDF == &llvm::APFloat::IEEEdouble ()) {
178+ Current = Class::SSE;
179+ } else {
180+ llvm_unreachable (" unexpected long double representation!" );
181+ }
182+ return ;
168183 } else if (mlir::isa<BoolType>(Ty)) {
169184 Current = Class::Integer;
170185 } else if (const auto RT = mlir::dyn_cast<StructType>(Ty)) {
@@ -267,6 +282,65 @@ void X86_64ABIInfo::classify(mlir::Type Ty, uint64_t OffsetBase, Class &Lo,
267282 cir_cconv_unreachable (" NYI" );
268283}
269284
285+ ABIArgInfo X86_64ABIInfo::getIndirectResult (mlir::Type ty,
286+ unsigned freeIntRegs) const {
287+ // If this is a scalar LLVM value then assume LLVM will pass it in the right
288+ // place naturally.
289+ //
290+ // This assumption is optimistic, as there could be free registers available
291+ // when we need to pass this argument in memory, and LLVM could try to pass
292+ // the argument in the free register. This does not seem to happen currently,
293+ // but this code would be much safer if we could mark the argument with
294+ // 'onstack'. See PR12193.
295+ if (!isAggregateTypeForABI (ty) /* && IsIllegalVectorType(Ty) &&*/
296+ /* !Ty->isBitIntType()*/ ) {
297+ // FIXME: Handling enum type?
298+
299+ return (isPromotableIntegerTypeForABI (ty) ? ABIArgInfo::getExtend (ty)
300+ : ABIArgInfo::getDirect ());
301+ }
302+
303+ if (CIRCXXABI::RecordArgABI RAA = getRecordArgABI (ty, getCXXABI ()))
304+ return getNaturalAlignIndirect (ty, RAA == CIRCXXABI::RAA_DirectInMemory);
305+
306+ // Compute the byval alignment. We specify the alignment of the byval in all
307+ // cases so that the mid-level optimizer knows the alignment of the byval.
308+ unsigned align = std::max (getContext ().getTypeAlign (ty) / 8 , 8U );
309+
310+ // Attempt to avoid passing indirect results using byval when possible. This
311+ // is important for good codegen.
312+ //
313+ // We do this by coercing the value into a scalar type which the backend can
314+ // handle naturally (i.e., without using byval).
315+ //
316+ // For simplicity, we currently only do this when we have exhausted all of the
317+ // free integer registers. Doing this when there are free integer registers
318+ // would require more care, as we would have to ensure that the coerced value
319+ // did not claim the unused register. That would require either reording the
320+ // arguments to the function (so that any subsequent inreg values came first),
321+ // or only doing this optimization when there were no following arguments that
322+ // might be inreg.
323+ //
324+ // We currently expect it to be rare (particularly in well written code) for
325+ // arguments to be passed on the stack when there are still free integer
326+ // registers available (this would typically imply large structs being passed
327+ // by value), so this seems like a fair tradeoff for now.
328+ //
329+ // We can revisit this if the backend grows support for 'onstack' parameter
330+ // attributes. See PR12193.
331+ if (freeIntRegs == 0 ) {
332+ uint64_t size = getContext ().getTypeSize (ty);
333+
334+ // If this type fits in an eightbyte, coerce it into the matching integral
335+ // type, which will end up on the stack (with alignment 8).
336+ if (align == 8 && size <= 64 )
337+ return ABIArgInfo::getDirect (
338+ cir::IntType::get (LT.getMLIRContext (), size, false ));
339+ }
340+
341+ return ABIArgInfo::getIndirect (align);
342+ }
343+
270344// / Return a type that will be passed by the backend in the low 8 bytes of an
271345// / XMM register, corresponding to the SSE class.
272346mlir::Type X86_64ABIInfo::GetSSETypeAtOffset (mlir::Type IRType,
@@ -278,7 +352,7 @@ mlir::Type X86_64ABIInfo::GetSSETypeAtOffset(mlir::Type IRType,
278352 (unsigned )getContext ().getTypeSize (SourceTy) / 8 - SourceOffset;
279353 mlir::Type T0 = getFPTypeAtOffset (IRType, IROffset, TD);
280354 if (!T0 || mlir::isa<mlir::Float64Type>(T0))
281- return T0; // NOTE( cir): Not sure if this is correct.
355+ return cir::DoubleType::get (LT. getMLIRContext ());
282356
283357 mlir::Type T1 = {};
284358 unsigned T0Size = TD.getTypeAllocSize (T0);
@@ -296,6 +370,8 @@ mlir::Type X86_64ABIInfo::GetSSETypeAtOffset(mlir::Type IRType,
296370 return T0;
297371 }
298372
373+ return cir::DoubleType::get (LT.getMLIRContext ());
374+
299375 cir_cconv_unreachable (" NYI" );
300376}
301377
@@ -539,13 +615,34 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(
539615 ++neededSSE;
540616 break ;
541617 }
618+ // AMD64-ABI 3.2.3p3: Rule 1. If the class is MEMORY, pass the argument
619+ // on the stack.
620+ case Class::Memory:
621+
622+ // AMD64-ABI 3.2.3p3: Rule 5. If the class is X87, X87UP or
623+ // COMPLEX_X87, it is passed in memory.
624+ case Class::X87:
625+ case Class::ComplexX87:
626+ if (getRecordArgABI (Ty, getCXXABI ()) == CIRCXXABI::RAA_Indirect)
627+ ++neededInt;
628+ return getIndirectResult (Ty, freeIntRegs);
629+
630+ case Class::SSEUp:
631+ case Class::X87Up:
632+ llvm_unreachable (" Invalid classification for lo word." );
633+
542634 default :
543635 cir_cconv_assert_or_abort (!cir::MissingFeatures::X86ArgTypeClassification (),
544636 " NYI" );
545637 }
546638
547639 mlir::Type HighPart = {};
548640 switch (Hi) {
641+ case Class::Memory:
642+ case Class::X87:
643+ case Class::ComplexX87:
644+ llvm_unreachable (" Invalid classification for hi word." );
645+
549646 case Class::NoClass:
550647 break ;
551648
@@ -558,8 +655,23 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(
558655 return ABIArgInfo::getDirect (HighPart, 8 );
559656 break ;
560657
561- default :
562- cir_cconv_unreachable (" NYI" );
658+ // X87Up generally doesn't occur here (long double is passed in
659+ // memory), except in situations involving unions.
660+ case Class::X87Up:
661+ case Class::SSE:
662+ ++neededSSE;
663+ HighPart = GetSSETypeAtOffset (Ty, 8 , Ty, 8 );
664+
665+ if (Lo == Class::NoClass) // Pass HighPart at offset 8 in memory.
666+ return ABIArgInfo::getDirect (HighPart, 8 );
667+ break ;
668+
669+ // AMD64-ABI 3.2.3p3: Rule 4. If the class is SSEUP, the
670+ // eightbyte is passed in the upper half of the last used SSE
671+ // register. This only happens when 128-bit vectors are passed.
672+ case Class::SSEUp:
673+ llvm_unreachable (" NYI && We need to implement GetByteVectorType" );
674+ break ;
563675 }
564676
565677 // If a high part was specified, merge it together with the low part. It is
0 commit comments