2727#include " llvm/CodeGen/TargetOpcodes.h"
2828#include " llvm/IR/Constants.h"
2929#include " llvm/IR/DebugInfoMetadata.h"
30+ #include " llvm/MC/TargetRegistry.h"
3031#include " llvm/Support/Debug.h"
3132
3233#define DEBUG_TYPE " legalizer"
@@ -44,6 +45,7 @@ class LegalizationArtifactCombiner {
4445 case TargetOpcode::G_SEXT:
4546 case TargetOpcode::G_ZEXT:
4647 case TargetOpcode::G_ANYEXT:
48+ case TargetOpcode::G_BITCAST:
4749 return true ;
4850 default :
4951 return false ;
@@ -507,6 +509,53 @@ class LegalizationArtifactCombiner {
507509 markInstAndDefDead (MI, CastMI, DeadInsts);
508510 return true ;
509511 }
512+ } else if (CastOpc == TargetOpcode::G_BITCAST) {
513+
514+ // %1:_(<2 x i32>) = G_BITCAST %0(<2 x f32>)
515+ // %2:_(i16), %3:_(i16), %4:_(i16), %5:_(i16) = G_UNMERGE_VALUES %1
516+ // =>
517+ // %6:_(f32), %7:_(f32) = G_UNMERGE_VALUES %0
518+ // %8:_(i32) = G_BITCAST %6
519+ // %2:_(i16), %3:_(i16) = G_UNMERGE_VALUES %8
520+ // %9:_(i32) = G_BITCAST %7
521+ // %4:_(i16), %5:_(i16) = G_UNMERGE_VALUES %9
522+
523+ if (CastSrcTy.isScalar () || SrcTy.isScalar () || DestTy.isVector () || DestTy == SrcTy.getScalarType ())
524+ return false ;
525+
526+ const unsigned NewNumDefs1 = CastSrcTy.getNumElements ();
527+ const unsigned NewNumDefs2 = NumDefs / NewNumDefs1;
528+
529+ if (NewNumDefs2 <= 1 )
530+ return false ;
531+
532+ SmallVector<Register, 8 > NewUnmergeRegs (NewNumDefs1);
533+ for (unsigned Idx = 0 ; Idx < NewNumDefs1; ++Idx)
534+ NewUnmergeRegs[Idx] = MRI.createGenericVirtualRegister (CastSrcTy.getElementType ());
535+
536+ Builder.setInstr (MI);
537+ auto NewUnmerge = Builder.buildUnmerge (NewUnmergeRegs, CastSrcReg);
538+
539+
540+ SmallVector<Register, 8 > DstRegs (NumDefs);
541+ for (unsigned Idx = 0 ; Idx < NumDefs; ++Idx)
542+ DstRegs[Idx] = MI.getOperand (Idx).getReg ();
543+
544+
545+ auto * It = DstRegs.begin ();
546+
547+ for (auto & Def : NewUnmerge->all_defs ()) {
548+ auto Bitcast = Builder.buildBitcast (SrcTy.getElementType (), Def);
549+ auto * Begin = It;
550+ It += NewNumDefs2;
551+ ArrayRef Regs (Begin, It);
552+ Builder.buildUnmerge (Regs, Bitcast);
553+ }
554+
555+ UpdatedDefs.append (NewUnmergeRegs.begin (), NewUnmergeRegs.end ());
556+ UpdatedDefs.append (DstRegs.begin (), DstRegs.end ());
557+ markInstAndDefDead (MI, CastMI, DeadInsts);
558+ return true ;
510559 }
511560
512561 // TODO: support combines with other casts as well
@@ -1165,8 +1214,9 @@ class LegalizationArtifactCombiner {
11651214 ++j, ++DefIdx)
11661215 DstRegs.push_back (MI.getReg (DefIdx));
11671216
1168- if (ConvertOp) {
1169- LLT MergeDstTy = MRI.getType (SrcDef->getOperand (0 ).getReg ());
1217+ LLT MergeDstTy = MRI.getType (SrcDef->getOperand (0 ).getReg ());
1218+
1219+ if (ConvertOp && DestTy != MergeDstTy) {
11701220
11711221 // This is a vector that is being split and casted. Extract to the
11721222 // element type, and do the conversion on the scalars (or smaller
@@ -1187,6 +1237,7 @@ class LegalizationArtifactCombiner {
11871237 // %7(<2 x s16>), %7(<2 x s16>) = G_UNMERGE_VALUES %9
11881238
11891239 Register TmpReg = MRI.createGenericVirtualRegister (MergeEltTy);
1240+ assert (MRI.getType (TmpReg) != MRI.getType (MergeI->getOperand (Idx + 1 ).getReg ()));
11901241 Builder.buildInstr (ConvertOp, {TmpReg},
11911242 {MergeI->getOperand (Idx + 1 ).getReg ()});
11921243 Builder.buildUnmerge (DstRegs, TmpReg);
@@ -1232,14 +1283,15 @@ class LegalizationArtifactCombiner {
12321283 ConvertOp = TargetOpcode::G_BITCAST;
12331284 }
12341285
1235- if (ConvertOp) {
1286+ if (ConvertOp && DestTy != MergeSrcTy ) {
12361287 Builder.setInstr (MI);
12371288
12381289 for (unsigned Idx = 0 ; Idx < NumDefs; ++Idx) {
12391290 Register DefReg = MI.getOperand (Idx).getReg ();
12401291 Register MergeSrc = MergeI->getOperand (Idx + 1 ).getReg ();
12411292
12421293 if (!MRI.use_empty (DefReg)) {
1294+ assert (MRI.getType (DefReg) != MRI.getType (MergeSrc));
12431295 Builder.buildInstr (ConvertOp, {DefReg}, {MergeSrc});
12441296 UpdatedDefs.push_back (DefReg);
12451297 }
@@ -1398,6 +1450,7 @@ class LegalizationArtifactCombiner {
13981450 case TargetOpcode::G_EXTRACT:
13991451 case TargetOpcode::G_TRUNC:
14001452 case TargetOpcode::G_BUILD_VECTOR:
1453+ case TargetOpcode::G_BITCAST:
14011454 // Adding Use to ArtifactList.
14021455 WrapperObserver.changedInstr (Use);
14031456 break ;
@@ -1425,6 +1478,7 @@ class LegalizationArtifactCombiner {
14251478 static Register getArtifactSrcReg (const MachineInstr &MI) {
14261479 switch (MI.getOpcode ()) {
14271480 case TargetOpcode::COPY:
1481+ case TargetOpcode::G_BITCAST:
14281482 case TargetOpcode::G_TRUNC:
14291483 case TargetOpcode::G_ZEXT:
14301484 case TargetOpcode::G_ANYEXT:
0 commit comments