forked from OSchip/llvm-project
[MachineIRBuilder] Fix an assertion failure with buildMerge
Teach buildMerge how to deal with scalar to vector kind of requests. Prior to this patch, buildMerge would issue either a G_MERGE_VALUES when all the vregs are scalars or a G_CONCAT_VECTORS when the destination vreg is a vector. G_CONCAT_VECTORS was actually not the proper instruction when the source vregs were scalars and the compiler would assert that the sources must be vectors. Instead we want is to issue a G_BUILD_VECTOR when we are in this situation. This patch fixes that. llvm-svn: 374588
This commit is contained in:
parent
03fbde6d84
commit
7720f11498
|
@ -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: {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue