diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp --- a/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/llvm/lib/Analysis/LazyValueInfo.cpp @@ -1859,9 +1859,27 @@ return getPredicateAt(CmpInst::getSwappedPredicate(Pred), RHS, C, CxtI, UseBlockValue); - // Got two non-Constant values. While we could handle them somewhat, - // by getting their constant ranges, and applying ConstantRange::icmp(), - // so far it did not appear to be profitable. + // Got two non-Constant values. Try to determine the comparison results based + // on the block values of the two operands, e.g. because they have + // non-overlapping ranges. + if (UseBlockValue) { + Module *M = CxtI->getModule(); + ValueLatticeElement L = + getImpl(PImpl, AC, M).getValueInBlock(LHS, CxtI->getParent(), CxtI); + if (L.isOverdefined()) + return LazyValueInfo::Unknown; + + ValueLatticeElement R = + getImpl(PImpl, AC, M).getValueInBlock(RHS, CxtI->getParent(), CxtI); + Type *Ty = CmpInst::makeCmpResultType(LHS->getType()); + if (Constant *Res = L.getCompare((CmpInst::Predicate)P, Ty, R, + M->getDataLayout())) { + if (Res->isNullValue()) + return LazyValueInfo::False; + if (Res->isOneValue()) + return LazyValueInfo::True; + } + } return LazyValueInfo::Unknown; } 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 @@ -340,18 +340,16 @@ /// exploiting range information. static bool constantFoldCmp(CmpInst *Cmp, LazyValueInfo *LVI) { Value *Op0 = Cmp->getOperand(0); - auto *C = dyn_cast(Cmp->getOperand(1)); - if (!C) - return false; - + Value *Op1 = Cmp->getOperand(1); LazyValueInfo::Tristate Result = - LVI->getPredicateAt(Cmp->getPredicate(), Op0, C, Cmp, + LVI->getPredicateAt(Cmp->getPredicate(), Op0, Op1, Cmp, /*UseBlockValue=*/true); if (Result == LazyValueInfo::Unknown) return false; ++NumCmps; - Constant *TorF = ConstantInt::get(Type::getInt1Ty(Cmp->getContext()), Result); + Constant *TorF = + ConstantInt::get(CmpInst::makeCmpResultType(Op0->getType()), Result); Cmp->replaceAllUsesWith(TorF); Cmp->eraseFromParent(); return true; diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll --- a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll @@ -1180,10 +1180,8 @@ ; CHECK-NEXT: br i1 [[AND]], label [[IF:%.*]], label [[ELSE:%.*]] ; CHECK: if: ; CHECK-NEXT: [[A_100:%.*]] = add nuw nsw i32 [[A]], 100 -; CHECK-NEXT: [[CMP3:%.*]] = icmp ne i32 [[A_100]], [[B]] -; CHECK-NEXT: call void @check1(i1 [[CMP3]]) -; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i32 [[A_100]], [[B]] -; CHECK-NEXT: call void @check1(i1 [[CMP4]]) +; CHECK-NEXT: call void @check1(i1 true) +; CHECK-NEXT: call void @check1(i1 false) ; CHECK-NEXT: [[A_10:%.*]] = add nuw nsw i32 [[A]], 10 ; CHECK-NEXT: [[CMP5:%.*]] = icmp ne i32 [[A_10]], [[B]] ; CHECK-NEXT: call void @check1(i1 [[CMP5]]) @@ -1220,8 +1218,7 @@ ; CHECK-LABEL: @non_const_range_minmax( ; CHECK-NEXT: [[A2:%.*]] = call i8 @llvm.umin.i8(i8 [[A:%.*]], i8 10) ; CHECK-NEXT: [[B2:%.*]] = call i8 @llvm.umax.i8(i8 [[B:%.*]], i8 11) -; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8 [[A2]], [[B2]] -; CHECK-NEXT: ret i1 [[CMP1]] +; CHECK-NEXT: ret i1 true ; %a2 = call i8 @llvm.umin.i8(i8 %a, i8 10) %b2 = call i8 @llvm.umax.i8(i8 %b, i8 11) @@ -1229,6 +1226,7 @@ ret i1 %cmp1 } +; FIXME: Also support vectors. define <2 x i1> @non_const_range_minmax_vec(<2 x i8> %a, <2 x i8> %b) { ; CHECK-LABEL: @non_const_range_minmax_vec( ; CHECK-NEXT: [[A2:%.*]] = call <2 x i8> @llvm.umin.v2i8(<2 x i8> [[A:%.*]], <2 x i8> ) diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/mul.ll b/llvm/test/Transforms/CorrelatedValuePropagation/mul.ll --- a/llvm/test/Transforms/CorrelatedValuePropagation/mul.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/mul.ll @@ -209,8 +209,7 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: [[C:%.*]] = add nuw nsw i8 [[B:%.*]], -3 ; CHECK-NEXT: [[MUL:%.*]] = mul nsw i8 [[C]], 4 -; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[C]], [[MUL]] -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; entry: %c = add nuw nsw i8 %b, -3 diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/shl.ll b/llvm/test/Transforms/CorrelatedValuePropagation/shl.ll --- a/llvm/test/Transforms/CorrelatedValuePropagation/shl.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/shl.ll @@ -412,8 +412,7 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: [[C:%.*]] = add nuw nsw i8 [[B:%.*]], -3 ; CHECK-NEXT: [[SHL:%.*]] = shl nsw i8 [[C]], 2 -; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[C]], [[SHL]] -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; entry: %c = add nuw nsw i8 %b, -3