diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp index 8a96a900aa08..9bbff490ea36 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -1063,8 +1063,11 @@ MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opc, "input operands do not cover output register"); if (SrcOps.size() == 1) return buildCast(DstOps[0], SrcOps[0]); - if (DstOps[0].getLLTTy(*getMRI()).isVector()) - return buildInstr(TargetOpcode::G_CONCAT_VECTORS, DstOps, SrcOps); + if (DstOps[0].getLLTTy(*getMRI()).isVector()) { + if (SrcOps[0].getLLTTy(*getMRI()).isVector()) + return buildInstr(TargetOpcode::G_CONCAT_VECTORS, DstOps, SrcOps); + return buildInstr(TargetOpcode::G_BUILD_VECTOR, DstOps, SrcOps); + } break; } case TargetOpcode::G_EXTRACT_VECTOR_ELT: { diff --git a/llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp b/llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp index 72a85db9461d..f39c28dc6485 100644 --- a/llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp @@ -314,3 +314,42 @@ TEST_F(GISelMITest, BuildAtomicRMW) { EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; } + +TEST_F(GISelMITest, BuildMerge) { + setUp(); + if (!TM) + return; + + LLT S32 = LLT::scalar(32); + Register RegC0 = B.buildConstant(S32, 0)->getOperand(0).getReg(); + Register RegC1 = B.buildConstant(S32, 1)->getOperand(0).getReg(); + Register RegC2 = B.buildConstant(S32, 2)->getOperand(0).getReg(); + Register RegC3 = B.buildConstant(S32, 3)->getOperand(0).getReg(); + + // Merging plain constants as one big blob of bit should produce a + // G_MERGE_VALUES. + B.buildMerge(LLT::scalar(128), {RegC0, RegC1, RegC2, RegC3}); + // Merging plain constants to a vector should produce a G_BUILD_VECTOR. + LLT V2x32 = LLT::vector(2, 32); + Register RegC0C1 = + B.buildMerge(V2x32, {RegC0, RegC1})->getOperand(0).getReg(); + Register RegC2C3 = + B.buildMerge(V2x32, {RegC2, RegC3})->getOperand(0).getReg(); + // Merging vector constants to a vector should produce a G_CONCAT_VECTORS. + B.buildMerge(LLT::vector(4, 32), {RegC0C1, RegC2C3}); + // Merging vector constants to a plain type is not allowed. + // Nothing else to test. + + auto CheckStr = R"( + ; CHECK: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 + ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 + ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2 + ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3 + ; CHECK: {{%[0-9]+}}:_(s128) = G_MERGE_VALUES [[C0]]:_(s32), [[C1]]:_(s32), [[C2]]:_(s32), [[C3]]:_(s32) + ; CHECK: [[LOW2x32:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C0]]:_(s32), [[C1]]:_(s32) + ; CHECK: [[HIGH2x32:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C2]]:_(s32), [[C3]]:_(s32) + ; CHECK: {{%[0-9]+}}:_(<4 x s32>) = G_CONCAT_VECTORS [[LOW2x32]]:_(<2 x s32>), [[HIGH2x32]]:_(<2 x s32>) + )"; + + EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF; +}