@@ -239,45 +239,67 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner {
239
239
// / uses of V and only keep uses of ~V.
240
240
// /
241
241
// / See also: canFreelyInvertAllUsersOf()
242
- static bool isFreeToInvert (Value *V, bool WillInvertAllUses) {
242
+ static bool isFreeToInvertImpl (Value *V, bool WillInvertAllUses,
243
+ bool &DoesConsume, unsigned Depth) {
244
+ using namespace llvm ::PatternMatch;
243
245
// ~(~(X)) -> X.
244
- if (match (V, m_Not (PatternMatch::m_Value ())))
246
+ if (match (V, m_Not (m_Value ()))) {
247
+ DoesConsume = true ;
245
248
return true ;
249
+ }
246
250
247
251
// Constants can be considered to be not'ed values.
248
- if (match (V, PatternMatch:: m_AnyIntegralConstant ()))
252
+ if (match (V, m_AnyIntegralConstant ()))
249
253
return true ;
250
254
255
+ if (Depth++ >= MaxAnalysisRecursionDepth)
256
+ return false ;
257
+
258
+ // The rest of the cases require that we invert all uses so don't bother
259
+ // doing the analysis if we know we can't use the result.
260
+ if (!WillInvertAllUses)
261
+ return false ;
262
+
251
263
// Compares can be inverted if all of their uses are being modified to use
252
264
// the ~V.
253
265
if (isa<CmpInst>(V))
254
- return WillInvertAllUses;
255
-
256
- // If `V` is of the form `A + Constant` then `-1 - V` can be folded into
257
- // `(-1 - Constant) - A` if we are willing to invert all of the uses.
258
- if (match (V, m_Add (PatternMatch::m_Value (), PatternMatch::m_ImmConstant ())))
259
- return WillInvertAllUses;
260
-
261
- // If `V` is of the form `Constant - A` then `-1 - V` can be folded into
262
- // `A + (-1 - Constant)` if we are willing to invert all of the uses.
263
- if (match (V, m_Sub (PatternMatch::m_ImmConstant (), PatternMatch::m_Value ())))
264
- return WillInvertAllUses;
265
-
266
- // Selects with invertible operands are freely invertible
267
- if (match (V,
268
- m_Select (PatternMatch::m_Value (), m_Not (PatternMatch::m_Value ()),
269
- m_Not (PatternMatch::m_Value ()))))
270
- return WillInvertAllUses;
271
-
272
- // Min/max may be in the form of intrinsics, so handle those identically
273
- // to select patterns.
274
- if (match (V, m_MaxOrMin (m_Not (PatternMatch::m_Value ()),
275
- m_Not (PatternMatch::m_Value ()))))
276
- return WillInvertAllUses;
266
+ return true ;
267
+
268
+ Value *A, *B;
269
+ // If `V` is of the form `A + B` then `-1 - V` can be folded into
270
+ // `~B - A` or `~A - B` if we are willing to invert all of the uses.
271
+ if (match (V, m_Add (m_Value (A), m_Value (B))))
272
+ return isFreeToInvertImpl (A, A->hasOneUse (), DoesConsume, Depth) ||
273
+ isFreeToInvertImpl (B, B->hasOneUse (), DoesConsume, Depth);
274
+
275
+ // If `V` is of the form `A - B` then `-1 - V` can be folded into
276
+ // `~A + B` if we are willing to invert all of the uses.
277
+ if (match (V, m_Sub (m_Value (A), m_Value ())))
278
+ return isFreeToInvertImpl (A, A->hasOneUse (), DoesConsume, Depth);
279
+
280
+ // LogicOps are special in that we canonicalize them at the cost of an
281
+ // instruction.
282
+ bool IsSelect = match (V, m_Select (m_Value (), m_Value (A), m_Value (B))) &&
283
+ !shouldAvoidAbsorbingNotIntoSelect (*cast<SelectInst>(V));
284
+ // Selects/min/max with invertible operands are freely invertible
285
+ if (IsSelect || match (V, m_MaxOrMin (m_Value (A), m_Value (B))))
286
+ return isFreeToInvertImpl (A, A->hasOneUse (), DoesConsume, Depth) &&
287
+ isFreeToInvertImpl (B, B->hasOneUse (), DoesConsume, Depth);
277
288
278
289
return false ;
279
290
}
280
291
292
+ static bool isFreeToInvert (Value *V, bool WillInvertAllUses,
293
+ bool &DoesConsume) {
294
+ DoesConsume = false ;
295
+ return isFreeToInvertImpl (V, WillInvertAllUses, DoesConsume, /* Depth*/ 0 );
296
+ }
297
+
298
+ static bool isFreeToInvert (Value *V, bool WillInvertAllUses) {
299
+ bool Unused;
300
+ return isFreeToInvert (V, WillInvertAllUses, Unused);
301
+ }
302
+
281
303
// / Given i1 V, can every user of V be freely adapted if V is changed to !V ?
282
304
// / InstCombine's freelyInvertAllUsersOf() must be kept in sync with this fn.
283
305
// / NOTE: for Instructions only!
0 commit comments