Skip to content

Commit 4a2a6a4

Browse files
authored
[ValueTracking] Try to infer range of select from true and false values. (#68256)
When computing range of `select` instruction, first compute the union of ranges of "True" and "False" operands of the `select` instruction.
1 parent 6795503 commit 4a2a6a4

File tree

3 files changed

+23
-6
lines changed

3 files changed

+23
-6
lines changed

llvm/lib/Analysis/ValueTracking.cpp

+8-3
Original file line numberDiff line numberDiff line change
@@ -8841,9 +8841,14 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned,
88418841
CR = ConstantRange::getNonEmpty(Lower, Upper);
88428842
} else if (auto *II = dyn_cast<IntrinsicInst>(V))
88438843
CR = getRangeForIntrinsic(*II);
8844-
else if (auto *SI = dyn_cast<SelectInst>(V))
8845-
CR = getRangeForSelectPattern(*SI, IIQ);
8846-
else if (isa<FPToUIInst>(V) || isa<FPToSIInst>(V)) {
8844+
else if (auto *SI = dyn_cast<SelectInst>(V)) {
8845+
ConstantRange CRTrue = computeConstantRange(
8846+
SI->getTrueValue(), ForSigned, UseInstrInfo, AC, CtxI, DT, Depth + 1);
8847+
ConstantRange CRFalse = computeConstantRange(
8848+
SI->getFalseValue(), ForSigned, UseInstrInfo, AC, CtxI, DT, Depth + 1);
8849+
CR = CRTrue.unionWith(CRFalse);
8850+
CR = CR.intersectWith(getRangeForSelectPattern(*SI, IIQ));
8851+
} else if (isa<FPToUIInst>(V) || isa<FPToSIInst>(V)) {
88478852
APInt Lower = APInt(BitWidth, 0);
88488853
APInt Upper = APInt(BitWidth, 0);
88498854
// TODO: Return ConstantRange.

llvm/test/Analysis/BasicAA/range.ll

+13-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

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

67
; CHECK: Function: t1
78
; CHECK: NoAlias: i32* %gep1, i32* %gep2
@@ -258,8 +259,19 @@ join:
258259
ret void
259260
}
260261

261-
declare void @llvm.assume(i1)
262262

263+
; CHECK-LABEL: Function: select_in_gep
264+
; CHECK: NoAlias: i32* %arrayidx, i32* getelementptr inbounds ([10 x i32], ptr @G, i64 0, i64 3)
265+
define i32 @select_in_gep(i1 %c) {
266+
entry:
267+
%select_ = select i1 %c, i64 2, i64 1
268+
%arrayidx = getelementptr inbounds [10 x i32], ptr @G, i64 0, i64 %select_
269+
store i32 42, ptr %arrayidx, align 4
270+
%load_ = load i32, ptr getelementptr inbounds ([10 x i32], ptr @G, i64 0, i64 3), align 4
271+
ret i32 %load_
272+
}
273+
274+
declare void @llvm.assume(i1)
263275

264276
!0 = !{ i32 0, i32 2 }
265277
!1 = !{ i32 0, i32 1 }

llvm/test/Transforms/InstCombine/binop-select.ll

+2-2
Original file line numberDiff line numberDiff line change
@@ -324,12 +324,12 @@ define i32 @sub_sel_op1_use(i1 %b) {
324324
; CHECK-LABEL: @sub_sel_op1_use(
325325
; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 42, i32 41
326326
; CHECK-NEXT: call void @use(i32 [[S]])
327-
; CHECK-NEXT: [[R:%.*]] = sub nsw i32 42, [[S]]
327+
; CHECK-NEXT: [[R:%.*]] = sub nuw nsw i32 42, [[S]]
328328
; CHECK-NEXT: ret i32 [[R]]
329329
;
330330
%s = select i1 %b, i32 42, i32 41
331331
call void @use(i32 %s)
332-
%r = sub nsw i32 42, %s
332+
%r = sub nuw nsw i32 42, %s
333333
ret i32 %r
334334
}
335335

0 commit comments

Comments
 (0)