@@ -165,6 +165,21 @@ void X86_64ABIInfo::classify(mlir::Type Ty, uint64_t OffsetBase, Class &Lo,
165
165
Current = Class::SSE;
166
166
return ;
167
167
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 ;
168
183
} else if (mlir::isa<BoolType>(Ty)) {
169
184
Current = Class::Integer;
170
185
} 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,
267
282
cir_cconv_unreachable (" NYI" );
268
283
}
269
284
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
+
270
344
// / Return a type that will be passed by the backend in the low 8 bytes of an
271
345
// / XMM register, corresponding to the SSE class.
272
346
mlir::Type X86_64ABIInfo::GetSSETypeAtOffset (mlir::Type IRType,
@@ -278,7 +352,7 @@ mlir::Type X86_64ABIInfo::GetSSETypeAtOffset(mlir::Type IRType,
278
352
(unsigned )getContext ().getTypeSize (SourceTy) / 8 - SourceOffset;
279
353
mlir::Type T0 = getFPTypeAtOffset (IRType, IROffset, TD);
280
354
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 ());
282
356
283
357
mlir::Type T1 = {};
284
358
unsigned T0Size = TD.getTypeAllocSize (T0);
@@ -539,13 +613,34 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(
539
613
++neededSSE;
540
614
break ;
541
615
}
616
+ // AMD64-ABI 3.2.3p3: Rule 1. If the class is MEMORY, pass the argument
617
+ // on the stack.
618
+ case Class::Memory:
619
+
620
+ // AMD64-ABI 3.2.3p3: Rule 5. If the class is X87, X87UP or
621
+ // COMPLEX_X87, it is passed in memory.
622
+ case Class::X87:
623
+ case Class::ComplexX87:
624
+ if (getRecordArgABI (Ty, getCXXABI ()) == CIRCXXABI::RAA_Indirect)
625
+ ++neededInt;
626
+ return getIndirectResult (Ty, freeIntRegs);
627
+
628
+ case Class::SSEUp:
629
+ case Class::X87Up:
630
+ llvm_unreachable (" Invalid classification for lo word." );
631
+
542
632
default :
543
633
cir_cconv_assert_or_abort (!cir::MissingFeatures::X86ArgTypeClassification (),
544
634
" NYI" );
545
635
}
546
636
547
637
mlir::Type HighPart = {};
548
638
switch (Hi) {
639
+ case Class::Memory:
640
+ case Class::X87:
641
+ case Class::ComplexX87:
642
+ llvm_unreachable (" Invalid classification for hi word." );
643
+
549
644
case Class::NoClass:
550
645
break ;
551
646
@@ -558,8 +653,23 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(
558
653
return ABIArgInfo::getDirect (HighPart, 8 );
559
654
break ;
560
655
561
- default :
562
- cir_cconv_unreachable (" NYI" );
656
+ // X87Up generally doesn't occur here (long double is passed in
657
+ // memory), except in situations involving unions.
658
+ case Class::X87Up:
659
+ case Class::SSE:
660
+ ++neededSSE;
661
+ HighPart = GetSSETypeAtOffset (Ty, 8 , Ty, 8 );
662
+
663
+ if (Lo == Class::NoClass) // Pass HighPart at offset 8 in memory.
664
+ return ABIArgInfo::getDirect (HighPart, 8 );
665
+ break ;
666
+
667
+ // AMD64-ABI 3.2.3p3: Rule 4. If the class is SSEUP, the
668
+ // eightbyte is passed in the upper half of the last used SSE
669
+ // register. This only happens when 128-bit vectors are passed.
670
+ case Class::SSEUp:
671
+ llvm_unreachable (" NYI && We need to implement GetByteVectorType" );
672
+ break ;
563
673
}
564
674
565
675
// If a high part was specified, merge it together with the low part. It is
0 commit comments