Skip to content

Commit 024b18a

Browse files
committed
[LVI][CVP] Calculate with.overflow result range
In LVI, calculate the range of extractvalue(op.with.overflow(%x, %y), 0) as the range of op(%x, %y). This is mainly useful in conjunction with D60650: If the result of the operation is extracted in a branch guarded against overflow, then the value of %x will be appropriately constrained and the result range of the operation will be calculated taking that into account. Differential Revision: https://reviews.llvm.org/D60656 llvm-svn: 361693
1 parent 17367b0 commit 024b18a

File tree

2 files changed

+22
-14
lines changed

2 files changed

+22
-14
lines changed

llvm/lib/Analysis/LazyValueInfo.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,8 @@ namespace {
430430
BasicBlock *BB);
431431
bool solveBlockValueCast(ValueLatticeElement &BBLV, CastInst *CI,
432432
BasicBlock *BB);
433+
bool solveBlockValueOverflowIntrinsic(
434+
ValueLatticeElement &BBLV, WithOverflowInst *WO, BasicBlock *BB);
433435
void intersectAssumeOrGuardBlockValueConstantRange(Value *Val,
434436
ValueLatticeElement &BBLV,
435437
Instruction *BBI);
@@ -642,6 +644,11 @@ bool LazyValueInfoImpl::solveBlockValueImpl(ValueLatticeElement &Res,
642644

643645
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(BBI))
644646
return solveBlockValueBinaryOp(Res, BO, BB);
647+
648+
if (auto *EVI = dyn_cast<ExtractValueInst>(BBI))
649+
if (auto *WO = dyn_cast<WithOverflowInst>(EVI->getAggregateOperand()))
650+
if (EVI->getNumIndices() == 1 && *EVI->idx_begin() == 0)
651+
return solveBlockValueOverflowIntrinsic(Res, WO, BB);
645652
}
646653

647654
LLVM_DEBUG(dbgs() << " compute BB '" << BB->getName()
@@ -1097,6 +1104,14 @@ bool LazyValueInfoImpl::solveBlockValueBinaryOp(ValueLatticeElement &BBLV,
10971104
};
10981105
}
10991106

1107+
bool LazyValueInfoImpl::solveBlockValueOverflowIntrinsic(
1108+
ValueLatticeElement &BBLV, WithOverflowInst *WO, BasicBlock *BB) {
1109+
return solveBlockValueBinaryOpImpl(BBLV, WO, BB,
1110+
[WO](const ConstantRange &CR1, const ConstantRange &CR2) {
1111+
return CR1.binaryOp(WO->getBinaryOp(), CR2);
1112+
});
1113+
}
1114+
11001115
static ValueLatticeElement getValueFromICmpCondition(Value *Val, ICmpInst *ICI,
11011116
bool isTrueDest) {
11021117
Value *LHS = ICI->getOperand(0);

llvm/test/Transforms/CorrelatedValuePropagation/overflow_predicate.ll

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,7 @@ define i1 @uadd_val(i8 %x, i1* %pc) {
470470
; CHECK: split:
471471
; CHECK-NEXT: [[C1:%.*]] = icmp ugt i8 [[VAL]], 100
472472
; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
473-
; CHECK-NEXT: [[C2:%.*]] = icmp uge i8 [[VAL]], 100
474-
; CHECK-NEXT: ret i1 [[C2]]
473+
; CHECK-NEXT: ret i1 true
475474
; CHECK: trap:
476475
; CHECK-NEXT: call void @llvm.trap()
477476
; CHECK-NEXT: unreachable
@@ -506,8 +505,7 @@ define i1 @sadd_val(i8 %x, i1* %pc) {
506505
; CHECK: split:
507506
; CHECK-NEXT: [[C1:%.*]] = icmp sgt i8 [[VAL]], -28
508507
; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
509-
; CHECK-NEXT: [[C2:%.*]] = icmp sge i8 [[VAL]], -28
510-
; CHECK-NEXT: ret i1 [[C2]]
508+
; CHECK-NEXT: ret i1 true
511509
; CHECK: trap:
512510
; CHECK-NEXT: call void @llvm.trap()
513511
; CHECK-NEXT: unreachable
@@ -542,8 +540,7 @@ define i1 @usub_val(i8 %x, i1* %pc) {
542540
; CHECK: split:
543541
; CHECK-NEXT: [[C1:%.*]] = icmp ult i8 [[VAL]], -101
544542
; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
545-
; CHECK-NEXT: [[C2:%.*]] = icmp ule i8 [[VAL]], -101
546-
; CHECK-NEXT: ret i1 [[C2]]
543+
; CHECK-NEXT: ret i1 true
547544
; CHECK: trap:
548545
; CHECK-NEXT: call void @llvm.trap()
549546
; CHECK-NEXT: unreachable
@@ -578,8 +575,7 @@ define i1 @ssub_val(i8 %x, i1* %pc) {
578575
; CHECK: split:
579576
; CHECK-NEXT: [[C1:%.*]] = icmp slt i8 [[VAL]], 27
580577
; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
581-
; CHECK-NEXT: [[C2:%.*]] = icmp sle i8 [[VAL]], 27
582-
; CHECK-NEXT: ret i1 [[C2]]
578+
; CHECK-NEXT: ret i1 true
583579
; CHECK: trap:
584580
; CHECK-NEXT: call void @llvm.trap()
585581
; CHECK-NEXT: unreachable
@@ -614,8 +610,7 @@ define i1 @umul_val(i8 %x, i1* %pc) {
614610
; CHECK: split:
615611
; CHECK-NEXT: [[C1:%.*]] = icmp ult i8 [[VAL]], -6
616612
; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
617-
; CHECK-NEXT: [[C2:%.*]] = icmp ule i8 [[VAL]], -6
618-
; CHECK-NEXT: ret i1 [[C2]]
613+
; CHECK-NEXT: ret i1 true
619614
; CHECK: trap:
620615
; CHECK-NEXT: call void @llvm.trap()
621616
; CHECK-NEXT: unreachable
@@ -650,8 +645,7 @@ define i1 @smul_val_bound1(i8 %x, i1* %pc) {
650645
; CHECK: split:
651646
; CHECK-NEXT: [[C1:%.*]] = icmp slt i8 [[VAL]], 120
652647
; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
653-
; CHECK-NEXT: [[C2:%.*]] = icmp sle i8 [[VAL]], 120
654-
; CHECK-NEXT: ret i1 [[C2]]
648+
; CHECK-NEXT: ret i1 true
655649
; CHECK: trap:
656650
; CHECK-NEXT: call void @llvm.trap()
657651
; CHECK-NEXT: unreachable
@@ -686,8 +680,7 @@ define i1 @smul_val_bound2(i8 %x, i1* %pc) {
686680
; CHECK: split:
687681
; CHECK-NEXT: [[C1:%.*]] = icmp sgt i8 [[VAL]], -120
688682
; CHECK-NEXT: store i1 [[C1]], i1* [[PC:%.*]]
689-
; CHECK-NEXT: [[C2:%.*]] = icmp sge i8 [[VAL]], -120
690-
; CHECK-NEXT: ret i1 [[C2]]
683+
; CHECK-NEXT: ret i1 true
691684
; CHECK: trap:
692685
; CHECK-NEXT: call void @llvm.trap()
693686
; CHECK-NEXT: unreachable

0 commit comments

Comments
 (0)