Skip to content

Commit

Permalink
[IndVars] Canonicalize comparisons between non-negative values and in…
Browse files Browse the repository at this point in the history
…dvars

-If there is a IndVar which is known to be non-negative, and there is a value which is also non-negative,
then signed and unsigned comparisons between them produce the same result. Both of those can be
seen in the same loop. To allow other optimizations to simplify them, we turn all instructions like

  %c = icmp slt i32 %iv, %b
to

  %c = icmp ult i32 %iv, %b

if both %iv and %b are known to be non-negative.

Differential Revision: https://reviews.llvm.org/D34979

llvm-svn: 307126
  • Loading branch information
Max Kazantsev committed Jul 5, 2017
1 parent 9d5571a commit 80bc4a5
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 6 deletions.
4 changes: 4 additions & 0 deletions llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,10 @@ void SimplifyIndvar::eliminateIVComparison(ICmpInst *ICmp, Value *IVOperand) {
ICmp->setPredicate(InvariantPredicate);
ICmp->setOperand(0, NewLHS);
ICmp->setOperand(1, NewRHS);
} else if (ICmpInst::isSigned(Pred) &&
SE->isKnownNonNegative(S) && SE->isKnownNonNegative(X)) {
DEBUG(dbgs() << "INDVARS: Turn to unsigned comparison: " << *ICmp << '\n');
ICmp->setPredicate(ICmpInst::getUnsignedPredicate(Pred));
} else
return;

Expand Down
6 changes: 3 additions & 3 deletions llvm/test/Analysis/ScalarEvolution/guards.ll
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ entry:
loop:
; CHECK: loop:
; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]
; CHECK: %iv.inc.cmp = icmp slt i32 %iv.inc, %len
; CHECK: %iv.inc.cmp = icmp ult i32 %iv.inc, %len
; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
; CHECK: leave:

Expand All @@ -41,7 +41,7 @@ leave:

define void @test_2(i32 %n, i32* %len_buf) {
; CHECK-LABEL: @test_2(
; CHECK: [[LEN_SEXT:%[^ ]+]] = sext i32 %len to i64
; CHECK: [[LEN_ZEXT:%[^ ]+]] = zext i32 %len to i64
; CHECK: br label %loop

entry:
Expand All @@ -52,7 +52,7 @@ loop:
; CHECK: loop:
; CHECK: %indvars.iv = phi i64 [ %indvars.iv.next, %loop ], [ 0, %entry ]
; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
; CHECK: %iv.inc.cmp = icmp slt i64 %indvars.iv.next, [[LEN_SEXT]]
; CHECK: %iv.inc.cmp = icmp ult i64 %indvars.iv.next, [[LEN_ZEXT]]
; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ]
; CHECK: leave:

Expand Down
52 changes: 52 additions & 0 deletions llvm/test/Transforms/IndVarSimplify/canonicalize-cmp.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
; RUN: opt -S -indvars < %s | FileCheck %s

; Check that we replace signed comparisons between non-negative values with
; unsigned comparisons if we can.

target datalayout = "n8:16:32:64"

define i32 @test_01(i32 %a, i32 %b, i32* %p) {

; CHECK-LABEL: @test_01(
; CHECK-NOT: icmp slt
; CHECK: %cmp1 = icmp ult i32 %iv, 100
; CHECK: %cmp2 = icmp ult i32 %iv, 100
; CHECK-NOT: %cmp3
; CHECK: %exitcond = icmp ne i32 %iv.next, 1000

entry:
br label %loop.entry

loop.entry:
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.be ]
%cmp1 = icmp slt i32 %iv, 100
br i1 %cmp1, label %b1, label %b2

b1:
store i32 %iv, i32* %p
br label %merge

b2:
store i32 %a, i32* %p
br label %merge

merge:
%cmp2 = icmp ult i32 %iv, 100
br i1 %cmp2, label %b3, label %b4

b3:
store i32 %iv, i32* %p
br label %loop.be

b4:
store i32 %b, i32* %p
br label %loop.be

loop.be:
%iv.next = add i32 %iv, 1
%cmp3 = icmp slt i32 %iv.next, 1000
br i1 %cmp3, label %loop.entry, label %exit

exit:
ret i32 %iv
}
4 changes: 2 additions & 2 deletions llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ return:
; Indvars should not turn the second loop into an infinite one.

; CHECK-LABEL: @func_11(
; CHECK: %tmp5 = icmp slt i32 %__key6.0, 10
; CHECK: %tmp5 = icmp ult i32 %__key6.0, 10
; CHECK-NOT: br i1 true, label %noassert68, label %unrolledend

define i32 @func_11() nounwind uwtable {
Expand Down Expand Up @@ -163,7 +163,7 @@ declare void @llvm.trap() noreturn nounwind

; In this case the second loop only has a single iteration, fold the header away
; CHECK-LABEL: @func_12(
; CHECK: %tmp5 = icmp slt i32 %__key6.0, 10
; CHECK: %tmp5 = icmp ult i32 %__key6.0, 10
; CHECK: br i1 true, label %noassert68, label %unrolledend
define i32 @func_12() nounwind uwtable {
entry:
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/IndVarSimplify/widen-loop-comp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ for.end:
; CHECK-LABEL: @test2
; CHECK: for.body4.us
; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
; CHECK: %cmp2.us = icmp slt i64
; CHECK: %cmp2.us = icmp ult i64
; CHECK-NOT: %2 = trunc i64 %indvars.iv.next to i32
; CHECK-NOT: %cmp2.us = icmp slt i32

Expand Down

0 comments on commit 80bc4a5

Please sign in to comment.