diff --git a/llvm/include/llvm/Analysis/LazyValueInfo.h b/llvm/include/llvm/Analysis/LazyValueInfo.h --- a/llvm/include/llvm/Analysis/LazyValueInfo.h +++ b/llvm/include/llvm/Analysis/LazyValueInfo.h @@ -71,10 +71,11 @@ Instruction *CxtI = nullptr); /// Determine whether the specified value comparison with a constant is known - /// to be true or false at the specified instruction - /// (from an assume intrinsic). Pred is a CmpInst predicate. + /// to be true or false at the specified instruction. + /// \p Pred is a CmpInst predicate. If \p UseBlockValue is true, the block + /// value is also taken into account. Tristate getPredicateAt(unsigned Pred, Value *V, Constant *C, - Instruction *CxtI); + Instruction *CxtI, bool UseBlockValue = false); /// Determine whether the specified value is known to be a constant at the /// specified instruction. Return null if not. 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 @@ -1744,7 +1744,7 @@ LazyValueInfo::Tristate LazyValueInfo::getPredicateAt(unsigned Pred, Value *V, Constant *C, - Instruction *CxtI) { + Instruction *CxtI, bool UseBlockValue) { // Is or is not NonNull are common predicates being queried. If // isKnownNonZero can tell us the result of the predicate, we can // return it quickly. But this is only a fastpath, and falling @@ -1758,7 +1758,10 @@ else if (Pred == ICmpInst::ICMP_NE) return LazyValueInfo::True; } - ValueLatticeElement Result = getImpl(PImpl, AC, M).getValueAt(V, CxtI); + + ValueLatticeElement Result = UseBlockValue + ? getImpl(PImpl, AC, M).getValueInBlock(V, CxtI->getParent(), CxtI) + : getImpl(PImpl, AC, M).getValueAt(V, CxtI); Tristate Ret = getPredicateResult(Pred, C, Result, DL, TLI); if (Ret != Unknown) return Ret; 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 @@ -304,18 +304,9 @@ if (!C) return false; - // As a policy choice, we choose not to waste compile time on anything where - // the comparison is testing local values. While LVI can sometimes reason - // about such cases, it's not its primary purpose. We do make sure to do - // the block local query for uses from terminator instructions, but that's - // handled in the code for each terminator. As an exception, we allow phi - // nodes, for which LVI can thread the condition into predecessors. - auto *I = dyn_cast(Op0); - if (I && I->getParent() == Cmp->getParent() && !isa(I)) - return false; - LazyValueInfo::Tristate Result = - LVI->getPredicateAt(Cmp->getPredicate(), Op0, C, Cmp); + LVI->getPredicateAt(Cmp->getPredicate(), Op0, C, Cmp, + /*UseBlockValue=*/true); if (Result == LazyValueInfo::Unknown) return false; diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll --- a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll @@ -295,7 +295,6 @@ define i1 @call_attribute() { ; CHECK-LABEL: @call_attribute( ; CHECK-NEXT: [[A:%.*]] = call i8* @return_nonnull() -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8* [[A]], null ; CHECK-NEXT: br label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: ret i1 false @@ -319,7 +318,6 @@ ; CHECK: b_guard: ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ult i32 [[A]], [[B]] ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]] -; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[MIN]], 7 ; CHECK-NEXT: br label [[NEXT:%.*]] ; CHECK: next: ; CHECK-NEXT: ret i1 false @@ -356,7 +354,6 @@ ; CHECK: b_guard: ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sle i32 [[A]], [[B]] ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]] -; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[MIN]], 7 ; CHECK-NEXT: br label [[NEXT:%.*]] ; CHECK: next: ; CHECK-NEXT: ret i1 false @@ -393,7 +390,6 @@ ; CHECK: b_guard: ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp sge i32 [[A]], [[B]] ; CHECK-NEXT: [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]] -; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[MAX]], 7 ; CHECK-NEXT: br label [[NEXT:%.*]] ; CHECK: next: ; CHECK-NEXT: ret i1 false @@ -430,7 +426,6 @@ ; CHECK: b_guard: ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp uge i32 [[A]], [[B]] ; CHECK-NEXT: [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]] -; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[MAX]], 7 ; CHECK-NEXT: br label [[NEXT:%.*]] ; CHECK: next: ; CHECK-NEXT: ret i1 false @@ -465,7 +460,6 @@ ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[A]] -; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[SEL]], 4 ; CHECK-NEXT: br label [[NEXT:%.*]] ; CHECK: next: ; CHECK-NEXT: ret i1 false @@ -497,7 +491,6 @@ ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], -1 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 5 -; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[SEL]], 4 ; CHECK-NEXT: br label [[NEXT:%.*]] ; CHECK: next: ; CHECK-NEXT: ret i1 false @@ -529,7 +522,6 @@ ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp eq i32 [[A]], 5 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 5, i32 [[A]] -; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[SEL]], 6 ; CHECK-NEXT: br label [[NEXT:%.*]] ; CHECK: next: ; CHECK-NEXT: ret i1 false @@ -561,7 +553,6 @@ ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 1 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 5 -; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[SEL]], 6 ; CHECK-NEXT: br label [[NEXT:%.*]] ; CHECK: next: ; CHECK-NEXT: ret i1 false @@ -594,7 +585,6 @@ ; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ne i32 [[A]], 5 ; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[A]], 100 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 5 -; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[SEL]], 105 ; CHECK-NEXT: br label [[NEXT:%.*]] ; CHECK: next: ; CHECK-NEXT: ret i1 false @@ -821,7 +811,6 @@ ; CHECK-LABEL: @zext_unknown( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[A32:%.*]] = zext i8 [[A:%.*]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A32]], 256 ; CHECK-NEXT: br label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: ret i1 true @@ -839,7 +828,6 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: [[A8:%.*]] = trunc i32 [[A:%.*]] to i8 ; CHECK-NEXT: [[A32:%.*]] = sext i8 [[A8]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[A32]], 128 ; CHECK-NEXT: br label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: ret i1 true @@ -894,7 +882,6 @@ ; CHECK-LABEL: @and_unknown( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 128 -; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[AND]], 128 ; CHECK-NEXT: br label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: ret i1 true @@ -911,7 +898,6 @@ ; CHECK-LABEL: @lshr_unknown( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[AND:%.*]] = lshr i32 [[A:%.*]], 30 -; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[AND]], 128 ; CHECK-NEXT: br label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: ret i1 true @@ -928,7 +914,6 @@ ; CHECK-LABEL: @urem_unknown( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[UREM:%.*]] = urem i32 [[A:%.*]], 30 -; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[UREM]], 30 ; CHECK-NEXT: br label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: ret i1 true @@ -945,8 +930,6 @@ ; CHECK-LABEL: @srem_unknown( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[SREM:%.*]] = srem i32 [[A:%.*]], 30 -; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[SREM]], 30 -; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[SREM]], -30 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] ; CHECK: exit1: ; CHECK-NEXT: ret i1 true @@ -968,8 +951,6 @@ ; CHECK-LABEL: @sdiv_unknown( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[SREM:%.*]] = sdiv i32 [[A:%.*]], 123 -; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[SREM]], 17459217 -; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[SREM]], -17459217 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] ; CHECK: exit1: ; CHECK-NEXT: ret i1 true @@ -991,7 +972,6 @@ ; CHECK-LABEL: @uadd_sat_unknown( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[A:%.*]], i32 100) -; CHECK-NEXT: [[CMP1:%.*]] = icmp uge i32 [[VAL]], 100 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[VAL]], 100 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] ; CHECK: exit1: @@ -1014,7 +994,6 @@ ; CHECK-LABEL: @usub_sat_unknown( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 100) -; CHECK-NEXT: [[CMP1:%.*]] = icmp ule i32 [[VAL]], -101 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[VAL]], -101 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] ; CHECK: exit1: @@ -1037,7 +1016,6 @@ ; CHECK-LABEL: @sadd_sat_unknown( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[A:%.*]], i32 100) -; CHECK-NEXT: [[CMP1:%.*]] = icmp sge i32 [[VAL]], -2147483548 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[VAL]], -2147483548 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] ; CHECK: exit1: @@ -1060,7 +1038,6 @@ ; CHECK-LABEL: @ssub_sat_unknown( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[VAL:%.*]] = call i32 @llvm.ssub.sat.i32(i32 [[A:%.*]], i32 100) -; CHECK-NEXT: [[CMP1:%.*]] = icmp sle i32 [[VAL]], 2147483547 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[VAL]], 2147483547 ; CHECK-NEXT: br i1 undef, label [[EXIT1:%.*]], label [[EXIT2:%.*]] ; CHECK: exit1: 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 @@ -381,8 +381,7 @@ ; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i64 [[ZEXT]], 7 ; CHECK-NEXT: [[SHR:%.*]] = lshr i64 [[MUL]], 32 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i64 [[SHR]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[TRUNC]], 7 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %zext = zext i32 %x to i64 %mul = mul nuw i64 %zext, 7 @@ -396,9 +395,8 @@ ; CHECK-LABEL: @test13( ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[X:%.*]] to i64 ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[ZEXT]], 128 -; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[ADD]], 384 ; CHECK-NEXT: store i64 [[ADD]], i64* [[P:%.*]], align 8 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %zext = zext i8 %x to i64 %add = add nuw nsw i64 %zext, 128 @@ -627,8 +625,7 @@ ; CHECK-NEXT: br i1 [[CMP1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]] ; CHECK: if.true: ; CHECK-NEXT: [[IDX_OFF2:%.*]] = add nsw i64 [[IDX]], -1 -; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i64 [[IDX_OFF2]], 10 -; CHECK-NEXT: ret i1 [[CMP2]] +; CHECK-NEXT: ret i1 true ; CHECK: if.false: ; CHECK-NEXT: ret i1 undef ; diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/range.ll b/llvm/test/Transforms/CorrelatedValuePropagation/range.ll --- a/llvm/test/Transforms/CorrelatedValuePropagation/range.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/range.ll @@ -241,7 +241,6 @@ define i1 @test8(i64* %p) { ; CHECK-LABEL: @test8( ; CHECK-NEXT: [[A:%.*]] = load i64, i64* [[P:%.*]], align 4, [[RNG0:!range !.*]] -; CHECK-NEXT: [[RES:%.*]] = icmp eq i64 [[A]], 0 ; CHECK-NEXT: ret i1 false ; %a = load i64, i64* %p, !range !{i64 4, i64 255} @@ -252,7 +251,6 @@ define i1 @test9(i64* %p) { ; CHECK-LABEL: @test9( ; CHECK-NEXT: [[A:%.*]] = load i64, i64* [[P:%.*]], align 4, [[RNG1:!range !.*]] -; CHECK-NEXT: [[RES:%.*]] = icmp eq i64 [[A]], 0 ; CHECK-NEXT: ret i1 true ; %a = load i64, i64* %p, !range !{i64 0, i64 1} @@ -263,7 +261,6 @@ define i1 @test10(i64* %p) { ; CHECK-LABEL: @test10( ; CHECK-NEXT: [[A:%.*]] = load i64, i64* [[P:%.*]], align 4, [[RNG2:!range !.*]] -; CHECK-NEXT: [[RES:%.*]] = icmp eq i64 [[A]], 0 ; CHECK-NEXT: ret i1 false ; %a = load i64, i64* %p, !range !{i64 4, i64 8, i64 15, i64 20} @@ -277,7 +274,6 @@ ; CHECK-LABEL: @test11( ; CHECK-NEXT: [[POSITIVE:%.*]] = load i32, i32* @g, align 4, [[RNG3:!range !.*]] ; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[POSITIVE]], 1 -; CHECK-NEXT: [[TEST:%.*]] = icmp sgt i32 [[ADD]], 0 ; CHECK-NEXT: br label [[NEXT:%.*]] ; CHECK: next: ; CHECK-NEXT: ret i1 true