Index: lib/Analysis/ScalarEvolution.cpp =================================================================== --- lib/Analysis/ScalarEvolution.cpp +++ lib/Analysis/ScalarEvolution.cpp @@ -1268,7 +1268,8 @@ } if (!hasTrunc) return getAddExpr(Operands); - UniqueSCEVs.FindNodeOrInsertPos(ID, IP); // Mutates IP, returns NULL. + if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) + return S; } // trunc(x1*x2*...*xN) --> trunc(x1)*trunc(x2)*...*trunc(xN) if we can @@ -1284,7 +1285,8 @@ } if (!hasTrunc) return getMulExpr(Operands); - UniqueSCEVs.FindNodeOrInsertPos(ID, IP); // Mutates IP, returns NULL. + if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) + return S; } // If the input value is a chrec scev, truncate the chrec's operands. Index: test/Analysis/ScalarEvolution/truncate.ll =================================================================== --- /dev/null +++ test/Analysis/ScalarEvolution/truncate.ll @@ -0,0 +1,96 @@ +; RUN: opt < %s -analyze -iv-users +; RUN: opt < %s -passes='print' +; Regression test for assert ScalarEvolution::getTruncateExpr. + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1" +target triple = "x86_64-unknown-linux-gnu" + +define void @test(i8*, i8 %p1, i64 %p2) { +entry: + br label %label5 + +label1.loopexit: ; preds = %not_zero108.1 + %1 = add nuw nsw i32 %14, 1 + %2 = icmp ugt i32 %14, 93 + br i1 %2, label %label2, label %label5 + +label2: ; preds = %label1.loopexit + br label %label4 + +label3: ; preds = %label4 + ret void + +label4: ; preds = %label4, %label2 + %3 = phi i64 [ %26, %label2 ], [ %8, %label4 ] + %local_4_33 = phi i32 [ 3, %label2 ], [ %11, %label4 ] + %local_7_36 = phi i32 [ 2, %label2 ], [ %12, %label4 ] + %4 = trunc i64 %3 to i32 + %5 = mul i32 %4, 11 + %6 = mul i32 %local_4_33, 55 + %7 = sdiv i32 %5, %6 + %8 = add i64 %3, -1 + %9 = sitofp i32 %7 to double + %10 = fsub double 0x3FBA89BDEE3337FA, %9 + %arg.v.i = insertelement <2 x double> undef, double %10, i32 0 + %res.i = call i32 @llvm.x86.sse2.cvttsd2si(<2 x double> %arg.v.i) + %11 = add i32 %res.i, %local_4_33 + %12 = add nuw nsw i32 %local_7_36, 1 + %13 = icmp ugt i32 %local_7_36, 68 + br i1 %13, label %label3, label %label4 + +label5: ; preds = %label1.loopexit, %entry + %a.p = phi i64 [ %p2, %entry ], [ %26, %label1.loopexit ] + %.p = phi i8 [ %p1, %entry ], [ %24, %label1.loopexit ] + %14 = phi i32 [ 2, %entry ], [ %1, %label1.loopexit ] + %local_4_144 = phi i32 [ -1, %entry ], [ %30, %label1.loopexit ] + br label %label6 + +label6: ; preds = %not_zero108.1, %label5 + %15 = phi i64 [ %a.p, %label5 ], [ %26, %not_zero108.1 ] + %16 = phi i8 [ %.p, %label5 ], [ %24, %not_zero108.1 ] + %local_3_91 = phi i32 [ 1, %label5 ], [ %31, %not_zero108.1 ] + %local_4_92 = phi i32 [ %local_4_144, %label5 ], [ %30, %not_zero108.1 ] + %17 = add i8 %16, -1 + %18 = sext i8 %17 to i64 + %.neg126 = sub i64 1, %15 + %19 = add i64 %.neg126, %18 + %20 = trunc i64 %19 to i32 + %21 = mul i32 %local_4_92, %20 + %22 = icmp eq i32 %20, 0 + br i1 %22, label %zero107.loopexit, label %not_zero108 + +not_zero108: ; preds = %label6 + br i1 false, label %done111, label %general_case110 + +general_case110: ; preds = %not_zero108 + %23 = srem i32 %21, %20 + br label %done111 + +done111: ; preds = %general_case110, %not_zero108 + %result112 = phi i32 [ %23, %general_case110 ], [ 0, %not_zero108 ] + %24 = add i8 %16, -2 + %25 = sext i8 %24 to i64 + %.neg126.1 = add nsw i64 %25, 1 + %26 = sub i64 %.neg126.1, %19 + %27 = trunc i64 %26 to i32 + %28 = icmp eq i32 %27, 0 + br i1 %28, label %zero107.split.loop.exit, label %not_zero108.1 + +zero107.split.loop.exit: ; preds = %done111 + br label %zero107 + +zero107.loopexit: ; preds = %label6 + br label %zero107 + +zero107: ; preds = %zero107.loopexit, %zero107.split.loop.exit + unreachable + +not_zero108.1: ; preds = %done111 + %29 = mul i32 %result112, %27 + %30 = srem i32 %29, %27 + %31 = add nuw nsw i32 %local_3_91, 2 + %32 = icmp ugt i32 %local_3_91, 52 + br i1 %32, label %label1.loopexit, label %label6 +} + +declare i32 @llvm.x86.sse2.cvttsd2si(<2 x double>)