Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -3282,10 +3282,17 @@ // atomic operations are guaranteed to terminate on most platforms // and most functions terminate. + if (ImmutableCallSite CS = ImmutableCallSite(I)) + // NB! This assumes that a function cannot have an infinite loop that does + // not contain side effects. As far as I can tell, this isn't a new + // assumption (e.g. we will DCE readnone and readonly calls). + return CS.doesNotThrow() && CS.onlyReadsMemory(); + + if (auto *II = dyn_cast(I)) + if (II->getIntrinsicID() == Intrinsic::dbg_value) + return true; + return !I->isAtomic() && // atomics may never succeed on some platforms - !isa(I) && // could throw and might not terminate - !isa(I) && // might not terminate and could throw to - // non-successor (see bug 24185 for details). !isa(I) && // has no successors !isa(I); // has no successors } Index: test/Analysis/ScalarEvolution/flags-from-poison.ll =================================================================== --- test/Analysis/ScalarEvolution/flags-from-poison.ll +++ test/Analysis/ScalarEvolution/flags-from-poison.ll @@ -1,5 +1,7 @@ ; RUN: opt < %s -S -analyze -scalar-evolution | FileCheck %s +declare void @unknown() + ; Positive and negative tests for inferring flags like nsw from ; reasoning about how a poison value from overflow would trigger ; undefined behavior. @@ -35,6 +37,63 @@ ret void } +define void @test-add-nsw-callinst-0(float* %input, i32 %offset, i32 %numIterations) { +; CHECK-LABEL: @test-add-nsw-callinst-0 +entry: + br label %loop +loop: + %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] + ; We do not know whether @unknown() will return or throw or + ; infinitely loop, so we cannot infer undefined behavior if %index32 + ; is poison. + call void @unknown() + +; CHECK: %index32 = +; CHECK: --> {%offset,+,1} + %index32 = add nsw i32 %i, %offset + +; CHECK: %index64 = +; CHECK: --> (sext i32 {%offset,+,1}<%loop> to i64) + %index64 = sext i32 %index32 to i64 + + %ptr = getelementptr inbounds float, float* %input, i64 %index64 + %nexti = add nsw i32 %i, 1 + %f = load float, float* %ptr, align 4 + call void @foo() + %exitcond = icmp eq i32 %nexti, %numIterations + br i1 %exitcond, label %exit, label %loop +exit: + ret void +} + +define void @test-add-nsw-callinst-1(float* %input, i32 %offset, i32 %numIterations) { +; CHECK-LABEL: @test-add-nsw-callinst-1 +entry: + br label %loop +loop: + %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] + ; We know that the call to @unknown will not throw or have an + ; infinite loop, so we can conclude UB if %index32 is poison. + call void @unknown() nounwind readonly + +; CHECK: %index32 = +; CHECK: --> {%offset,+,1} + %index32 = add nsw i32 %i, %offset + +; CHECK: %index64 = +; CHECK: --> {(sext i32 %offset to i64),+,1} + %index64 = sext i32 %index32 to i64 + + %ptr = getelementptr inbounds float, float* %input, i64 %index64 + %nexti = add nsw i32 %i, 1 + %f = load float, float* %ptr, align 4 + call void @foo() + %exitcond = icmp eq i32 %nexti, %numIterations + br i1 %exitcond, label %exit, label %loop +exit: + ret void +} + ; Example where an add should get the nuw flag. define void @test-add-nuw(float* %input, i32 %offset, i32 %numIterations) { ; CHECK-LABEL: @test-add-nuw