[GlobalISel] Restrict G_MERGE_VALUES capability and replace with new opcodes.
This patch restricts the capability of G_MERGE_VALUES, and uses the new
G_BUILD_VECTOR and G_CONCAT_VECTORS opcodes instead in the appropriate places.
This patch also includes AArch64 support for selecting G_BUILD_VECTOR of <4 x s32>
and <2 x s64> vectors.
Differential Revisions: https://reviews.llvm.org/D53629
llvm-svn: 348788
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 7970dff..f4804e7 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -1055,6 +1055,32 @@
}
break;
}
+ case TargetOpcode::G_MERGE_VALUES: {
+ // G_MERGE_VALUES should only be used to merge scalars into a larger scalar,
+ // e.g. s2N = MERGE sN, sN
+ // Merging multiple scalars into a vector is not allowed, should use
+ // G_BUILD_VECTOR for that.
+ LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
+ LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
+ if (DstTy.isVector() || SrcTy.isVector())
+ report("G_MERGE_VALUES cannot operate on vectors", MI);
+ break;
+ }
+ case TargetOpcode::G_UNMERGE_VALUES: {
+ LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
+ LLT SrcTy = MRI->getType(MI->getOperand(MI->getNumOperands()-1).getReg());
+ // For now G_UNMERGE can split vectors.
+ for (unsigned i = 0; i < MI->getNumOperands()-1; ++i) {
+ if (MRI->getType(MI->getOperand(i).getReg()) != DstTy)
+ report("G_UNMERGE_VALUES destination types do not match", MI);
+ }
+ if (SrcTy.getSizeInBits() !=
+ (DstTy.getSizeInBits() * (MI->getNumOperands() - 1))) {
+ report("G_UNMERGE_VALUES source operand does not cover dest operands",
+ MI);
+ }
+ break;
+ }
case TargetOpcode::G_BUILD_VECTOR: {
// Source types must be scalars, dest type a vector. Total size of scalars
// must match the dest vector size.