Index: llvm/unittests/Analysis/ScalarEvolutionTest.cpp =================================================================== --- llvm/unittests/Analysis/ScalarEvolutionTest.cpp +++ llvm/unittests/Analysis/ScalarEvolutionTest.cpp @@ -1744,4 +1744,53 @@ }); } +TEST_F(ScalarEvolutionsTest, ProveCondContainingPhiWithSameInputs) { + StringRef Assembly = R"( + define void @foo(i32 %n, ptr addrspace(1) %p) { + ENTRY: + %x01 = load atomic i32, ptr addrspace(1) %p unordered, align 8 + %cmp0 = icmp slt i32 %x01, 0 + br i1 %cmp0, label %EXIT, label %L0 + + L0: + %x = phi i32 [ %x01, %ENTRY ], [ %x02, %L2 ] + %cmp1 = icmp eq i32 %x, 0 + br i1 %cmp1, label %EXIT, label %L1 + + L1: + %iv = phi i32 [ 0, %L0 ], [ %iv.next, %L2 ] + %cmp2 = icmp ult i32 %iv, %n + br i1 %cmp2, label %L2, label %EXIT + + L2: + %iv.next = add nuw nsw i32 %iv, 1 + %x02 = load atomic i32, ptr addrspace(1) %p unordered, align 8 + %cmp3 = icmp slt i32 %iv.next, %x + br i1 %cmp3, label %L1, label %L0 + + EXIT: + ret void + } + )"; + + LLVMContext C; + SMDiagnostic Err; + std::unique_ptr M = parseAssemblyString(Assembly, Err, C); + ASSERT_TRUE(M && "Could not parse module?"); + ASSERT_TRUE(!verifyModule(*M) && "Must have been well formed!"); + + runWithSE(*M, "foo", [](Function &F, LoopInfo &LI, ScalarEvolution &SE) { + auto *LHS = SE.getConstant(APInt(/*numBits=*/32, 0)); + auto *RHS = SE.getSCEV(getInstructionByName(F, "x")); + auto *L1 = getInstructionByName(F, "iv")->getParent(); + ASSERT_TRUE(L1); + // TODO: + // - L1 is guarded by 'x01 >=s 0' and 'x != 0'; + // - %x has same inputs: %x01 and %x02; + // Thus L1 is guarded by cond '0