Index: llvm/trunk/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp @@ -2413,7 +2413,7 @@ } if (Ok) { // Evaluate the expression in the larger type. - const SCEV *Fold = getAddExpr(LargeOps, Flags, Depth + 1); + const SCEV *Fold = getAddExpr(LargeOps, SCEV::FlagAnyWrap, Depth + 1); // If it folds to something simple, use it. Otherwise, don't. if (isa(Fold) || isa(Fold)) return getTruncateExpr(Fold, Ty); Index: llvm/trunk/test/Analysis/ScalarEvolution/truncate.ll =================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/truncate.ll +++ llvm/trunk/test/Analysis/ScalarEvolution/truncate.ll @@ -73,3 +73,37 @@ %tmp36 = icmp ugt i32 %tmp16, 52 br i1 %tmp36, label %bb3, label %bb13 } + +; Make sure that no nuw flag is assigned to %tmp27, otherwise we will have a +; poisoned value. +define void @no_nuw(i64 %param) { + +; CHECK-LABEL: Classifying expressions for: @no_nuw +; CHECK: %tmp27 = add i64 %tmp20, -1 +; CHECK-NOT: (-1 + %tmp20) +; CHECK-NEXT: --> (-1 + %tmp20) U: + +bb: + %shift = shl i64 %param, 58 + br label %bb18 + +bb18: ; preds = %bb36, %bb + %tmp20 = phi i64 [ %shift, %bb ], [ 0, %bb36 ] + %tmp21 = phi i64 [ 0, %bb ], [ %tmp24, %bb36 ] + %tmp22 = phi i32 [ -6, %bb ], [ %tmp46, %bb36 ] + %tmp25 = add i32 %tmp22, 1 + %tmp26 = sext i32 %tmp25 to i64 + %tmp27 = add i64 %tmp20, -1 + %tmp28 = mul i64 %tmp27, %tmp26 + %tmp29 = icmp ult i64 %tmp21, 1048576 + br i1 %tmp29, label %bb36, label %bb30 + +bb30: ; preds = %bb18 + ret void + +bb36: ; preds = %bb18 + %tmp24 = add nuw i64 %tmp21, 1 + %tmp45 = trunc i64 %tmp28 to i32 + %tmp46 = sub i32 %tmp22, %tmp45 + br label %bb18 +}