Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -3371,6 +3371,11 @@ return false; } + case Instruction::ICmp: + // Comparing poison with any value yields poison. This is why, for + // instance, x s< (x +nsw 1) can be folded to true. + return true; + case Instruction::GetElementPtr: // A GEP implicitly represents a sequence of additions, subtractions, // truncations, sign extensions and multiplications. The multiplications @@ -3405,6 +3410,11 @@ case Instruction::SRem: return I->getOperand(1); + case Instruction::Br: + if (cast(I)->isConditional()) + return cast(I)->getCondition(); + return nullptr; + default: return nullptr; } Index: test/Analysis/ScalarEvolution/flags-from-poison.ll =================================================================== --- test/Analysis/ScalarEvolution/flags-from-poison.ll +++ test/Analysis/ScalarEvolution/flags-from-poison.ll @@ -116,6 +116,55 @@ ret void } +; Example where an add should get the nuw flag: the UB-on-poison in +; this example is not due to a memory operation, but due to a +; compare-and-branch. +define void @test-add-nuw-from-icmp-and-branch( + float* %input, i32 %offset, i32 %numIterations) { +; CHECK-LABEL: @test-add-nuw-from-icmp-and-branch +entry: + br label %loop +loop: + %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] + +; CHECK: %index32 = +; CHECK: --> {%offset,+,1} + %index32 = add nuw i32 %i, %offset + + %nexti = add nuw i32 %i, 1 + %exitcond = icmp eq i32 %index32, %numIterations + br i1 %exitcond, label %exit, label %loop + +exit: + ret void +} + +; Like @test-add-nuw-from-icmp-and-branch, but we're testing just the +; icmp logic here (this pattern is unlikely to appear in real code). +define void @test-add-nuw-from-icmp(float* %input, i32 %offset, + i32 %numIterations) { +; CHECK-LABEL: @test-add-nuw-from-icmp +entry: + br label %loop +loop: + %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] + +; CHECK: %index32 = +; CHECK: --> {%offset,+,1} + %index32 = add nuw i32 %i, %offset + %cmp = icmp sgt i32 %index32, 0 + %cmp.idx = sext i1 %cmp to i32 + + %ptr = getelementptr inbounds float, float* %input, i32 %cmp.idx + %nexti = add nuw i32 %i, 1 + %f = load float, float* %ptr, align 4 + %exitcond = icmp eq i32 %nexti, %numIterations + br i1 %exitcond, label %exit, label %loop + +exit: + ret void +} + ; With no load to trigger UB from poison, we cannot infer nsw. define void @test-add-no-load(float* %input, i32 %offset, i32 %numIterations) { ; CHECK-LABEL: @test-add-no-load