34
34
#include " llvm/IR/IntrinsicInst.h"
35
35
#include " llvm/IR/Operator.h"
36
36
#include " llvm/IR/PassManager.h"
37
+ #include " llvm/IR/PatternMatch.h"
37
38
#include " llvm/IR/Type.h"
38
39
#include " llvm/IR/Value.h"
39
40
#include " llvm/Support/Casting.h"
44
45
#include < utility>
45
46
46
47
using namespace llvm ;
48
+ using namespace llvm ::PatternMatch;
47
49
48
50
#define DEBUG_TYPE " correlated-value-propagation"
49
51
@@ -285,7 +287,41 @@ static bool processPHI(PHINode *P, LazyValueInfo *LVI, DominatorTree *DT,
285
287
return Changed;
286
288
}
287
289
290
+ // / Given an icmp `icmp eq X, C`,
291
+ // / if we already know that C is 2k+1 and X is in [2k, 2k+1],
292
+ // / then we can fold it to `trunc X to i1`.
293
+ static bool processEqualityICmp (ICmpInst *Cmp, LazyValueInfo *LVI) {
294
+ if (Cmp->getType ()->isVectorTy () ||
295
+ !Cmp->getOperand (0 )->getType ()->isIntegerTy () || !Cmp->isEquality ())
296
+ return false ;
297
+
298
+ Value *Op0 = Cmp->getOperand (0 );
299
+ const APInt *RHSC;
300
+ if (!match (Cmp->getOperand (1 ), m_APInt (RHSC)))
301
+ return false ;
302
+
303
+ ConstantRange Range =
304
+ LVI->getConstantRangeAtUse (Cmp->getOperandUse (0 ), /* UndefAllowed*/ true );
305
+ APInt RangeSize = Range.getUpper () - Range.getLower ();
306
+ if (RangeSize != 2 || !Range.contains (*RHSC))
307
+ return false ;
308
+
309
+ bool ShouldBeOdd = Cmp->getPredicate () == ICmpInst::Predicate::ICMP_EQ;
310
+ if ((*RHSC)[0 ] == ShouldBeOdd) {
311
+ IRBuilder<> B{Cmp};
312
+ Value *Trunc = B.CreateTrunc (Op0, Cmp->getType ());
313
+ Cmp->replaceAllUsesWith (Trunc);
314
+ Cmp->eraseFromParent ();
315
+ return true ;
316
+ }
317
+
318
+ return false ;
319
+ }
320
+
288
321
static bool processICmp (ICmpInst *Cmp, LazyValueInfo *LVI) {
322
+ if (processEqualityICmp (Cmp, LVI))
323
+ return true ;
324
+
289
325
// Only for signed relational comparisons of scalar integers.
290
326
if (Cmp->getType ()->isVectorTy () ||
291
327
!Cmp->getOperand (0 )->getType ()->isIntegerTy ())
@@ -332,39 +368,6 @@ static bool constantFoldCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
332
368
return true ;
333
369
}
334
370
335
- // / Given an icmp `icmp eq X, C`,
336
- // / if we already know that C is 2k+1 and X is in [2k, 2k+1],
337
- // / then we can fold it to `trunc X to i1`.
338
- static bool processEqualityICmp (CmpInst *Cmp, LazyValueInfo *LVI) {
339
- if (Cmp->getType ()->isVectorTy () ||
340
- !Cmp->getOperand (0 )->getType ()->isIntegerTy () || !Cmp->isEquality ())
341
- return false ;
342
-
343
- Value *Op0 = Cmp->getOperand (0 );
344
- Value *Op1 = Cmp->getOperand (1 );
345
- ConstantInt *CI = dyn_cast<ConstantInt>(Op1);
346
- if (!CI)
347
- return false ;
348
-
349
- ConstantRange Range =
350
- LVI->getConstantRangeAtUse (Cmp->getOperandUse (0 ), /* UndefAllowed*/ true );
351
- APInt RangeSize = Range.getUpper () - Range.getLower ();
352
- APInt Value = CI->getValue ();
353
- if (RangeSize != 2 || !Range.contains (Value))
354
- return false ;
355
-
356
- bool ShouldBeOdd = Cmp->getPredicate () == ICmpInst::Predicate::ICMP_EQ;
357
- if ((CI->getValue () & 1 ) == ShouldBeOdd) {
358
- IRBuilder<> B{Cmp};
359
- auto *Trunc = B.CreateTruncOrBitCast (Op0, Cmp->getType ());
360
- Cmp->replaceAllUsesWith (Trunc);
361
- Cmp->eraseFromParent ();
362
- return true ;
363
- }
364
-
365
- return false ;
366
- }
367
-
368
371
static bool processCmp (CmpInst *Cmp, LazyValueInfo *LVI) {
369
372
if (constantFoldCmp (Cmp, LVI))
370
373
return true ;
@@ -373,9 +376,6 @@ static bool processCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
373
376
if (processICmp (ICmp, LVI))
374
377
return true ;
375
378
376
- if (processEqualityICmp (Cmp, LVI))
377
- return true ;
378
-
379
379
return false ;
380
380
}
381
381
0 commit comments