diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -1443,10 +1443,18 @@ Known.Zero.setAllBits(); Known.One.setAllBits(); + // Don't blindly recurse on Depth as there can be alot of incoming edges + // (increasing compile time). Instead set minimum depth as the number of + // incoming edges. Make sure we do at least one level. + unsigned InLoopRecurseDepth = + std::min(MaxAnalysisRecursionDepth - 1, + std::max(Depth + 1, P->getNumIncomingValues())); + // InLoopRecurseDepth = MaxAnalysisRecursionDepth - 1; for (unsigned u = 0, e = P->getNumIncomingValues(); u < e; ++u) { Value *IncValue = P->getIncomingValue(u); // Skip direct self references. - if (IncValue == P) continue; + if (IncValue == P) + continue; // Change the context instruction to the "edge" that flows into the // phi. This is important because that is where the value is actually @@ -1457,13 +1465,11 @@ Known2 = KnownBits(BitWidth); - // Recurse, but cap the recursion to one level, because we don't - // want to waste time spinning around in loops. - computeKnownBits(IncValue, Known2, MaxAnalysisRecursionDepth - 1, RecQ); + computeKnownBits(IncValue, Known2, InLoopRecurseDepth, RecQ); - // If this failed, see if we can use a conditional branch into the phi + // See if we can further use a conditional branch into the phi // to help us determine the range of the value. - if (Known2.isUnknown()) { + if (!Known2.isConstant()) { ICmpInst::Predicate Pred; const APInt *RHSC; BasicBlock *TrueSucc, *FalseSucc; @@ -1478,7 +1484,7 @@ Pred = CmpInst::getInversePredicate(Pred); // Get the knownbits implied by the incoming phi condition. auto CR = ConstantRange::makeExactICmpRegion(Pred, *RHSC); - Known2 = CR.toKnownBits(); + Known2 = Known2.unionWith(CR.toKnownBits()); } } } diff --git a/llvm/test/Analysis/ScalarEvolution/outer_phi.ll b/llvm/test/Analysis/ScalarEvolution/outer_phi.ll --- a/llvm/test/Analysis/ScalarEvolution/outer_phi.ll +++ b/llvm/test/Analysis/ScalarEvolution/outer_phi.ll @@ -7,7 +7,7 @@ ; CHECK-LABEL: 'test_01' ; CHECK-NEXT: Classifying expressions for: @test_01 ; CHECK-NEXT: %outer.iv = phi i32 [ 0, %entry ], [ %iv.next, %outer.backedge ] -; CHECK-NEXT: --> %outer.iv U: [0,-2147483647) S: [0,-2147483647) Exits: <> LoopDispositions: { %outer: Variant, %inner: Invariant } +; CHECK-NEXT: --> %outer.iv U: [0,-2147483648) S: [0,-2147483648) Exits: <> LoopDispositions: { %outer: Variant, %inner: Invariant } ; CHECK-NEXT: %iv = phi i32 [ 0, %outer ], [ %iv.next, %inner.backedge ] ; CHECK-NEXT: --> {0,+,1}<%inner> U: [0,-2147483648) S: [0,-2147483648) Exits: <> LoopDispositions: { %inner: Computable, %outer: Variant } ; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1 diff --git a/llvm/test/Transforms/InstCombine/catchswitch-phi.ll b/llvm/test/Transforms/InstCombine/catchswitch-phi.ll --- a/llvm/test/Transforms/InstCombine/catchswitch-phi.ll +++ b/llvm/test/Transforms/InstCombine/catchswitch-phi.ll @@ -120,8 +120,7 @@ ; CHECK-NEXT: [[TMP2:%.*]] = catchswitch within none [label %catch.start1] unwind to caller ; CHECK: catch.start1: ; CHECK-NEXT: [[TMP3:%.*]] = catchpad within [[TMP2]] [ptr null] -; CHECK-NEXT: [[TMP0:%.*]] = and i8 [[AP_2]], 1 -; CHECK-NEXT: [[TOBOOL1_NOT:%.*]] = icmp eq i8 [[TMP0]], 0 +; CHECK-NEXT: [[TOBOOL1_NOT:%.*]] = icmp eq i8 [[AP_2]], 0 ; CHECK-NEXT: br i1 [[TOBOOL1_NOT]], label [[IF_END1:%.*]], label [[IF_THEN1:%.*]] ; CHECK: if.then1: ; CHECK-NEXT: br label [[IF_END1]] diff --git a/llvm/test/Transforms/InstCombine/known-phi-recurse.ll b/llvm/test/Transforms/InstCombine/known-phi-recurse.ll --- a/llvm/test/Transforms/InstCombine/known-phi-recurse.ll +++ b/llvm/test/Transforms/InstCombine/known-phi-recurse.ll @@ -43,8 +43,7 @@ ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[TRUNC]], [[ENTRY:%.*]] ], [ 255, [[BODY]] ] -; CHECK-NEXT: [[RES:%.*]] = and i32 [[PHI]], 255 -; CHECK-NEXT: ret i32 [[RES]] +; CHECK-NEXT: ret i32 [[PHI]] ; entry: %y = call i64 @llvm.ctpop.i64(i64 %x) @@ -70,8 +69,7 @@ ; CHECK-NEXT: br label [[END]] ; CHECK: end: ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[TRUNC]], [[ENTRY:%.*]] ], [ [[TRUNC2]], [[BODY]] ] -; CHECK-NEXT: [[RES:%.*]] = and i32 [[PHI]], 255 -; CHECK-NEXT: ret i32 [[RES]] +; CHECK-NEXT: ret i32 [[PHI]] ; entry: %y = call i64 @llvm.ctpop.i64(i64 %x) diff --git a/llvm/test/Transforms/LoopUnroll/AArch64/runtime-unroll-generic.ll b/llvm/test/Transforms/LoopUnroll/AArch64/runtime-unroll-generic.ll --- a/llvm/test/Transforms/LoopUnroll/AArch64/runtime-unroll-generic.ll +++ b/llvm/test/Transforms/LoopUnroll/AArch64/runtime-unroll-generic.ll @@ -93,7 +93,7 @@ ; CHECK-A55-NEXT: [[EPIL_ITER_CMP_NOT:%.*]] = icmp eq i32 [[XTRAITER]], 1 ; CHECK-A55-NEXT: br i1 [[EPIL_ITER_CMP_NOT]], label [[FOR_END]], label [[FOR_BODY6_EPIL_1:%.*]] ; CHECK-A55: for.body6.epil.1: -; CHECK-A55-NEXT: [[INC_EPIL:%.*]] = add nuw i32 [[K_03_UNR]], 1 +; CHECK-A55-NEXT: [[INC_EPIL:%.*]] = or i32 [[K_03_UNR]], 1 ; CHECK-A55-NEXT: [[IDX_EXT_EPIL_1:%.*]] = zext i32 [[INC_EPIL]] to i64 ; CHECK-A55-NEXT: [[ARRAYIDX10_EPIL_1:%.*]] = getelementptr inbounds i16, ptr [[ARG_2]], i64 [[IDX_EXT_EPIL_1]] ; CHECK-A55-NEXT: [[TMP16:%.*]] = load i16, ptr [[ARRAYIDX10_EPIL_1]], align 2 @@ -109,7 +109,7 @@ ; CHECK-A55-NEXT: [[EPIL_ITER_CMP_1_NOT:%.*]] = icmp eq i32 [[XTRAITER]], 2 ; CHECK-A55-NEXT: br i1 [[EPIL_ITER_CMP_1_NOT]], label [[FOR_END]], label [[FOR_BODY6_EPIL_2:%.*]] ; CHECK-A55: for.body6.epil.2: -; CHECK-A55-NEXT: [[INC_EPIL_1:%.*]] = add nuw i32 [[K_03_UNR]], 2 +; CHECK-A55-NEXT: [[INC_EPIL_1:%.*]] = or i32 [[K_03_UNR]], 2 ; CHECK-A55-NEXT: [[IDX_EXT_EPIL_2:%.*]] = zext i32 [[INC_EPIL_1]] to i64 ; CHECK-A55-NEXT: [[ARRAYIDX10_EPIL_2:%.*]] = getelementptr inbounds i16, ptr [[ARG_2]], i64 [[IDX_EXT_EPIL_2]] ; CHECK-A55-NEXT: [[TMP19:%.*]] = load i16, ptr [[ARRAYIDX10_EPIL_2]], align 2 diff --git a/llvm/test/Transforms/LoopUnroll/runtime-unroll-remainder.ll b/llvm/test/Transforms/LoopUnroll/runtime-unroll-remainder.ll --- a/llvm/test/Transforms/LoopUnroll/runtime-unroll-remainder.ll +++ b/llvm/test/Transforms/LoopUnroll/runtime-unroll-remainder.ll @@ -35,7 +35,7 @@ ; CHECK-NEXT: [[EPIL_ITER_CMP_NOT:%.*]] = icmp eq i64 [[XTRAITER]], 1 ; CHECK-NEXT: br i1 [[EPIL_ITER_CMP_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_EPILOG_LCSSA:%.*]], label [[FOR_BODY_EPIL_1:%.*]] ; CHECK: for.body.epil.1: -; CHECK-NEXT: [[INDVARS_IV_NEXT_EPIL:%.*]] = add nuw nsw i64 [[INDVARS_IV_UNR]], 1 +; CHECK-NEXT: [[INDVARS_IV_NEXT_EPIL:%.*]] = or i64 [[INDVARS_IV_UNR]], 1 ; CHECK-NEXT: [[ARRAYIDX_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_EPIL]] ; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX_EPIL_1]], align 4 ; CHECK-NEXT: [[ARRAYIDX2_EPIL_1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[INDVARS_IV_NEXT_EPIL]] @@ -45,7 +45,7 @@ ; CHECK-NEXT: [[EPIL_ITER_CMP_1_NOT:%.*]] = icmp eq i64 [[XTRAITER]], 2 ; CHECK-NEXT: br i1 [[EPIL_ITER_CMP_1_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT_EPILOG_LCSSA]], label [[FOR_BODY_EPIL_2:%.*]] ; CHECK: for.body.epil.2: -; CHECK-NEXT: [[INDVARS_IV_NEXT_EPIL_1:%.*]] = add nuw nsw i64 [[INDVARS_IV_UNR]], 2 +; CHECK-NEXT: [[INDVARS_IV_NEXT_EPIL_1:%.*]] = or i64 [[INDVARS_IV_UNR]], 2 ; CHECK-NEXT: [[ARRAYIDX_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[INDVARS_IV_NEXT_EPIL_1]] ; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX_EPIL_2]], align 4 ; CHECK-NEXT: [[ARRAYIDX2_EPIL_2:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[INDVARS_IV_NEXT_EPIL_1]] diff --git a/llvm/test/Transforms/PhaseOrdering/X86/pr38280.ll b/llvm/test/Transforms/PhaseOrdering/X86/pr38280.ll --- a/llvm/test/Transforms/PhaseOrdering/X86/pr38280.ll +++ b/llvm/test/Transforms/PhaseOrdering/X86/pr38280.ll @@ -32,7 +32,7 @@ ; CHECK-NEXT: [[DST_ADDR_130:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], [[WHILE_BODY4]] ], [ [[DST_ADDR_0_LCSSA]], [[WHILE_COND3_PREHEADER]] ] ; CHECK-NEXT: [[SRC_ADDR_129:%.*]] = phi ptr [ [[INCDEC_PTR8:%.*]], [[WHILE_BODY4]] ], [ [[SRC_ADDR_0_LCSSA]], [[WHILE_COND3_PREHEADER]] ] ; CHECK-NEXT: [[COUNT_ADDR_128:%.*]] = phi i64 [ [[DEC:%.*]], [[WHILE_BODY4]] ], [ [[COUNT_ADDR_0_LCSSA]], [[WHILE_COND3_PREHEADER]] ] -; CHECK-NEXT: [[DEC]] = add i64 [[COUNT_ADDR_128]], -1 +; CHECK-NEXT: [[DEC]] = add nsw i64 [[COUNT_ADDR_128]], -1 ; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[SRC_ADDR_129]], align 1 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[DST_ADDR_130]], i64 [[NEG_OFFS]] ; CHECK-NEXT: [[TMP3:%.*]] = load i8, ptr [[ARRAYIDX]], align 1 @@ -41,7 +41,7 @@ ; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i8, ptr [[DST_ADDR_130]], i64 1 ; CHECK-NEXT: [[INCDEC_PTR8]] = getelementptr inbounds i8, ptr [[SRC_ADDR_129]], i64 1 ; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i64 [[DEC]], 0 -; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[WHILE_END9]], label [[WHILE_BODY4]], !llvm.loop [[LOOP0:![0-9]+]] +; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[WHILE_END9]], label [[WHILE_BODY4]] ; CHECK: while.end9: ; CHECK-NEXT: ret void ;