diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index b76becf24d10fc9..f5b18785d4869e0 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -8841,9 +8841,14 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool ForSigned, CR = ConstantRange::getNonEmpty(Lower, Upper); } else if (auto *II = dyn_cast(V)) CR = getRangeForIntrinsic(*II); - else if (auto *SI = dyn_cast(V)) - CR = getRangeForSelectPattern(*SI, IIQ); - else if (isa(V) || isa(V)) { + else if (auto *SI = dyn_cast(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(V) || isa(V)) { APInt Lower = APInt(BitWidth, 0); APInt Upper = APInt(BitWidth, 0); // TODO: Return ConstantRange. diff --git a/llvm/test/Analysis/BasicAA/range.ll b/llvm/test/Analysis/BasicAA/range.ll index 3862e26ee49a4ba..e5dfb60c8b8784b 100644 --- a/llvm/test/Analysis/BasicAA/range.ll +++ b/llvm/test/Analysis/BasicAA/range.ll @@ -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 @@ -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 } diff --git a/llvm/test/Transforms/InstCombine/binop-select.ll b/llvm/test/Transforms/InstCombine/binop-select.ll index a59e19897f061d1..6cd4132eadd77b9 100644 --- a/llvm/test/Transforms/InstCombine/binop-select.ll +++ b/llvm/test/Transforms/InstCombine/binop-select.ll @@ -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 }