diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp index 0892aa9d75fb4..789a02ed329c9 100644 --- a/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/llvm/lib/Analysis/LazyValueInfo.cpp @@ -801,7 +801,7 @@ void LazyValueInfoImpl::intersectAssumeOrGuardBlockValueConstantRange( static ConstantRange getConstantRangeOrFull(const ValueLatticeElement &Val, Type *Ty, const DataLayout &DL) { - if (Val.isConstantRange()) + if (Val.isConstantRange(/*UndefAllowed*/ false)) return Val.getConstantRange(); return ConstantRange::getFull(DL.getTypeSizeInBits(Ty)); } diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll b/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll index 2aba1f0a99190..1d70932ee857b 100644 --- a/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll @@ -382,3 +382,40 @@ exit: ; CVP only simplifies based on ranges for non-local conditions. call void @use(i1 %t.1) ret i64 %res } + +; Test case for PR68381. +; Because of `undef`, we can only delete the second `and` instruction. +define i32 @constant_range_and_undef_and(i1 %c0, i1 %c1, i8 %v1, i8 %v2) { +; CHECK-LABEL: @constant_range_and_undef_and( +; CHECK-NEXT: start: +; CHECK-NEXT: br i1 [[C0:%.*]], label [[BB0:%.*]], label [[BB1:%.*]] +; CHECK: bb0: +; CHECK-NEXT: [[V1_I32:%.*]] = zext i8 [[V1:%.*]] to i32 +; CHECK-NEXT: br label [[BB1]] +; CHECK: bb1: +; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[V1_I32]], [[BB0]] ], [ undef, [[START:%.*]] ] +; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB0]], label [[BB2:%.*]] +; CHECK: bb2: +; CHECK-NEXT: [[V2_I32:%.*]] = zext i8 [[V2:%.*]] to i32 +; CHECK-NEXT: [[Y:%.*]] = or i32 [[X]], [[V2_I32]] +; CHECK-NEXT: [[Z:%.*]] = and i32 [[Y]], 255 +; CHECK-NEXT: ret i32 [[Z]] +; +start: + br i1 %c0, label %bb0, label %bb1 + +bb0: + %v1_i32 = zext i8 %v1 to i32 + br label %bb1 + +bb1: + %x = phi i32 [ %v1_i32, %bb0 ], [ undef, %start ] + br i1 %c1, label %bb0, label %bb2 + +bb2: + %v2_i32 = zext i8 %v2 to i32 + %y = or i32 %x, %v2_i32 + %z = and i32 %y, 255 + %z1 = and i32 %z, 255 + ret i32 %z1 +}