Index: lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCompares.cpp +++ lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2392,7 +2392,7 @@ // If there is overflow, the result must be true or false. // TODO: Can we assert there is no overflow because InstSimplify always // handles those cases? - if (!Overflow) + if (!Overflow && !isa(X)) // icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2) return new ICmpInst(Pred, X, ConstantInt::get(Ty, NewC)); } Index: test/Transforms/InstCombine/icmp-add.ll =================================================================== --- test/Transforms/InstCombine/icmp-add.ll +++ test/Transforms/InstCombine/icmp-add.ll @@ -175,6 +175,25 @@ ret i1 %cmp } +; icmp Pred (add nsw X, C2), C --> should not be optimized to icmp Pred X, (C - C2) when X is a PHI node. +define void @slt_phi_node_add_nsw(i32 %a) { +; CHECK-LABEL: @slt_phi_node_add_nsw( +; CHECK: [[CMP:%.*]] = icmp slt i32 %inc, 255 +; +entry: + br label %do.body + +do.body: ; preds = %do.body, %entry + %myValue = phi i32 [ 0, %entry ], [ %inc, %do.body ] + %inc = add nuw nsw i32 %myValue, 1 + %add = add nsw i32 %a, 1 + %cmp = icmp slt i32 %inc, 255 + br i1 %cmp, label %do.body, label %do.end + +do.end: + ret void; +} + ; The same fold should work with vectors. define <2 x i1> @slt_zero_add_nsw_splat_vec(<2 x i8> %a) {