From 6f5229d7da594d63ee954346e06d3e508f9ee07a Mon Sep 17 00:00:00 2001 From: Max Kazantsev Date: Wed, 1 Nov 2017 13:21:56 +0000 Subject: [PATCH] Revert rL311205 "[IRCE] Fix buggy behavior in Clamp" This patch reverts rL311205 that was initially a wrong fix. The real problem was in intersection of signed and unsigned ranges (see rL316552), and the patch being reverted masked the problem instead of fixing it. By now, the test against which rL311205 was made works OK even without this code. This revert patch also contains a test case that demonstrates incorrect behavior caused by rL311205: it is caused by incorrect choise of signed max instead of unsigned. llvm-svn: 317088 --- .../Scalar/InductiveRangeCheckElimination.cpp | 3 +- llvm/test/Transforms/IRCE/clamp.ll | 67 ++++++++++++++++++- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp b/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp index d7361c03f02a..01f7a969ba92 100644 --- a/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp +++ b/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp @@ -1132,8 +1132,7 @@ LoopConstrainer::calculateSubRanges(bool IsSignedPredicate) const { } auto Clamp = [this, Smallest, Greatest, IsSignedPredicate](const SCEV *S) { - bool MaybeNegativeValues = IsSignedPredicate || !SE.isKnownNonNegative(S); - return MaybeNegativeValues + return IsSignedPredicate ? SE.getSMaxExpr(Smallest, SE.getSMinExpr(Greatest, S)) : SE.getUMaxExpr(Smallest, SE.getUMinExpr(Greatest, S)); }; diff --git a/llvm/test/Transforms/IRCE/clamp.ll b/llvm/test/Transforms/IRCE/clamp.ll index ea5abc1e2732..5215ba9d9e8b 100644 --- a/llvm/test/Transforms/IRCE/clamp.ll +++ b/llvm/test/Transforms/IRCE/clamp.ll @@ -3,9 +3,13 @@ ; The test demonstrates that incorrect behavior of Clamp may lead to incorrect ; calculation of post-loop exit condition. -; CHECK: irce: in function test: constrained Loop at depth 1 containing: %loop
,%in_bounds,%not_zero +; CHECK-LABEL: irce: in function test_01: constrained Loop at depth 1 containing: %loop
,%in_bounds,%not_zero +; CHECK-LABEL: irce: in function test_02: constrained Loop at depth 1 containing: %loop
,%in_bounds + +define void @test_01() { + +; CHECK-LABEL: test_01 -define void @test() { entry: %indvars.iv.next467 = add nuw nsw i64 2, 1 %length.i167 = load i32, i32 addrspace(1)* undef, align 8 @@ -62,3 +66,62 @@ in_bounds: ; preds = %loop %tmp107 = icmp ult i64 %indvars.iv.next, 2 br i1 %tmp107, label %not_zero, label %exit } + +define void @test_02() { + +; CHECK-LABEL: test_02 +; CHECK-NOT: br i1 false, label %loop.preloop.preheader, label %preloop.pseudo.exit +; CHECK-NOT: postloop +; CHECK: entry: +; CHECK-NEXT: br i1 true, label %loop.preloop.preheader, label %preloop.pseudo.exit +; CHECK: mainloop: +; CHECK-NEXT: br label %loop +; CHECK: loop: +; CHECK-NEXT: %iv1 = phi i64 [ %iv1.preloop.copy, %mainloop ], [ %iv1.next, %in_bounds ] +; CHECK-NEXT: %iv2 = phi i64 [ %iv2.preloop.copy, %mainloop ], [ %iv2.next, %in_bounds ] +; CHECK-NEXT: %iv2.offset = add i64 %iv2, 1 +; CHECK-NEXT: %rc = icmp ult i64 %iv2.offset, 400 +; CHECK-NEXT: br i1 true, label %in_bounds, label %bci_321.loopexit1 +; CHECK: in_bounds: +; CHECK-NEXT: %iv1.next = add nuw nsw i64 %iv1, 2 +; CHECK-NEXT: %iv2.next = add nuw nsw i64 %iv2, 2 +; CHECK-NEXT: %cond = icmp ugt i64 %iv1, 204 +; CHECK-NEXT: br i1 %cond, label %bci_321.loopexit1, label %loop +; CHECK: loop.preloop: +; CHECK-NEXT: %iv1.preloop = phi i64 [ %iv1.next.preloop, %in_bounds.preloop ], [ 3, %loop.preloop.preheader ] +; CHECK-NEXT: %iv2.preloop = phi i64 [ %iv2.next.preloop, %in_bounds.preloop ], [ 4294967295, %loop.preloop.preheader ] +; CHECK-NEXT: %iv2.offset.preloop = add i64 %iv2.preloop, 1 +; CHECK-NEXT: %rc.preloop = icmp ult i64 %iv2.offset.preloop, 400 +; CHECK-NEXT: br i1 %rc.preloop, label %in_bounds.preloop, label %bci_321.loopexit +; CHECK: in_bounds.preloop: +; CHECK-NEXT: %iv1.next.preloop = add nuw nsw i64 %iv1.preloop, 2 +; CHECK-NEXT: %iv2.next.preloop = add nuw nsw i64 %iv2.preloop, 2 +; CHECK-NEXT: %cond.preloop = icmp ugt i64 %iv1.preloop, 204 +; CHECK-NEXT: [[C0:%[^ ]+]] = icmp ult i64 %iv1.preloop, 205 +; CHECK-NEXT: [[C1:%[^ ]+]] = xor i1 [[C0]], true +; CHECK-NEXT: br i1 [[C1]], label %preloop.exit.selector, label %loop.preloop +; CHECK: preloop.pseudo.exit: +; CHECK-NEXT: %iv1.preloop.copy = phi i64 [ 3, %entry ], [ %iv1.next.preloop.lcssa, %preloop.exit.selector ] +; CHECK-NEXT: %iv2.preloop.copy = phi i64 [ 4294967295, %entry ], [ %iv2.next.preloop.lcssa, %preloop.exit.selector ] +; CHECK-NEXT: %indvar.end = phi i64 [ 1, %entry ], [ %iv1.preloop.lcssa, %preloop.exit.selector ] +; CHECK-NEXT: br label %mainloop + +entry: + br label %loop + +loop: ; preds = %in_bounds, %entry + %iv1 = phi i64 [ 3, %entry ], [ %iv1.next, %in_bounds ] + %iv2 = phi i64 [ 4294967295, %entry ], [ %iv2.next, %in_bounds ] + %iv2.offset = add i64 %iv2, 1 + %rc = icmp ult i64 %iv2.offset, 400 + br i1 %rc, label %in_bounds, label %bci_321 + +bci_321: ; preds = %in_bounds, %loop + ret void + +in_bounds: ; preds = %loop + %iv1.next = add nuw nsw i64 %iv1, 2 + %iv2.next = add nuw nsw i64 %iv2, 2 + %cond = icmp ugt i64 %iv1, 204 + br i1 %cond, label %bci_321, label %loop +}