GlobalISel: Implement fewerElementsVector for phi

llvm-svn: 355048
diff --git a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
index 2e4cd06..67b897f 100644
--- a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
+++ b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
@@ -635,4 +635,98 @@
 
   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
 }
+
+TEST_F(GISelMITest, FewerElementsPhi) {
+  if (!TM)
+    return;
+
+  LLT s1 = LLT::scalar(1);
+  LLT s32 = LLT::scalar(32);
+  LLT s64 = LLT::scalar(64);
+  LLT v2s32 = LLT::vector(2, 32);
+  LLT v5s32 = LLT::vector(5, 32);
+
+  LegalizerInfo LI;
+  LI.getActionDefinitionsBuilder(TargetOpcode::G_PHI)
+    .legalFor({v2s32})
+    .clampMinNumElements(0, s32, 2);
+  LI.computeTables();
+
+  LLT PhiTy = v5s32;
+  DummyGISelObserver Observer;
+  LegalizerHelper Helper(*MF, LI, Observer, B);
+  B.setMBB(*EntryMBB);
+
+  MachineBasicBlock *MidMBB = MF->CreateMachineBasicBlock();
+  MachineBasicBlock *EndMBB = MF->CreateMachineBasicBlock();
+  MF->insert(MF->end(), MidMBB);
+  MF->insert(MF->end(), EndMBB);
+
+  EntryMBB->addSuccessor(MidMBB);
+  EntryMBB->addSuccessor(EndMBB);
+  MidMBB->addSuccessor(EndMBB);
+
+  auto InitVal = B.buildUndef(PhiTy);
+  auto InitOtherVal = B.buildConstant(s64, 999);
+
+  auto ICmp = B.buildICmp(CmpInst::ICMP_EQ, s1, Copies[0], Copies[1]);
+  B.buildBrCond(ICmp.getReg(0), *MidMBB);
+  B.buildBr(*EndMBB);
+
+
+  B.setMBB(*MidMBB);
+  auto MidVal = B.buildUndef(PhiTy);
+  auto MidOtherVal = B.buildConstant(s64, 345);
+  B.buildBr(*EndMBB);
+
+  B.setMBB(*EndMBB);
+  auto Phi = B.buildInstr(TargetOpcode::G_PHI)
+    .addDef(MRI->createGenericVirtualRegister(PhiTy))
+    .addUse(InitVal.getReg(0))
+    .addMBB(EntryMBB)
+    .addUse(MidVal.getReg(0))
+    .addMBB(MidMBB);
+
+  // Insert another irrelevant phi to make sure the rebuild is inserted after
+  // it.
+  B.buildInstr(TargetOpcode::G_PHI)
+    .addDef(MRI->createGenericVirtualRegister(s64))
+    .addUse(InitOtherVal.getReg(0))
+    .addMBB(EntryMBB)
+    .addUse(MidOtherVal.getReg(0))
+    .addMBB(MidMBB);
+
+  // Add some use instruction after the phis.
+  B.buildAnd(PhiTy, Phi.getReg(0), Phi.getReg(0));
+
+  EXPECT_EQ(LegalizerHelper::LegalizeResult::Legalized,
+            Helper.fewerElementsVector(*Phi, 0, v2s32));
+
+  auto CheckStr = R"(
+  CHECK: [[INITVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+  CHECK: [[EXTRACT0:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[INITVAL]]:_(<5 x s32>), 0
+  CHECK: [[EXTRACT1:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[INITVAL]]:_(<5 x s32>), 64
+  CHECK: [[EXTRACT2:%[0-9]+]]:_(s32) = G_EXTRACT [[INITVAL]]:_(<5 x s32>), 128
+  CHECK: G_BRCOND
+
+  CHECK: [[MIDVAL:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+  CHECK: [[EXTRACT3:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[MIDVAL]]:_(<5 x s32>), 0
+  CHECK: [[EXTRACT4:%[0-9]+]]:_(<2 x s32>) = G_EXTRACT [[MIDVAL]]:_(<5 x s32>), 64
+  CHECK: [[EXTRACT5:%[0-9]+]]:_(s32) = G_EXTRACT [[MIDVAL]]:_(<5 x s32>), 128
+  CHECK: G_BR
+
+  CHECK: [[PHI0:%[0-9]+]]:_(<2 x s32>) = G_PHI [[EXTRACT0]]:_(<2 x s32>), %bb.0, [[EXTRACT3]]:_(<2 x s32>), %bb.1
+  CHECK: [[PHI1:%[0-9]+]]:_(<2 x s32>) = G_PHI [[EXTRACT1]]:_(<2 x s32>), %bb.0, [[EXTRACT4]]:_(<2 x s32>), %bb.1
+  CHECK: [[PHI2:%[0-9]+]]:_(s32) = G_PHI [[EXTRACT2]]:_(s32), %bb.0, [[EXTRACT5]]:_(s32), %bb.1
+
+  CHECK: [[OTHER_PHI:%[0-9]+]]:_(s64) = G_PHI
+  CHECK: [[REBUILD_VAL_IMPDEF:%[0-9]+]]:_(<5 x s32>) = G_IMPLICIT_DEF
+  CHECK: [[INSERT0:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[REBUILD_VAL_IMPDEF]]:_, [[PHI0]]:_(<2 x s32>), 0
+  CHECK: [[INSERT1:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[INSERT0]]:_, [[PHI1]]:_(<2 x s32>), 64
+  CHECK: [[INSERT2:%[0-9]+]]:_(<5 x s32>) = G_INSERT [[INSERT1]]:_, [[PHI2]]:_(s32), 128
+  CHECK: [[USE_OP:%[0-9]+]]:_(<5 x s32>) = G_AND [[INSERT2]]:_, [[INSERT2]]:_
+  )";
+
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
 } // namespace