diff --git a/llvm/test/Transforms/LoopRotate/pr51981-scev-problem.ll b/llvm/test/Transforms/LoopRotate/pr51981-scev-problem.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/LoopRotate/pr51981-scev-problem.ll @@ -0,0 +1,59 @@ +; RUN: opt < %s -passes='print,loop(loop-rotate),invalidate,print' -disable-output 2>&1 | FileCheck -check-prefixes CHECK-SCEV,CHECK-SCEV-OK %s +; RUN: opt < %s -passes='print,loop(loop-rotate),print' -disable-output 2>&1 | FileCheck -check-prefixes CHECK-SCEV,CHECK-SCEV-NOK %s +; FIXME (crashes): opt < %s -passes='loop(canon-freeze),loop(loop-rotate),function(bounds-checking)' -disable-output + +; Verify that we get the same SCEV expressions after loop-rotate, regardless if we invalidate scalar-evolution before the final printing or not. +; FIXME: As indicated by CHECK-SCEV-OK vs CHECK-SCEV-NOK this isn't currently true (PR51981). +; +; CHECK-SCEV: Classifying expressions for: @test_memcpy_1 +; CHECK-SCEV: %div210 = load i32, i32* @offset, align 1 +; CHECK-SCEV: --> %div210 U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond109: Variant, %for.body215: Invariant } +; CHECK-SCEV: %conv211 = trunc i32 %div210 to i16 +; CHECK-SCEV: --> (trunc i32 %div210 to i16) U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond109: Variant, %for.body215: Invariant } +; CHECK-SCEV: %inc2243 = phi i16 [ %conv211, %for.body215.lr.ph ], [ %inc224, %for.body215 ] +; CHECK-SCEV: --> {(trunc i32 %div210 to i16),+,1}<%for.body215> U: full-set S: full-set Exits: (-1 + (700 umax (1 + (trunc i32 %div210 to i16)))) LoopDispositions: { %for.body215: Computable, %for.cond109: Variant } +; +; CHECK-SCEV: Classifying expressions for: @test_memcpy_1 +; CHECK-SCEV: %div2101 = load i32, i32* @offset, align 1 +; CHECK-SCEV: --> %div2101 U: full-set S: full-set +; CHECK-SCEV: %div2102 = phi i32 [ %div2101, %for.body215.lr.ph.lr.ph ], [ %div210, %crit_edge ] +; CHECK-SCEV: --> %div2102 U: full-set S: full-set Exits: <> LoopDispositions: { %for.body215.lr.ph: Variant, %for.body215: Invariant } +; CHECK-SCEV: %conv211 = trunc i32 %div2102 to i16 +; CHECK-SCEV-OK: --> (trunc i32 %div2102 to i16) U: full-set S: full-set Exits: <> LoopDispositions: { %for.body215.lr.ph: Variant, %for.body215: Invariant } +; CHECK-SCEV-NOK: --> (trunc i32 %div210 to i16) U: full-set S: full-set Exits: <> LoopDispositions: { %for.body215.lr.ph: Variant, %for.body215: Invariant } +; CHECK-SCEV: %inc2243 = phi i16 [ %conv211, %for.body215.lr.ph ], [ %inc224, %for.body215 ] +; CHECK-SCEV-OK: --> {(trunc i32 %div2102 to i16),+,1}<%for.body215> U: full-set S: full-set Exits: (-1 + (700 umax (1 + (trunc i32 %div2102 to i16)))) LoopDispositions: { %for.body215: Computable, %for.body215.lr.ph: Variant } +; CHECK-SCEV-NOK: --> {(trunc i32 %div210 to i16),+,1}<%for.body215> U: full-set S: full-set Exits: (-1 + (700 umax (1 + (trunc i32 %div210 to i16)))) LoopDispositions: { %for.body215: Computable, %for.body215.lr.ph: Variant } + + +@offset = external dso_local global i32, align 1 +@cm_array = internal global [11263 x i32] zeroinitializer, align 1 + +define void @test_memcpy_1(i1 %a) { +entry: + br label %for.cond109 + +for.cond109: ; preds = %crit_edge, %entry + %div210 = load i32, i32* @offset, align 1 + br i1 %a, label %exit, label %for.body215.lr.ph + +for.body215.lr.ph: ; preds = %for.cond109 + %conv211 = trunc i32 %div210 to i16 + br label %for.body215 + +for.body215: ; preds = %for.body215, %for.body215.lr.ph + %inc2243 = phi i16 [ %conv211, %for.body215.lr.ph ], [ %inc224, %for.body215 ] + %idxprom221 = zext i16 %inc2243 to i32 + %arrayidx222 = getelementptr inbounds [11263 x i32], [11263 x i32]* @cm_array, i32 0, i32 %idxprom221 + store i32 7, i32* %arrayidx222, align 1 + %inc224 = add i16 %inc2243, 1 + %cmp213 = icmp ult i16 %inc224, 700 + br i1 %cmp213, label %for.body215, label %crit_edge + +crit_edge: ; preds = %for.body215 + br label %for.cond109 + +exit: ; preds = %for.cond109 + ret void +} +