1212// ===----------------------------------------------------------------------===//
1313
1414#include " llvm/CodeGen/GlobalISel/CallLowering.h"
15+ #include " llvm/ADT/STLExtras.h"
1516#include " llvm/CodeGen/Analysis.h"
1617#include " llvm/CodeGen/CallingConvLower.h"
1718#include " llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
2021#include " llvm/CodeGen/MachineOperand.h"
2122#include " llvm/CodeGen/MachineRegisterInfo.h"
2223#include " llvm/CodeGen/TargetLowering.h"
24+ #include " llvm/CodeGen/TargetOpcodes.h"
2325#include " llvm/IR/DataLayout.h"
2426#include " llvm/IR/LLVMContext.h"
2527#include " llvm/IR/Module.h"
28+ #include " llvm/Support/ErrorHandling.h"
2629#include " llvm/Target/TargetMachine.h"
2730
2831#define DEBUG_TYPE " call-lowering"
@@ -409,12 +412,12 @@ static void buildCopyFromRegs(MachineIRBuilder &B, ArrayRef<Register> OrigRegs,
409412 // Sometimes pointers are passed zero extended.
410413 LLT OrigTy = MRI.getType (OrigRegs[0 ]);
411414 if (OrigTy.isPointer ()) {
412- LLT IntPtrTy = LLT::scalar (OrigTy.getSizeInBits ());
415+ LLT IntPtrTy = LLT::integer (OrigTy.getSizeInBits ());
413416 B.buildIntToPtr (OrigRegs[0 ], B.buildTrunc (IntPtrTy, SrcReg));
414417 return ;
415418 }
416419
417- B.buildTrunc (OrigRegs[0 ], SrcReg);
420+ B.buildTruncLike (OrigRegs[0 ], SrcReg);
418421 return ;
419422 }
420423
@@ -423,11 +426,22 @@ static void buildCopyFromRegs(MachineIRBuilder &B, ArrayRef<Register> OrigRegs,
423426 LLT OrigTy = MRI.getType (OrigRegs[0 ]);
424427
425428 unsigned SrcSize = PartLLT.getSizeInBits ().getFixedValue () * Regs.size ();
426- if (SrcSize == OrigTy.getSizeInBits ())
427- B.buildMergeValues (OrigRegs[0 ], Regs);
428- else {
429- auto Widened = B.buildMergeLikeInstr (LLT::scalar (SrcSize), Regs);
430- B.buildTrunc (OrigRegs[0 ], Widened);
429+ if (SrcSize == OrigTy.getSizeInBits ()) {
430+ if (OrigTy.isFloat () && !PartLLT.isFloat ()) {
431+ auto Merge = B.buildMergeValues (OrigTy.changeToInteger (), Regs);
432+ B.buildBitcast (OrigRegs[0 ], Merge);
433+ } else if (!OrigTy.isFloat () && PartLLT.isFloat ()) {
434+ SmallVector<Register> CastRegs (Regs.size ());
435+ for (auto && [Idx, Reg]: enumerate(Regs))
436+ CastRegs[Idx] = B.buildBitcast (PartLLT.changeToInteger (), Reg).getReg (0 );
437+
438+ B.buildMergeValues (OrigRegs[0 ], CastRegs);
439+ } else {
440+ B.buildMergeValues (OrigRegs[0 ], Regs);
441+ }
442+ } else {
443+ auto Widened = B.buildMergeLikeInstr (LLT::integer (SrcSize), Regs);
444+ B.buildTruncLike (OrigRegs[0 ], Widened);
431445 }
432446
433447 return ;
@@ -492,19 +506,25 @@ static void buildCopyFromRegs(MachineIRBuilder &B, ArrayRef<Register> OrigRegs,
492506 SmallVector<Register, 8 > EltMerges;
493507 int PartsPerElt =
494508 divideCeil (DstEltTy.getSizeInBits (), PartLLT.getSizeInBits ());
495- LLT ExtendedPartTy = LLT::scalar (PartLLT.getSizeInBits () * PartsPerElt);
509+ LLT ExtendedPartTy = LLT::integer (PartLLT.getSizeInBits () * PartsPerElt);
496510
497511 for (int I = 0 , NumElts = LLTy.getNumElements (); I != NumElts; ++I) {
498512 auto Merge =
499513 B.buildMergeLikeInstr (ExtendedPartTy, Regs.take_front (PartsPerElt));
500514 if (ExtendedPartTy.getSizeInBits () > RealDstEltTy.getSizeInBits ())
501- Merge = B.buildTrunc (RealDstEltTy, Merge);
515+ Merge = B.buildTruncLike (RealDstEltTy, Merge);
502516 // Fix the type in case this is really a vector of pointers.
503- MRI.setType (Merge.getReg (0 ), RealDstEltTy);
504- EltMerges.push_back (Merge.getReg (0 ));
517+ Register MergeReg = Merge.getReg (0 );
518+
519+ if (RealDstEltTy.isPointer ()) {
520+ MRI.setType (MergeReg, RealDstEltTy);
521+ } else if (RealDstEltTy.isFloat () &&
522+ !MRI.getType (MergeReg).getScalarType ().isFloat ()) {
523+ MergeReg = B.buildBitcast (RealDstEltTy, MergeReg).getReg (0 );
524+ }
525+ EltMerges.push_back (MergeReg);
505526 Regs = Regs.drop_front (PartsPerElt);
506527 }
507-
508528 B.buildBuildVector (OrigRegs[0 ], EltMerges);
509529 } else {
510530 // Vector was split, and elements promoted to a wider type.
@@ -532,9 +552,12 @@ static void buildCopyFromRegs(MachineIRBuilder &B, ArrayRef<Register> OrigRegs,
532552 SmallVector<Register, 0 > BVRegs;
533553 BVRegs.reserve (Regs.size () * EltPerReg);
534554 for (Register R : Regs) {
535- auto Unmerge = B.buildUnmerge (OriginalEltTy, R);
536- for (unsigned K = 0 ; K < EltPerReg; ++K)
537- BVRegs.push_back (B.buildAnyExt (PartLLT, Unmerge.getReg (K)).getReg (0 ));
555+ auto Unmerge = B.buildUnmerge (OriginalEltTy.changeToInteger (), R);
556+ for (unsigned K = 0 ; K < EltPerReg; ++K) {
557+ Register BVreg;
558+ BVreg = B.buildAnyExt (PartLLT, Unmerge.getReg (K)).getReg (0 );
559+ BVRegs.push_back (BVreg);
560+ }
538561 }
539562
540563 // We may have some more elements in BVRegs, e.g. if we have 2 s32 pieces
@@ -545,7 +568,8 @@ static void buildCopyFromRegs(MachineIRBuilder &B, ArrayRef<Register> OrigRegs,
545568 }
546569 BuildVec = B.buildBuildVector (BVType, BVRegs).getReg (0 );
547570 }
548- B.buildTrunc (OrigRegs[0 ], BuildVec);
571+
572+ B.buildTruncLike (OrigRegs[0 ], BuildVec);
549573 }
550574}
551575
@@ -565,6 +589,8 @@ static void buildCopyToRegs(MachineIRBuilder &B, ArrayRef<Register> DstRegs,
565589 if (PartTy.isVector () == SrcTy.isVector () &&
566590 PartTy.getScalarSizeInBits () > SrcTy.getScalarSizeInBits ()) {
567591 assert (DstRegs.size () == 1 );
592+ if (PartTy.getScalarType ().isFloat () && SrcTy.getScalarType ().isFloat ())
593+ ExtendOp = TargetOpcode::G_FPEXT;
568594 B.buildInstr (ExtendOp, {DstRegs[0 ]}, {SrcReg});
569595 return ;
570596 }
@@ -573,8 +599,18 @@ static void buildCopyToRegs(MachineIRBuilder &B, ArrayRef<Register> DstRegs,
573599 TypeSize::isKnownGT (PartSize, SrcTy.getElementType ().getSizeInBits ())) {
574600 // Vector was scalarized, and the elements extended.
575601 auto UnmergeToEltTy = B.buildUnmerge (SrcTy.getElementType (), SrcReg);
576- for (int i = 0 , e = DstRegs.size (); i != e; ++i)
577- B.buildAnyExt (DstRegs[i], UnmergeToEltTy.getReg (i));
602+ for (int i = 0 , e = DstRegs.size (); i != e; ++i) {
603+ Register Unmerge = UnmergeToEltTy.getReg (i);
604+ if (SrcTy.isFloatVector () && PartTy.isFloat ()) {
605+ B.buildFPExt (DstRegs[i], Unmerge);
606+ continue ;
607+ }
608+
609+ if (SrcTy.isFloatVector () && !PartTy.isFloat ())
610+ Unmerge = B.buildBitcast (SrcTy.getElementType ().changeToInteger (), Unmerge).getReg (0 );
611+
612+ B.buildAnyExt (DstRegs[i], Unmerge);
613+ }
578614 return ;
579615 }
580616
@@ -590,6 +626,9 @@ static void buildCopyToRegs(MachineIRBuilder &B, ArrayRef<Register> DstRegs,
590626
591627 LLT GCDTy = getGCDType (SrcTy, PartTy);
592628 if (GCDTy == PartTy) {
629+ if (SrcTy.getScalarType ().isFloat () && !PartTy.getScalarType ().isFloat ())
630+ SrcReg = B.buildBitcast (SrcTy.changeToInteger (), SrcReg).getReg (0 );
631+
593632 // If this already evenly divisible, we can create a simple unmerge.
594633 B.buildUnmerge (DstRegs, SrcReg);
595634 return ;
@@ -599,8 +638,11 @@ static void buildCopyToRegs(MachineIRBuilder &B, ArrayRef<Register> DstRegs,
599638 SrcTy.getScalarSizeInBits () > PartTy.getSizeInBits ()) {
600639 LLT ExtTy =
601640 LLT::vector (SrcTy.getElementCount (),
602- LLT::scalar (PartTy.getScalarSizeInBits () * DstRegs.size () /
603- SrcTy.getNumElements ()));
641+ LLT::integer (PartTy.getScalarSizeInBits () * DstRegs.size () /
642+ SrcTy.getNumElements ()));
643+ if (SrcTy.isFloatVector ())
644+ SrcReg = B.buildBitcast (SrcTy.changeToInteger (), SrcReg).getReg (0 );
645+
604646 auto Ext = B.buildAnyExt (ExtTy, SrcReg);
605647 B.buildUnmerge (DstRegs, Ext);
606648 return ;
@@ -626,7 +668,7 @@ static void buildCopyToRegs(MachineIRBuilder &B, ArrayRef<Register> DstRegs,
626668 // For scalars, it's common to be able to use a simple extension.
627669 if (SrcTy.isScalar () && DstTy.isScalar ()) {
628670 CoveringSize = alignTo (SrcSize, DstSize);
629- LLT CoverTy = LLT::scalar (CoveringSize);
671+ LLT CoverTy = LLT::integer (CoveringSize);
630672 UnmergeSrc = B.buildInstr (ExtendOp, {CoverTy}, {SrcReg}).getReg (0 );
631673 } else {
632674 // Widen to the common type.
@@ -822,8 +864,9 @@ bool CallLowering::handleAssignments(ValueHandler &Handler,
822864 if (!Handler.isIncomingArgumentHandler () && OrigTy != ValTy &&
823865 VA.getLocInfo () != CCValAssign::Indirect) {
824866 assert (Args[i].OrigRegs .size () == 1 );
867+ unsigned ExtendOp = extendOpFromFlags (Args[i].Flags [0 ]);
825868 buildCopyToRegs (MIRBuilder, Args[i].Regs , Args[i].OrigRegs [0 ], OrigTy,
826- ValTy, extendOpFromFlags (Args[i]. Flags [ 0 ]) );
869+ ValTy, ExtendOp );
827870 }
828871
829872 bool IndirectParameterPassingHandled = false ;
0 commit comments