@@ -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