@@ -470,58 +470,50 @@ static bool processBinOp(BinaryOperator *BinOp, LazyValueInfo *LVI);
470
470
// because it is negation-invariant.
471
471
static bool processAbsIntrinsic (IntrinsicInst *II, LazyValueInfo *LVI) {
472
472
Value *X = II->getArgOperand (0 );
473
- bool IsIntMinPoison = cast<ConstantInt>(II->getArgOperand (1 ))->isOne ();
474
-
475
473
Type *Ty = X->getType ();
476
- Constant *IntMin =
477
- ConstantInt::get (Ty, APInt::getSignedMinValue (Ty->getScalarSizeInBits ()));
478
- LazyValueInfo::Tristate Result;
474
+ if (!Ty->isIntegerTy ())
475
+ return false ;
476
+
477
+ bool IsIntMinPoison = cast<ConstantInt>(II->getArgOperand (1 ))->isOne ();
478
+ APInt IntMin = APInt::getSignedMinValue (Ty->getScalarSizeInBits ());
479
+ ConstantRange Range = LVI->getConstantRangeAtUse (
480
+ II->getOperandUse (0 ), /* UndefAllowed*/ IsIntMinPoison);
479
481
480
482
// Is X in [0, IntMin]? NOTE: INT_MIN is fine!
481
- Result = LVI-> getPredicateAt (CmpInst::Predicate::ICMP_ULE, X, IntMin, II,
482
- /* UseBlockValue= */ true );
483
- if (Result == LazyValueInfo::True ) {
483
+ ConstantRange ZeroIntMinRange =
484
+ ConstantRange::makeExactICmpRegion (CmpInst::Predicate::ICMP_ULE, IntMin );
485
+ if (ZeroIntMinRange. contains (Range) ) {
484
486
++NumAbs;
485
487
II->replaceAllUsesWith (X);
486
488
II->eraseFromParent ();
487
489
return true ;
488
490
}
489
491
490
492
// Is X in [IntMin, 0]? NOTE: INT_MIN is fine!
491
- Constant *Zero = ConstantInt::getNullValue (Ty);
492
- Result = LVI->getPredicateAt (CmpInst::Predicate::ICMP_SLE, X, Zero, II,
493
- /* UseBlockValue=*/ true );
494
- assert (Result != LazyValueInfo::False && " Should have been handled already." );
495
-
496
- if (Result == LazyValueInfo::Unknown) {
497
- // Argument's range crosses zero.
498
- bool Changed = false ;
499
- if (!IsIntMinPoison) {
500
- // Can we at least tell that the argument is never INT_MIN?
501
- Result = LVI->getPredicateAt (CmpInst::Predicate::ICMP_NE, X, IntMin, II,
502
- /* UseBlockValue=*/ true );
503
- if (Result == LazyValueInfo::True) {
504
- ++NumNSW;
505
- ++NumSubNSW;
506
- II->setArgOperand (1 , ConstantInt::getTrue (II->getContext ()));
507
- Changed = true ;
508
- }
509
- }
510
- return Changed;
511
- }
493
+ if (Range.getSignedMax ().isNonPositive ()) {
494
+ IRBuilder<> B (II);
495
+ Value *NegX = B.CreateNeg (X, II->getName (), /* HasNUW=*/ false ,
496
+ /* HasNSW=*/ IsIntMinPoison);
497
+ ++NumAbs;
498
+ II->replaceAllUsesWith (NegX);
499
+ II->eraseFromParent ();
512
500
513
- IRBuilder<> B (II);
514
- Value *NegX = B.CreateNeg (X, II->getName (), /* HasNUW=*/ false ,
515
- /* HasNSW=*/ IsIntMinPoison);
516
- ++NumAbs;
517
- II->replaceAllUsesWith (NegX);
518
- II->eraseFromParent ();
501
+ // See if we can infer some no-wrap flags.
502
+ if (auto *BO = dyn_cast<BinaryOperator>(NegX))
503
+ processBinOp (BO, LVI);
519
504
520
- // See if we can infer some no-wrap flags.
521
- if (auto *BO = dyn_cast<BinaryOperator>(NegX))
522
- processBinOp (BO, LVI);
505
+ return true ;
506
+ }
523
507
524
- return true ;
508
+ // Argument's range crosses zero.
509
+ // Can we at least tell that the argument is never INT_MIN?
510
+ if (!IsIntMinPoison && !Range.contains (IntMin)) {
511
+ ++NumNSW;
512
+ ++NumSubNSW;
513
+ II->setArgOperand (1 , ConstantInt::getTrue (II->getContext ()));
514
+ return true ;
515
+ }
516
+ return false ;
525
517
}
526
518
527
519
// See if this min/max intrinsic always picks it's one specific operand.
0 commit comments