@@ -144,20 +144,24 @@ bool isZeroExtended(Register R, MachineRegisterInfo &MRI) {
144144// )
145145// ->
146146// G_CONCAT_VECTORS(
147+ // src,
147148// undef
148- // src
149149// )
150150bool matchCombineBuildUnmerge (MachineInstr &MI, MachineRegisterInfo &MRI,
151151 Register &UnmergeSrc) {
152152 assert (MI.getOpcode () == TargetOpcode::G_BUILD_VECTOR);
153153
154- unsigned UnmergeInstrCount = 0 ;
154+ unsigned UnmergeUseCount = 0 ;
155155 unsigned UndefInstrCount = 0 ;
156156
157157 unsigned UnmergeEltCount = 0 ;
158158 unsigned UnmergeEltSize = 0 ;
159159
160+ unsigned BuildOperandCount = MI.getNumOperands ();
161+ bool EncounteredUndef = false ;
162+
160163 Register UnmergeSrcTemp;
164+ MachineInstr *UnmergeInstr;
161165
162166 std::set<int > KnownRegs;
163167
@@ -170,14 +174,21 @@ bool matchCombineBuildUnmerge(MachineInstr &MI, MachineRegisterInfo &MRI,
170174
171175 unsigned Opcode = Def->getOpcode ();
172176
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+ return false ;
182+
173183 switch (Opcode) {
174184 default :
175185 return false ;
176186 case TargetOpcode::G_IMPLICIT_DEF:
177187 ++UndefInstrCount;
188+ EncounteredUndef = true ;
178189 break ;
179190 case TargetOpcode::G_UNMERGE_VALUES:
180- ++UnmergeInstrCount ;
191+ ++UnmergeUseCount ;
181192
182193 UnmergeEltSize = MRI.getType (Use.getReg ()).getScalarSizeInBits ();
183194 UnmergeEltCount = Def->getNumDefs ();
@@ -197,8 +208,10 @@ bool matchCombineBuildUnmerge(MachineInstr &MI, MachineRegisterInfo &MRI,
197208
198209 KnownRegs.insert (RegId);
199210
200- // We know the unmerge is a valid target now so store the register.
211+ // We know the unmerge is a valid target now so store the register & the
212+ // instruction.
201213 UnmergeSrc = UnmergeSrcTemp;
214+ UnmergeInstr = Def;
202215
203216 break ;
204217 }
@@ -207,11 +220,22 @@ bool matchCombineBuildUnmerge(MachineInstr &MI, MachineRegisterInfo &MRI,
207220 // Only want to match patterns that pad half of a vector with undefined. We
208221 // also want to ensure that these values come from a single unmerge and all
209222 // unmerged values are consumed.
210- if (UndefInstrCount != UnmergeInstrCount ||
211- UnmergeEltCount != UnmergeInstrCount || KnownRegs.size () != 1 ) {
223+ if (UndefInstrCount != UnmergeUseCount ||
224+ UnmergeEltCount != UnmergeUseCount || KnownRegs.size () != 1 ) {
212225 return false ;
213226 }
214227
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)
236+ return false ;
237+ }
238+
215239 return true ;
216240}
217241
0 commit comments