GlobalISel: Have lowerLoad scalarize unaligned vectors
This could be smarter by picking an ideal type, or at least splitting
the vector in half first. Also handles lower for non-power-of-2,
non-extending vector loads.
Currently this just avoids failing to legalize some odd vector AMDGPU
tests, but is a step towards removing the split logic from the
NarrowScalar logic.
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 4dddb98..074e5e6 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -2886,13 +2886,14 @@
MachineMemOperand &MMO = LoadMI.getMMO();
LLT MemTy = MMO.getMemoryType();
MachineFunction &MF = MIRBuilder.getMF();
- if (MemTy.isVector())
- return UnableToLegalize;
unsigned MemSizeInBits = MemTy.getSizeInBits();
unsigned MemStoreSizeInBits = 8 * MemTy.getSizeInBytes();
if (MemSizeInBits != MemStoreSizeInBits) {
+ if (MemTy.isVector())
+ return UnableToLegalize;
+
// Promote to a byte-sized load if not loading an integral number of
// bytes. For example, promote EXTLOAD:i20 -> EXTLOAD:i24.
LLT WideMemTy = LLT::scalar(MemStoreSizeInBits);
@@ -2928,9 +2929,6 @@
return Legalized;
}
- if (DstTy.isVector())
- return UnableToLegalize;
-
// Big endian lowering not implemented.
if (MIRBuilder.getDataLayout().isBigEndian())
return UnableToLegalize;
@@ -2953,9 +2951,12 @@
uint64_t LargeSplitSize, SmallSplitSize;
if (!isPowerOf2_32(MemSizeInBits)) {
+ // This load needs splitting into power of 2 sized loads.
LargeSplitSize = PowerOf2Floor(MemSizeInBits);
SmallSplitSize = MemSizeInBits - LargeSplitSize;
} else {
+ // This is already a power of 2, but we still need to split this in half.
+ //
// Assume we're being asked to decompose an unaligned load.
// TODO: If this requires multiple splits, handle them all at once.
auto &Ctx = MF.getFunction().getContext();
@@ -2965,6 +2966,16 @@
SmallSplitSize = LargeSplitSize = MemSizeInBits / 2;
}
+ if (MemTy.isVector()) {
+ // TODO: Handle vector extloads
+ if (MemTy != DstTy)
+ return UnableToLegalize;
+
+ // TODO: We can do better than scalarizing the vector and at least split it
+ // in half.
+ return reduceLoadStoreWidth(LoadMI, 0, DstTy.getElementType());
+ }
+
MachineMemOperand *LargeMMO =
MF.getMachineMemOperand(&MMO, 0, LargeSplitSize / 8);
MachineMemOperand *SmallMMO =