Skip to content

Commit

Permalink
[ValueTracking] Try to infer range of select from true and false valu…
Browse files Browse the repository at this point in the history
…es. (#68256)

When computing range of `select` instruction, first compute the union of
ranges of "True" and "False" operands of the `select` instruction.
  • Loading branch information
mgudim authored Oct 5, 2023
1 parent 6795503 commit 4a2a6a4
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 6 deletions.
11 changes: 8 additions & 3 deletions llvm/lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8841,9 +8841,14 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned,
CR = ConstantRange::getNonEmpty(Lower, Upper);
} else if (auto *II = dyn_cast<IntrinsicInst>(V))
CR = getRangeForIntrinsic(*II);
else if (auto *SI = dyn_cast<SelectInst>(V))
CR = getRangeForSelectPattern(*SI, IIQ);
else if (isa<FPToUIInst>(V) || isa<FPToSIInst>(V)) {
else if (auto *SI = dyn_cast<SelectInst>(V)) {
ConstantRange CRTrue = computeConstantRange(
SI->getTrueValue(), ForSigned, UseInstrInfo, AC, CtxI, DT, Depth + 1);
ConstantRange CRFalse = computeConstantRange(
SI->getFalseValue(), ForSigned, UseInstrInfo, AC, CtxI, DT, Depth + 1);
CR = CRTrue.unionWith(CRFalse);
CR = CR.intersectWith(getRangeForSelectPattern(*SI, IIQ));
} else if (isa<FPToUIInst>(V) || isa<FPToSIInst>(V)) {
APInt Lower = APInt(BitWidth, 0);
APInt Upper = APInt(BitWidth, 0);
// TODO: Return ConstantRange.
Expand Down
14 changes: 13 additions & 1 deletion llvm/test/Analysis/BasicAA/range.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

%struct.S = type { i32, [2 x i32], i32 }
%struct.S2 = type { i32, [4 x i32], [4 x i32] }
@G = global [10 x i32] zeroinitializer, align 4

; CHECK: Function: t1
; CHECK: NoAlias: i32* %gep1, i32* %gep2
Expand Down Expand Up @@ -258,8 +259,19 @@ join:
ret void
}

declare void @llvm.assume(i1)

; CHECK-LABEL: Function: select_in_gep
; CHECK: NoAlias: i32* %arrayidx, i32* getelementptr inbounds ([10 x i32], ptr @G, i64 0, i64 3)
define i32 @select_in_gep(i1 %c) {
entry:
%select_ = select i1 %c, i64 2, i64 1
%arrayidx = getelementptr inbounds [10 x i32], ptr @G, i64 0, i64 %select_
store i32 42, ptr %arrayidx, align 4
%load_ = load i32, ptr getelementptr inbounds ([10 x i32], ptr @G, i64 0, i64 3), align 4
ret i32 %load_
}

declare void @llvm.assume(i1)

!0 = !{ i32 0, i32 2 }
!1 = !{ i32 0, i32 1 }
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/InstCombine/binop-select.ll
Original file line number Diff line number Diff line change
Expand Up @@ -324,12 +324,12 @@ define i32 @sub_sel_op1_use(i1 %b) {
; CHECK-LABEL: @sub_sel_op1_use(
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 42, i32 41
; CHECK-NEXT: call void @use(i32 [[S]])
; CHECK-NEXT: [[R:%.*]] = sub nsw i32 42, [[S]]
; CHECK-NEXT: [[R:%.*]] = sub nuw nsw i32 42, [[S]]
; CHECK-NEXT: ret i32 [[R]]
;
%s = select i1 %b, i32 42, i32 41
call void @use(i32 %s)
%r = sub nsw i32 42, %s
%r = sub nuw nsw i32 42, %s
ret i32 %r
}

Expand Down

0 comments on commit 4a2a6a4

Please sign in to comment.