Index: lib/Analysis/LazyValueInfo.cpp =================================================================== --- lib/Analysis/LazyValueInfo.cpp +++ lib/Analysis/LazyValueInfo.cpp @@ -1153,6 +1153,36 @@ } } + if (isTrueDest && ICI->getOperand(0) == Val) { + // TODO: generalize this for when Val is operand(1) + unsigned BitWidth = Val->getType()->getPrimitiveSizeInBits(); + + // A getPredicate() == ICmpInst::ICMP_SLT || + ICI->getPredicate() == ICmpInst::ICMP_ULT)) { + ConstantRange Max = ICI->isSigned() ? + ConstantRange(APInt::getSignedMaxValue(BitWidth)) : + ConstantRange(APInt::getMaxValue(BitWidth)); + ConstantRange TrueValues = + ConstantRange::makeAllowedICmpRegion(ICI->getPredicate(), Max); + Result = LVILatticeVal::getRange(std::move(TrueValues)); + return true; + } + // A >s B for any A and B implies A >s INT_MIN on success path + // A >u B for any A and B implies A >u UINT_MIN on success path + if ((ICI->getPredicate() == ICmpInst::ICMP_SGT || + ICI->getPredicate() == ICmpInst::ICMP_UGT)) { + ConstantRange Min = ICI->isSigned() ? + ConstantRange(APInt::getSignedMinValue(BitWidth)) : + ConstantRange(APInt::getMinValue(BitWidth)); + ConstantRange TrueValues = + ConstantRange::makeAllowedICmpRegion(ICI->getPredicate(), Min); + Result = LVILatticeVal::getRange(std::move(TrueValues)); + return true; + } + } + return false; } Index: test/Transforms/CorrelatedValuePropagation/overflow.ll =================================================================== --- test/Transforms/CorrelatedValuePropagation/overflow.ll +++ test/Transforms/CorrelatedValuePropagation/overflow.ll @@ -0,0 +1,44 @@ +; RUN: opt < %s -correlated-propagation -S | FileCheck %s + +; Just showing arbitrary constants work, not really a clamp +define i1 @slt(i8 %a, i8 %b) { +; CHECK-LABEL: @slt( +; CHECK: ret i1 true +entry: + %cmp = icmp slt i8 %a, %b + call void @llvm.assume(i1 %cmp) + %res = icmp slt i8 %a, 127 + ret i1 %res +} + +define i1 @sgt(i8 %a, i8 %b) { +; CHECK-LABEL: @sgt( +; CHECK: ret i1 true +entry: + %cmp = icmp sgt i8 %a, %b + call void @llvm.assume(i1 %cmp) + %res = icmp sgt i8 %a, -128 + ret i1 %res +} + +define i1 @ult(i8 %a, i8 %b) { +; CHECK-LABEL: @ult( +; CHECK: ret i1 true +entry: + %cmp = icmp ult i8 %a, %b + call void @llvm.assume(i1 %cmp) + %res = icmp ult i8 %a, 255 + ret i1 %res +} + +define i1 @ugt(i8 %a, i8 %b) { +; CHECK-LABEL: @ugt( +; CHECK: ret i1 true +entry: + %cmp = icmp ugt i8 %a, %b + call void @llvm.assume(i1 %cmp) + %res = icmp ugt i8 %a, 0 + ret i1 %res +} + +declare void @llvm.assume(i1)