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