diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp --- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -975,7 +975,8 @@ if (SDI->getType()->isVectorTy()) return false; - ConstantRange LRange = LVI->getConstantRangeAtUse(SDI->getOperandUse(0)); + ConstantRange LRange = + LVI->getConstantRangeAtUse(SDI->getOperandUse(0), /*UndefAllowed*/ false); unsigned OrigWidth = SDI->getType()->getIntegerBitWidth(); ConstantRange NegOneOrZero = ConstantRange(APInt(OrigWidth, (uint64_t)-1, true), APInt(OrigWidth, 1)); @@ -1007,7 +1008,8 @@ return false; const Use &Base = SDI->getOperandUse(0); - if (!LVI->getConstantRangeAtUse(Base).isAllNonNegative()) + if (!LVI->getConstantRangeAtUse(Base, /*UndefAllowed*/ false) + .isAllNonNegative()) return false; ++NumSExt; diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/ashr.ll b/llvm/test/Transforms/CorrelatedValuePropagation/ashr.ll --- a/llvm/test/Transforms/CorrelatedValuePropagation/ashr.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/ashr.ll @@ -140,3 +140,35 @@ %2 = select i1 %s, i32 %0, i32 %1 ret i32 %2 } + +define i32 @may_including_undef(i1 %c.1, i1 %c.2) { +; CHECK-LABEL: define i32 @may_including_undef +; CHECK-SAME: (i1 [[C_1:%.*]], i1 [[C_2:%.*]]) { +; CHECK-NEXT: br i1 [[C_1]], label [[TRUE_1:%.*]], label [[FALSE:%.*]] +; CHECK: true.1: +; CHECK-NEXT: br i1 [[C_2]], label [[TRUE_2:%.*]], label [[EXIT:%.*]] +; CHECK: true.2: +; CHECK-NEXT: br label [[EXIT]] +; CHECK: false: +; CHECK-NEXT: br label [[EXIT]] +; CHECK: exit: +; CHECK-NEXT: [[P:%.*]] = phi i32 [ 2, [[TRUE_1]] ], [ 4, [[TRUE_2]] ], [ undef, [[FALSE]] ] +; CHECK-NEXT: [[R:%.*]] = ashr i32 [[P]], 1 +; CHECK-NEXT: ret i32 [[R]] +; + br i1 %c.1, label %true.1, label %false + +true.1: + br i1 %c.2, label %true.2, label %exit + +true.2: + br label %exit + +false: + br label %exit + +exit: + %p = phi i32 [ 2, %true.1 ], [ 4, %true.2], [ undef, %false ] + %r = ashr i32 %p, 1 + ret i32 %r +} diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/sext.ll b/llvm/test/Transforms/CorrelatedValuePropagation/sext.ll --- a/llvm/test/Transforms/CorrelatedValuePropagation/sext.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/sext.ll @@ -133,3 +133,34 @@ exit: ret void } + +define i64 @may_including_undef(i1 %c.1, i1 %c.2) { +; CHECK-LABEL: @may_including_undef( +; CHECK-NEXT: br i1 [[C_1:%.*]], label [[TRUE_1:%.*]], label [[FALSE:%.*]] +; CHECK: true.1: +; CHECK-NEXT: br i1 [[C_2:%.*]], label [[TRUE_2:%.*]], label [[EXIT:%.*]] +; CHECK: true.2: +; CHECK-NEXT: br label [[EXIT]] +; CHECK: false: +; CHECK-NEXT: br label [[EXIT]] +; CHECK: exit: +; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, [[TRUE_1]] ], [ 1, [[TRUE_2]] ], [ undef, [[FALSE]] ] +; CHECK-NEXT: [[EXT:%.*]] = sext i32 [[P]] to i64 +; CHECK-NEXT: ret i64 [[EXT]] +; + br i1 %c.1, label %true.1, label %false + +true.1: + br i1 %c.2, label %true.2, label %exit + +true.2: + br label %exit + +false: + br label %exit + +exit: + %p = phi i32 [ 0, %true.1 ], [ 1, %true.2], [ undef, %false ] + %ext = sext i32 %p to i64 + ret i64 %ext +}