Skip to content

Commit 5bd7bbe

Browse files
committed
[LVI][CVP] Treat undef like a full range on abs(x, false)
1 parent 287580e commit 5bd7bbe

File tree

2 files changed

+36
-44
lines changed

2 files changed

+36
-44
lines changed

llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp

Lines changed: 31 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -470,58 +470,50 @@ static bool processBinOp(BinaryOperator *BinOp, LazyValueInfo *LVI);
470470
// because it is negation-invariant.
471471
static bool processAbsIntrinsic(IntrinsicInst *II, LazyValueInfo *LVI) {
472472
Value *X = II->getArgOperand(0);
473-
bool IsIntMinPoison = cast<ConstantInt>(II->getArgOperand(1))->isOne();
474-
475473
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);
479481

480482
// 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)) {
484486
++NumAbs;
485487
II->replaceAllUsesWith(X);
486488
II->eraseFromParent();
487489
return true;
488490
}
489491

490492
// 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();
512500

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);
519504

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+
}
523507

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;
525517
}
526518

527519
// See if this min/max intrinsic always picks it's one specific operand.

llvm/test/Transforms/CorrelatedValuePropagation/abs.ll

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -380,8 +380,7 @@ define i8 @test27(i8 %x) {
380380

381381
define i1 @pr59887(i1 %x, i1 %c) {
382382
; CHECK-LABEL: @pr59887(
383-
; CHECK-NEXT: [[ABS:%.*]] = call i1 @llvm.abs.i1(i1 [[X:%.*]], i1 false)
384-
; CHECK-NEXT: [[RES:%.*]] = select i1 [[C:%.*]], i1 [[ABS]], i1 false
383+
; CHECK-NEXT: [[RES:%.*]] = select i1 [[C:%.*]], i1 [[X:%.*]], i1 false
385384
; CHECK-NEXT: ret i1 [[RES]]
386385
;
387386
%abs = call i1 @llvm.abs.i1(i1 %x, i1 false)
@@ -402,7 +401,8 @@ define i32 @pr68381_undef_abs_false(i1 %c0, i1 %c1, i8 %v1) {
402401
; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[V1_I32]], [[BB0]] ], [ undef, [[START:%.*]] ]
403402
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB0]], label [[BB2:%.*]]
404403
; CHECK: bb2:
405-
; CHECK-NEXT: ret i32 [[X]]
404+
; CHECK-NEXT: [[Z:%.*]] = call i32 @llvm.abs.i32(i32 [[X]], i1 false)
405+
; CHECK-NEXT: ret i32 [[Z]]
406406
;
407407
start:
408408
br i1 %c0, label %bb0, label %bb1
@@ -466,8 +466,8 @@ define i32 @pr68381_undef_abs_false_sub(i1 %c0, i1 %c1, i32 %v1, i32 %v2) {
466466
; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[V3]], [[BB0]] ], [ undef, [[START:%.*]] ]
467467
; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB0]], label [[BB2:%.*]]
468468
; CHECK: bb2:
469-
; CHECK-NEXT: [[Z1:%.*]] = sub i32 0, [[X]]
470-
; CHECK-NEXT: ret i32 [[Z1]]
469+
; CHECK-NEXT: [[Z:%.*]] = call i32 @llvm.abs.i32(i32 [[X]], i1 false)
470+
; CHECK-NEXT: ret i32 [[Z]]
471471
;
472472
start:
473473
br i1 %c0, label %bb0, label %bb1

0 commit comments

Comments
 (0)