@@ -166,6 +166,21 @@ void X86_64ABIInfo::classify(Type Ty, uint64_t OffsetBase, Class &Lo, Class &Hi,
166
166
Current = Class::SSE;
167
167
return ;
168
168
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 ;
169
184
} else if (isa<BoolType>(Ty)) {
170
185
Current = Class::Integer;
171
186
} 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,
268
283
cir_cconv_unreachable (" NYI" );
269
284
}
270
285
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
+
271
345
// / Return a type that will be passed by the backend in the low 8 bytes of an
272
346
// / XMM register, corresponding to the SSE class.
273
347
Type X86_64ABIInfo::GetSSETypeAtOffset (Type IRType, unsigned IROffset,
@@ -278,7 +352,7 @@ Type X86_64ABIInfo::GetSSETypeAtOffset(Type IRType, unsigned IROffset,
278
352
(unsigned )getContext ().getTypeSize (SourceTy) / 8 - SourceOffset;
279
353
Type T0 = getFPTypeAtOffset (IRType, IROffset, TD);
280
354
if (!T0 || isa<Float64Type>(T0))
281
- return T0; // NOTE( cir): Not sure if this is correct.
355
+ return :: mlir:: cir::DoubleType::get (LT. getMLIRContext ());
282
356
283
357
Type T1 = {};
284
358
unsigned T0Size = TD.getTypeAllocSize (T0);
@@ -296,6 +370,8 @@ Type X86_64ABIInfo::GetSSETypeAtOffset(Type IRType, unsigned IROffset,
296
370
return T0;
297
371
}
298
372
373
+ return ::mlir::cir::DoubleType::get (LT.getMLIRContext ());
374
+
299
375
cir_cconv_unreachable (" NYI" );
300
376
}
301
377
@@ -538,13 +614,34 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(Type Ty, unsigned freeIntRegs,
538
614
++neededSSE;
539
615
break ;
540
616
}
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
+
541
633
default :
542
634
cir_cconv_assert_or_abort (
543
635
!::cir::MissingFeatures::X86ArgTypeClassification (), " NYI" );
544
636
}
545
637
546
638
Type HighPart = {};
547
639
switch (Hi) {
640
+ case Class::Memory:
641
+ case Class::X87:
642
+ case Class::ComplexX87:
643
+ llvm_unreachable (" Invalid classification for hi word." );
644
+
548
645
case Class::NoClass:
549
646
break ;
550
647
@@ -557,8 +654,23 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(Type Ty, unsigned freeIntRegs,
557
654
return ABIArgInfo::getDirect (HighPart, 8 );
558
655
break ;
559
656
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 ;
562
674
}
563
675
564
676
// If a high part was specified, merge it together with the low part. It is
0 commit comments