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
This commit is contained in:
Max Kazantsev 2017-11-01 13:21:56 +00:00
parent 687982c181
commit 6f5229d7da
2 changed files with 66 additions and 4 deletions

View File

@ -1132,8 +1132,7 @@ LoopConstrainer::calculateSubRanges(bool IsSignedPredicate) const {
} }
auto Clamp = [this, Smallest, Greatest, IsSignedPredicate](const SCEV *S) { auto Clamp = [this, Smallest, Greatest, IsSignedPredicate](const SCEV *S) {
bool MaybeNegativeValues = IsSignedPredicate || !SE.isKnownNonNegative(S); return IsSignedPredicate
return MaybeNegativeValues
? SE.getSMaxExpr(Smallest, SE.getSMinExpr(Greatest, S)) ? SE.getSMaxExpr(Smallest, SE.getSMinExpr(Greatest, S))
: SE.getUMaxExpr(Smallest, SE.getUMinExpr(Greatest, S)); : SE.getUMaxExpr(Smallest, SE.getUMinExpr(Greatest, S));
}; };

View File

@ -3,9 +3,13 @@
; The test demonstrates that incorrect behavior of Clamp may lead to incorrect ; The test demonstrates that incorrect behavior of Clamp may lead to incorrect
; calculation of post-loop exit condition. ; calculation of post-loop exit condition.
; CHECK: irce: in function test: constrained Loop at depth 1 containing: %loop<header><exiting>,%in_bounds<exiting>,%not_zero<latch><exiting> ; CHECK-LABEL: irce: in function test_01: constrained Loop at depth 1 containing: %loop<header><exiting>,%in_bounds<exiting>,%not_zero<latch><exiting>
; CHECK-LABEL: irce: in function test_02: constrained Loop at depth 1 containing: %loop<header><exiting>,%in_bounds<latch><exiting>
define void @test_01() {
; CHECK-LABEL: test_01
define void @test() {
entry: entry:
%indvars.iv.next467 = add nuw nsw i64 2, 1 %indvars.iv.next467 = add nuw nsw i64 2, 1
%length.i167 = load i32, i32 addrspace(1)* undef, align 8 %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 %tmp107 = icmp ult i64 %indvars.iv.next, 2
br i1 %tmp107, label %not_zero, label %exit 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
}