Skip to content

Commit 3f8d7da

Browse files
Simplify logic & check for legality of resulting concatenation
1 parent a0376ab commit 3f8d7da

File tree

1 file changed

+31
-69
lines changed

1 file changed

+31
-69
lines changed

llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerCombiner.cpp

Lines changed: 31 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -151,91 +151,53 @@ bool matchCombineBuildUnmerge(MachineInstr &MI, MachineRegisterInfo &MRI,
151151
Register &UnmergeSrc) {
152152
assert(MI.getOpcode() == TargetOpcode::G_BUILD_VECTOR);
153153

154-
unsigned UnmergeUseCount = 0;
155-
unsigned UndefInstrCount = 0;
154+
unsigned BuildUseCount = MI.getNumOperands() - 1;
156155

157-
unsigned UnmergeEltCount = 0;
158-
unsigned UnmergeEltSize = 0;
159-
160-
unsigned BuildOperandCount = MI.getNumOperands();
161-
bool EncounteredUndef = false;
156+
if (BuildUseCount % 2 != 0)
157+
return false;
162158

163-
Register UnmergeSrcTemp;
164-
MachineInstr *UnmergeInstr;
159+
unsigned HalfWayIndex = BuildUseCount / 2;
165160

166-
std::set<int> KnownRegs;
161+
// Check the first operand is an unmerge
162+
auto *MaybeUnmerge = getDefIgnoringCopies(MI.getOperand(1).getReg(), MRI);
163+
if (MaybeUnmerge->getOpcode() != TargetOpcode::G_UNMERGE_VALUES)
164+
return false;
167165

168-
for (auto &Use : MI.all_uses()) {
169-
auto *Def = getDefIgnoringCopies(Use.getReg(), MRI);
166+
// Check that the resultant concat will be legal
167+
auto UnmergeEltSize =
168+
MRI.getType(MaybeUnmerge->getOperand(1).getReg()).getScalarSizeInBits();
169+
auto UnmergeEltCount = MaybeUnmerge->getNumDefs();
170170

171-
if (!Def) {
172-
return false;
173-
}
171+
if (UnmergeEltCount < 2 || (UnmergeEltSize * UnmergeEltCount != 64 &&
172+
UnmergeEltSize * UnmergeEltCount != 128))
173+
return false;
174174

175-
unsigned Opcode = Def->getOpcode();
175+
// Check that all of the operands before the midpoint come from the same
176+
// unmerge and are in the same order as they are used in the build_vector
177+
for (unsigned I = 0; I < HalfWayIndex; ++I) {
178+
auto MaybeUnmergeReg = MI.getOperand(I + 1).getReg();
179+
auto *Unmerge = getDefIgnoringCopies(MaybeUnmergeReg, MRI);
176180

177-
// Ensure that the unmerged instructions are consecutive and before the
178-
// undefined values by checking we don't encounter an undef before we reach
179-
// half way
180-
if (EncounteredUndef && UnmergeUseCount < BuildOperandCount / 2)
181+
if (Unmerge != MaybeUnmerge)
181182
return false;
182183

183-
switch (Opcode) {
184-
default:
184+
if (Unmerge->getOperand(I).getReg() != MaybeUnmergeReg)
185185
return false;
186-
case TargetOpcode::G_IMPLICIT_DEF:
187-
++UndefInstrCount;
188-
EncounteredUndef = true;
189-
break;
190-
case TargetOpcode::G_UNMERGE_VALUES:
191-
++UnmergeUseCount;
192-
193-
UnmergeEltSize = MRI.getType(Use.getReg()).getScalarSizeInBits();
194-
UnmergeEltCount = Def->getNumDefs();
195-
if (UnmergeEltCount < 2 || (UnmergeEltSize * UnmergeEltCount != 64 &&
196-
UnmergeEltSize * UnmergeEltCount != 128)) {
197-
return false;
198-
}
199-
200-
// Unmerge should only use one register so we can use the last one
201-
for (auto &UnmergeUse : Def->all_uses())
202-
UnmergeSrcTemp = UnmergeUse.getReg();
203-
204-
// Track unique sources for the G_UNMERGE_VALUES
205-
unsigned RegId = UnmergeSrcTemp.id();
206-
if (KnownRegs.find(RegId) != KnownRegs.end())
207-
continue;
208-
209-
KnownRegs.insert(RegId);
210-
211-
// We know the unmerge is a valid target now so store the register & the
212-
// instruction.
213-
UnmergeSrc = UnmergeSrcTemp;
214-
UnmergeInstr = Def;
215-
216-
break;
217-
}
218186
}
219187

220-
// Only want to match patterns that pad half of a vector with undefined. We
221-
// also want to ensure that these values come from a single unmerge and all
222-
// unmerged values are consumed.
223-
if (UndefInstrCount != UnmergeUseCount ||
224-
UnmergeEltCount != UnmergeUseCount || KnownRegs.size() != 1) {
225-
return false;
226-
}
188+
// Check that all of the operands after the mid point are undefs.
189+
for (unsigned I = HalfWayIndex; I < BuildUseCount; ++I) {
190+
auto *Undef = getDefIgnoringCopies(MI.getOperand(I + 1).getReg(), MRI);
227191

228-
// Check the operands of the unmerge are used in the same order they are
229-
// defined G_BUILD_VECTOR always defines 1 output so we know the uses start
230-
// from index 1
231-
for (unsigned OperandIndex = 0; OperandIndex < UnmergeUseCount;
232-
++OperandIndex) {
233-
Register BuildReg = MI.getOperand(OperandIndex + 1).getReg();
234-
Register UnmergeReg = UnmergeInstr->getOperand(OperandIndex).getReg();
235-
if (BuildReg != UnmergeReg)
192+
if (Undef->getOpcode() != TargetOpcode::G_IMPLICIT_DEF)
236193
return false;
237194
}
238195

196+
// Unmerge should only use one register so we can use the last one
197+
for (auto &UnmergeUse :
198+
getDefIgnoringCopies(MI.getOperand(1).getReg(), MRI)->all_uses())
199+
UnmergeSrc = UnmergeUse.getReg();
200+
239201
return true;
240202
}
241203

0 commit comments

Comments
 (0)