You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.167
Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
parent
e19d552987
commit
b084638f15
1028
external/llvm/test/Transforms/LoopPredication/basic.ll
vendored
1028
external/llvm/test/Transforms/LoopPredication/basic.ll
vendored
File diff suppressed because it is too large
Load Diff
@ -1,217 +0,0 @@
|
||||
; RUN: opt -S -loop-predication < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -passes='require<scalar-evolution>,loop(loop-predication)' < %s 2>&1 | FileCheck %s
|
||||
|
||||
declare void @llvm.experimental.guard(i1, ...)
|
||||
|
||||
define i32 @signed_loop_0_to_n_nested_0_to_l_inner_index_check(i32* %array, i32 %length, i32 %n, i32 %l) {
|
||||
; CHECK-LABEL: @signed_loop_0_to_n_nested_0_to_l_inner_index_check
|
||||
entry:
|
||||
%tmp5 = icmp sle i32 %n, 0
|
||||
br i1 %tmp5, label %exit, label %outer.loop.preheader
|
||||
|
||||
outer.loop.preheader:
|
||||
br label %outer.loop
|
||||
|
||||
outer.loop:
|
||||
%outer.loop.acc = phi i32 [ %outer.loop.acc.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
|
||||
%i = phi i32 [ %i.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
|
||||
%tmp6 = icmp sle i32 %l, 0
|
||||
br i1 %tmp6, label %outer.loop.inc, label %inner.loop.preheader
|
||||
|
||||
inner.loop.preheader:
|
||||
; CHECK: inner.loop.preheader:
|
||||
; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %l, %length
|
||||
; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
|
||||
; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
|
||||
; CHECK-NEXT: br label %inner.loop
|
||||
br label %inner.loop
|
||||
|
||||
inner.loop:
|
||||
; CHECK: inner.loop:
|
||||
; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
|
||||
%inner.loop.acc = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %inner.loop.preheader ]
|
||||
%j = phi i32 [ %j.next, %inner.loop ], [ 0, %inner.loop.preheader ]
|
||||
|
||||
%within.bounds = icmp ult i32 %j, %length
|
||||
call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
|
||||
|
||||
%j.i64 = zext i32 %j to i64
|
||||
%array.j.ptr = getelementptr inbounds i32, i32* %array, i64 %j.i64
|
||||
%array.j = load i32, i32* %array.j.ptr, align 4
|
||||
%inner.loop.acc.next = add i32 %inner.loop.acc, %array.j
|
||||
|
||||
%j.next = add nsw i32 %j, 1
|
||||
%inner.continue = icmp slt i32 %j.next, %l
|
||||
br i1 %inner.continue, label %inner.loop, label %outer.loop.inc
|
||||
|
||||
outer.loop.inc:
|
||||
%outer.loop.acc.next = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %outer.loop ]
|
||||
%i.next = add nsw i32 %i, 1
|
||||
%outer.continue = icmp slt i32 %i.next, %n
|
||||
br i1 %outer.continue, label %outer.loop, label %exit
|
||||
|
||||
exit:
|
||||
%result = phi i32 [ 0, %entry ], [ %outer.loop.acc.next, %outer.loop.inc ]
|
||||
ret i32 %result
|
||||
}
|
||||
|
||||
define i32 @signed_loop_0_to_n_nested_0_to_l_outer_index_check(i32* %array, i32 %length, i32 %n, i32 %l) {
|
||||
; CHECK-LABEL: @signed_loop_0_to_n_nested_0_to_l_outer_index_check
|
||||
entry:
|
||||
%tmp5 = icmp sle i32 %n, 0
|
||||
br i1 %tmp5, label %exit, label %outer.loop.preheader
|
||||
|
||||
outer.loop.preheader:
|
||||
; CHECK: outer.loop.preheader:
|
||||
; CHECK: [[limit_check:[^ ]+]] = icmp sle i32 %n, %length
|
||||
; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
|
||||
; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
|
||||
; CHECK-NEXT: br label %outer.loop
|
||||
br label %outer.loop
|
||||
|
||||
outer.loop:
|
||||
%outer.loop.acc = phi i32 [ %outer.loop.acc.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
|
||||
%i = phi i32 [ %i.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
|
||||
%tmp6 = icmp sle i32 %l, 0
|
||||
br i1 %tmp6, label %outer.loop.inc, label %inner.loop.preheader
|
||||
|
||||
inner.loop.preheader:
|
||||
br label %inner.loop
|
||||
|
||||
inner.loop:
|
||||
; CHECK: inner.loop:
|
||||
; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
|
||||
|
||||
%inner.loop.acc = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %inner.loop.preheader ]
|
||||
%j = phi i32 [ %j.next, %inner.loop ], [ 0, %inner.loop.preheader ]
|
||||
|
||||
%within.bounds = icmp ult i32 %i, %length
|
||||
call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
|
||||
|
||||
%i.i64 = zext i32 %i to i64
|
||||
%array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
|
||||
%array.i = load i32, i32* %array.i.ptr, align 4
|
||||
%inner.loop.acc.next = add i32 %inner.loop.acc, %array.i
|
||||
|
||||
%j.next = add nsw i32 %j, 1
|
||||
%inner.continue = icmp slt i32 %j.next, %l
|
||||
br i1 %inner.continue, label %inner.loop, label %outer.loop.inc
|
||||
|
||||
outer.loop.inc:
|
||||
%outer.loop.acc.next = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %outer.loop ]
|
||||
%i.next = add nsw i32 %i, 1
|
||||
%outer.continue = icmp slt i32 %i.next, %n
|
||||
br i1 %outer.continue, label %outer.loop, label %exit
|
||||
|
||||
exit:
|
||||
%result = phi i32 [ 0, %entry ], [ %outer.loop.acc.next, %outer.loop.inc ]
|
||||
ret i32 %result
|
||||
}
|
||||
|
||||
define i32 @signed_loop_0_to_n_nested_i_to_l_inner_index_check(i32* %array, i32 %length, i32 %n, i32 %l) {
|
||||
; CHECK-LABEL: @signed_loop_0_to_n_nested_i_to_l_inner_index_check
|
||||
entry:
|
||||
%tmp5 = icmp sle i32 %n, 0
|
||||
br i1 %tmp5, label %exit, label %outer.loop.preheader
|
||||
|
||||
outer.loop.preheader:
|
||||
; CHECK: outer.loop.preheader:
|
||||
; CHECK-NEXT: [[limit_check_outer:[^ ]+]] = icmp sle i32 %n, %length
|
||||
; CHECK-NEXT: [[first_iteration_check_outer:[^ ]+]] = icmp ult i32 0, %length
|
||||
; CHECK-NEXT: [[wide_cond_outer:[^ ]+]] = and i1 [[first_iteration_check_outer]], [[limit_check_outer]]
|
||||
; CHECK-NEXT: br label %outer.loop
|
||||
br label %outer.loop
|
||||
|
||||
outer.loop:
|
||||
; CHECK: outer.loop:
|
||||
%outer.loop.acc = phi i32 [ %outer.loop.acc.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
|
||||
%i = phi i32 [ %i.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
|
||||
%tmp6 = icmp sle i32 %l, 0
|
||||
br i1 %tmp6, label %outer.loop.inc, label %inner.loop.preheader
|
||||
|
||||
inner.loop.preheader:
|
||||
; CHECK: inner.loop.preheader:
|
||||
; CHECK: [[limit_check_inner:[^ ]+]] = icmp sle i32 %l, %length
|
||||
; CHECK: br label %inner.loop
|
||||
br label %inner.loop
|
||||
|
||||
inner.loop:
|
||||
; CHECK: inner.loop:
|
||||
; CHECK: [[wide_cond:[^ ]+]] = and i1 [[limit_check_inner]], [[wide_cond_outer]]
|
||||
; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
|
||||
%inner.loop.acc = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %inner.loop.preheader ]
|
||||
%j = phi i32 [ %j.next, %inner.loop ], [ %i, %inner.loop.preheader ]
|
||||
|
||||
%within.bounds = icmp ult i32 %j, %length
|
||||
call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
|
||||
|
||||
%j.i64 = zext i32 %j to i64
|
||||
%array.j.ptr = getelementptr inbounds i32, i32* %array, i64 %j.i64
|
||||
%array.j = load i32, i32* %array.j.ptr, align 4
|
||||
%inner.loop.acc.next = add i32 %inner.loop.acc, %array.j
|
||||
|
||||
%j.next = add nsw i32 %j, 1
|
||||
%inner.continue = icmp slt i32 %j.next, %l
|
||||
br i1 %inner.continue, label %inner.loop, label %outer.loop.inc
|
||||
|
||||
outer.loop.inc:
|
||||
%outer.loop.acc.next = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %outer.loop ]
|
||||
%i.next = add nsw i32 %i, 1
|
||||
%outer.continue = icmp slt i32 %i.next, %n
|
||||
br i1 %outer.continue, label %outer.loop, label %exit
|
||||
|
||||
exit:
|
||||
%result = phi i32 [ 0, %entry ], [ %outer.loop.acc.next, %outer.loop.inc ]
|
||||
ret i32 %result
|
||||
}
|
||||
|
||||
define i32 @cant_expand_guard_check_start(i32* %array, i32 %length, i32 %n, i32 %l, i32 %maybezero) {
|
||||
; CHECK-LABEL: @cant_expand_guard_check_start
|
||||
entry:
|
||||
%tmp5 = icmp sle i32 %n, 0
|
||||
br i1 %tmp5, label %exit, label %outer.loop.preheader
|
||||
|
||||
outer.loop.preheader:
|
||||
br label %outer.loop
|
||||
|
||||
outer.loop:
|
||||
%outer.loop.acc = phi i32 [ %outer.loop.acc.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
|
||||
%i = phi i32 [ %i.next, %outer.loop.inc ], [ 0, %outer.loop.preheader ]
|
||||
%tmp6 = icmp sle i32 %l, 0
|
||||
%div = udiv i32 %i, %maybezero
|
||||
br i1 %tmp6, label %outer.loop.inc, label %inner.loop.preheader
|
||||
|
||||
inner.loop.preheader:
|
||||
; CHECK: inner.loop.preheader:
|
||||
; CHECK: br label %inner.loop
|
||||
br label %inner.loop
|
||||
|
||||
inner.loop:
|
||||
; CHECK: inner.loop:
|
||||
; CHECK: %within.bounds = icmp ult i32 %j, %length
|
||||
; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
|
||||
%inner.loop.acc = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %inner.loop.preheader ]
|
||||
%j = phi i32 [ %j.next, %inner.loop ], [ %div, %inner.loop.preheader ]
|
||||
|
||||
%within.bounds = icmp ult i32 %j, %length
|
||||
call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
|
||||
|
||||
%j.i64 = zext i32 %j to i64
|
||||
%array.j.ptr = getelementptr inbounds i32, i32* %array, i64 %j.i64
|
||||
%array.j = load i32, i32* %array.j.ptr, align 4
|
||||
%inner.loop.acc.next = add i32 %inner.loop.acc, %array.j
|
||||
|
||||
%j.next = add nsw i32 %j, 1
|
||||
%inner.continue = icmp slt i32 %j.next, %l
|
||||
br i1 %inner.continue, label %inner.loop, label %outer.loop.inc
|
||||
|
||||
outer.loop.inc:
|
||||
%outer.loop.acc.next = phi i32 [ %inner.loop.acc.next, %inner.loop ], [ %outer.loop.acc, %outer.loop ]
|
||||
%i.next = add nsw i32 %i, 1
|
||||
%outer.continue = icmp slt i32 %i.next, %n
|
||||
br i1 %outer.continue, label %outer.loop, label %exit
|
||||
|
||||
exit:
|
||||
%result = phi i32 [ 0, %entry ], [ %outer.loop.acc.next, %outer.loop.inc ]
|
||||
ret i32 %result
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
; RUN: opt -S -loop-predication -loop-predication-enable-count-down-loop=true < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -passes='require<scalar-evolution>,loop(loop-predication)' -loop-predication-enable-count-down-loop=true < %s 2>&1 | FileCheck %s
|
||||
|
||||
declare void @llvm.experimental.guard(i1, ...)
|
||||
|
||||
define i32 @signed_reverse_loop_n_to_lower_limit(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) {
|
||||
; CHECK-LABEL: @signed_reverse_loop_n_to_lower_limit(
|
||||
entry:
|
||||
%tmp5 = icmp eq i32 %n, 0
|
||||
br i1 %tmp5, label %exit, label %loop.preheader
|
||||
|
||||
; CHECK: loop.preheader:
|
||||
; CHECK-NEXT: [[range_start:%.*]] = add i32 %n, -1
|
||||
; CHECK-NEXT: [[first_iteration_check:%.*]] = icmp ult i32 [[range_start]], %length
|
||||
; CHECK-NEXT: [[no_wrap_check:%.*]] = icmp sge i32 %lowerlimit, 1
|
||||
; CHECK-NEXT: [[wide_cond:%.*]] = and i1 [[first_iteration_check]], [[no_wrap_check]]
|
||||
loop.preheader:
|
||||
br label %loop
|
||||
|
||||
; CHECK: loop:
|
||||
; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
|
||||
loop:
|
||||
%loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
|
||||
%i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ]
|
||||
%i.next = add nsw i32 %i, -1
|
||||
%within.bounds = icmp ult i32 %i.next, %length
|
||||
call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
|
||||
%i.i64 = zext i32 %i.next to i64
|
||||
%array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
|
||||
%array.i = load i32, i32* %array.i.ptr, align 4
|
||||
%loop.acc.next = add i32 %loop.acc, %array.i
|
||||
%continue = icmp sgt i32 %i, %lowerlimit
|
||||
br i1 %continue, label %loop, label %exit
|
||||
|
||||
exit:
|
||||
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
|
||||
ret i32 %result
|
||||
}
|
||||
|
||||
define i32 @unsigned_reverse_loop_n_to_lower_limit(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) {
|
||||
; CHECK-LABEL: @unsigned_reverse_loop_n_to_lower_limit(
|
||||
entry:
|
||||
%tmp5 = icmp eq i32 %n, 0
|
||||
br i1 %tmp5, label %exit, label %loop.preheader
|
||||
|
||||
; CHECK: loop.preheader:
|
||||
; CHECK-NEXT: [[range_start:%.*]] = add i32 %n, -1
|
||||
; CHECK-NEXT: [[first_iteration_check:%.*]] = icmp ult i32 [[range_start]], %length
|
||||
; CHECK-NEXT: [[no_wrap_check:%.*]] = icmp uge i32 %lowerlimit, 1
|
||||
; CHECK-NEXT: [[wide_cond:%.*]] = and i1 [[first_iteration_check]], [[no_wrap_check]]
|
||||
loop.preheader:
|
||||
br label %loop
|
||||
|
||||
; CHECK: loop:
|
||||
; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
|
||||
loop:
|
||||
%loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
|
||||
%i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ]
|
||||
%i.next = add nsw i32 %i, -1
|
||||
%within.bounds = icmp ult i32 %i.next, %length
|
||||
call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
|
||||
%i.i64 = zext i32 %i.next to i64
|
||||
%array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
|
||||
%array.i = load i32, i32* %array.i.ptr, align 4
|
||||
%loop.acc.next = add i32 %loop.acc, %array.i
|
||||
%continue = icmp ugt i32 %i, %lowerlimit
|
||||
br i1 %continue, label %loop, label %exit
|
||||
|
||||
exit:
|
||||
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
|
||||
ret i32 %result
|
||||
}
|
||||
|
||||
|
||||
; if we predicated the loop, the guard will definitely fail and we will
|
||||
; deoptimize early on.
|
||||
define i32 @unsigned_reverse_loop_n_to_0(i32* %array, i32 %length, i32 %n, i32 %lowerlimit) {
|
||||
; CHECK-LABEL: @unsigned_reverse_loop_n_to_0(
|
||||
entry:
|
||||
%tmp5 = icmp eq i32 %n, 0
|
||||
br i1 %tmp5, label %exit, label %loop.preheader
|
||||
|
||||
; CHECK: loop.preheader:
|
||||
; CHECK-NEXT: [[range_start:%.*]] = add i32 %n, -1
|
||||
; CHECK-NEXT: [[first_iteration_check:%.*]] = icmp ult i32 [[range_start]], %length
|
||||
; CHECK-NEXT: [[wide_cond:%.*]] = and i1 [[first_iteration_check]], false
|
||||
loop.preheader:
|
||||
br label %loop
|
||||
|
||||
; CHECK: loop:
|
||||
; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[wide_cond]], i32 9) [ "deopt"() ]
|
||||
loop:
|
||||
%loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
|
||||
%i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ]
|
||||
%i.next = add nsw i32 %i, -1
|
||||
%within.bounds = icmp ult i32 %i.next, %length
|
||||
call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
|
||||
%i.i64 = zext i32 %i.next to i64
|
||||
%array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
|
||||
%array.i = load i32, i32* %array.i.ptr, align 4
|
||||
%loop.acc.next = add i32 %loop.acc, %array.i
|
||||
%continue = icmp ugt i32 %i, 0
|
||||
br i1 %continue, label %loop, label %exit
|
||||
|
||||
exit:
|
||||
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
|
||||
ret i32 %result
|
||||
}
|
||||
|
||||
; do not loop predicate when the range has step -1 and latch has step 1.
|
||||
define i32 @reverse_loop_range_step_increment(i32 %n, i32* %array, i32 %length) {
|
||||
; CHECK-LABEL: @reverse_loop_range_step_increment(
|
||||
entry:
|
||||
%tmp5 = icmp eq i32 %n, 0
|
||||
br i1 %tmp5, label %exit, label %loop.preheader
|
||||
|
||||
loop.preheader:
|
||||
br label %loop
|
||||
|
||||
; CHECK: loop:
|
||||
; CHECK: llvm.experimental.guard(i1 %within.bounds, i32 9)
|
||||
loop:
|
||||
%loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
|
||||
%i = phi i32 [ %i.next, %loop ], [ %n, %loop.preheader ]
|
||||
%irc = phi i32 [ %i.inc, %loop ], [ 1, %loop.preheader ]
|
||||
%i.inc = add nuw nsw i32 %irc, 1
|
||||
%within.bounds = icmp ult i32 %irc, %length
|
||||
call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ]
|
||||
%i.i64 = zext i32 %irc to i64
|
||||
%array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
|
||||
%array.i = load i32, i32* %array.i.ptr, align 4
|
||||
%i.next = add nsw i32 %i, -1
|
||||
%loop.acc.next = add i32 %loop.acc, %array.i
|
||||
%continue = icmp ugt i32 %i, 65534
|
||||
br i1 %continue, label %loop, label %exit
|
||||
|
||||
exit:
|
||||
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
|
||||
ret i32 %result
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
; RUN: opt -S -loop-predication < %s 2>&1 | FileCheck %s
|
||||
; RUN: opt -S -passes='require<scalar-evolution>,loop(loop-predication)' < %s 2>&1 | FileCheck %s
|
||||
|
||||
declare void @llvm.experimental.guard(i1, ...)
|
||||
|
||||
define i32 @test_visited(i32* %array, i32 %length, i32 %n, i32 %x) {
|
||||
; CHECK-LABEL: @test_visited
|
||||
entry:
|
||||
%tmp5 = icmp eq i32 %n, 0
|
||||
br i1 %tmp5, label %exit, label %loop.preheader
|
||||
|
||||
loop.preheader:
|
||||
; CHECK: loop.preheader:
|
||||
; CHECK: [[limit_check:[^ ]+]] = icmp ule i32 %n, %length
|
||||
; CHECK-NEXT: [[first_iteration_check:[^ ]+]] = icmp ult i32 0, %length
|
||||
; CHECK-NEXT: [[wide_cond:[^ ]+]] = and i1 [[first_iteration_check]], [[limit_check]]
|
||||
; CHECK-NEXT: br label %loop
|
||||
br label %loop
|
||||
|
||||
loop:
|
||||
; CHECK: loop:
|
||||
; CHECK: %unrelated.cond = icmp eq i32 %x, %i
|
||||
; CHECK: [[guard_cond:[^ ]+]] = and i1 %unrelated.cond, [[wide_cond]]
|
||||
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[guard_cond]], i32 9) [ "deopt"() ]
|
||||
%loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ]
|
||||
%i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ]
|
||||
%within.bounds = icmp ult i32 %i, %length
|
||||
%unrelated.cond = icmp eq i32 %x, %i
|
||||
%guard.cond.2 = and i1 %within.bounds, %unrelated.cond
|
||||
%guard.cond.3 = and i1 %guard.cond.2, %unrelated.cond
|
||||
%guard.cond.4 = and i1 %guard.cond.3, %guard.cond.2
|
||||
%guard.cond.5 = and i1 %guard.cond.4, %guard.cond.3
|
||||
%guard.cond.6 = and i1 %guard.cond.5, %guard.cond.4
|
||||
%guard.cond.7 = and i1 %guard.cond.6, %guard.cond.5
|
||||
%guard.cond.8 = and i1 %guard.cond.7, %guard.cond.6
|
||||
%guard.cond.9 = and i1 %guard.cond.8, %guard.cond.7
|
||||
%guard.cond.10 = and i1 %guard.cond.9, %guard.cond.8
|
||||
%guard.cond.11 = and i1 %guard.cond.10, %guard.cond.9
|
||||
%guard.cond.12 = and i1 %guard.cond.11, %guard.cond.10
|
||||
%guard.cond.13 = and i1 %guard.cond.12, %guard.cond.11
|
||||
%guard.cond.14 = and i1 %guard.cond.13, %guard.cond.12
|
||||
%guard.cond.15 = and i1 %guard.cond.14, %guard.cond.13
|
||||
%guard.cond.16 = and i1 %guard.cond.15, %guard.cond.14
|
||||
%guard.cond.17 = and i1 %guard.cond.16, %guard.cond.15
|
||||
%guard.cond.18 = and i1 %guard.cond.17, %guard.cond.16
|
||||
%guard.cond.19 = and i1 %guard.cond.18, %guard.cond.17
|
||||
%guard.cond.20 = and i1 %guard.cond.19, %guard.cond.18
|
||||
%guard.cond.21 = and i1 %guard.cond.20, %guard.cond.19
|
||||
%guard.cond.22 = and i1 %guard.cond.21, %guard.cond.20
|
||||
%guard.cond.23 = and i1 %guard.cond.22, %guard.cond.21
|
||||
%guard.cond.24 = and i1 %guard.cond.23, %guard.cond.22
|
||||
%guard.cond.25 = and i1 %guard.cond.24, %guard.cond.23
|
||||
%guard.cond.26 = and i1 %guard.cond.25, %guard.cond.24
|
||||
%guard.cond.27 = and i1 %guard.cond.26, %guard.cond.25
|
||||
%guard.cond.28 = and i1 %guard.cond.27, %guard.cond.26
|
||||
%guard.cond.29 = and i1 %guard.cond.28, %guard.cond.27
|
||||
%guard.cond.30 = and i1 %guard.cond.29, %guard.cond.28
|
||||
%guard.cond.31 = and i1 %guard.cond.30, %guard.cond.29
|
||||
%guard.cond.32 = and i1 %guard.cond.31, %guard.cond.30
|
||||
%guard.cond.33 = and i1 %guard.cond.32, %guard.cond.31
|
||||
%guard.cond.34 = and i1 %guard.cond.33, %guard.cond.32
|
||||
%guard.cond.35 = and i1 %guard.cond.34, %guard.cond.33
|
||||
%guard.cond.36 = and i1 %guard.cond.35, %guard.cond.34
|
||||
%guard.cond.37 = and i1 %guard.cond.36, %guard.cond.35
|
||||
%guard.cond.38 = and i1 %guard.cond.37, %guard.cond.36
|
||||
%guard.cond.39 = and i1 %guard.cond.38, %guard.cond.37
|
||||
%guard.cond.40 = and i1 %guard.cond.39, %guard.cond.38
|
||||
%guard.cond.41 = and i1 %guard.cond.40, %guard.cond.39
|
||||
%guard.cond.42 = and i1 %guard.cond.41, %guard.cond.40
|
||||
%guard.cond.43 = and i1 %guard.cond.42, %guard.cond.41
|
||||
%guard.cond.44 = and i1 %guard.cond.43, %guard.cond.42
|
||||
%guard.cond.45 = and i1 %guard.cond.44, %guard.cond.43
|
||||
%guard.cond.46 = and i1 %guard.cond.45, %guard.cond.44
|
||||
%guard.cond.47 = and i1 %guard.cond.46, %guard.cond.45
|
||||
%guard.cond.48 = and i1 %guard.cond.47, %guard.cond.46
|
||||
%guard.cond.49 = and i1 %guard.cond.48, %guard.cond.47
|
||||
%guard.cond.50 = and i1 %guard.cond.49, %guard.cond.48
|
||||
%guard.cond.51 = and i1 %guard.cond.50, %guard.cond.49
|
||||
%guard.cond.52 = and i1 %guard.cond.51, %guard.cond.50
|
||||
%guard.cond.53 = and i1 %guard.cond.52, %guard.cond.51
|
||||
%guard.cond.54 = and i1 %guard.cond.53, %guard.cond.52
|
||||
%guard.cond.55 = and i1 %guard.cond.54, %guard.cond.53
|
||||
%guard.cond.56 = and i1 %guard.cond.55, %guard.cond.54
|
||||
%guard.cond.57 = and i1 %guard.cond.56, %guard.cond.55
|
||||
%guard.cond.58 = and i1 %guard.cond.57, %guard.cond.56
|
||||
%guard.cond.59 = and i1 %guard.cond.58, %guard.cond.57
|
||||
%guard.cond.60 = and i1 %guard.cond.59, %guard.cond.58
|
||||
%guard.cond.61 = and i1 %guard.cond.60, %guard.cond.59
|
||||
%guard.cond.62 = and i1 %guard.cond.61, %guard.cond.60
|
||||
%guard.cond.63 = and i1 %guard.cond.62, %guard.cond.61
|
||||
%guard.cond.64 = and i1 %guard.cond.63, %guard.cond.62
|
||||
%guard.cond.65 = and i1 %guard.cond.64, %guard.cond.63
|
||||
%guard.cond.66 = and i1 %guard.cond.65, %guard.cond.64
|
||||
%guard.cond.67 = and i1 %guard.cond.66, %guard.cond.65
|
||||
%guard.cond.68 = and i1 %guard.cond.67, %guard.cond.66
|
||||
%guard.cond.69 = and i1 %guard.cond.68, %guard.cond.67
|
||||
%guard.cond.70 = and i1 %guard.cond.69, %guard.cond.68
|
||||
%guard.cond.71 = and i1 %guard.cond.70, %guard.cond.69
|
||||
%guard.cond.72 = and i1 %guard.cond.71, %guard.cond.70
|
||||
%guard.cond.73 = and i1 %guard.cond.72, %guard.cond.71
|
||||
%guard.cond.74 = and i1 %guard.cond.73, %guard.cond.72
|
||||
%guard.cond.75 = and i1 %guard.cond.74, %guard.cond.73
|
||||
%guard.cond.76 = and i1 %guard.cond.75, %guard.cond.74
|
||||
%guard.cond.77 = and i1 %guard.cond.76, %guard.cond.75
|
||||
%guard.cond.78 = and i1 %guard.cond.77, %guard.cond.76
|
||||
%guard.cond.79 = and i1 %guard.cond.78, %guard.cond.77
|
||||
%guard.cond.80 = and i1 %guard.cond.79, %guard.cond.78
|
||||
%guard.cond.81 = and i1 %guard.cond.80, %guard.cond.79
|
||||
%guard.cond.82 = and i1 %guard.cond.81, %guard.cond.80
|
||||
%guard.cond.83 = and i1 %guard.cond.82, %guard.cond.81
|
||||
%guard.cond.84 = and i1 %guard.cond.83, %guard.cond.82
|
||||
%guard.cond.85 = and i1 %guard.cond.84, %guard.cond.83
|
||||
%guard.cond.86 = and i1 %guard.cond.85, %guard.cond.84
|
||||
%guard.cond.87 = and i1 %guard.cond.86, %guard.cond.85
|
||||
%guard.cond.88 = and i1 %guard.cond.87, %guard.cond.86
|
||||
%guard.cond.89 = and i1 %guard.cond.88, %guard.cond.87
|
||||
%guard.cond.90 = and i1 %guard.cond.89, %guard.cond.88
|
||||
%guard.cond.91 = and i1 %guard.cond.90, %guard.cond.89
|
||||
%guard.cond.92 = and i1 %guard.cond.91, %guard.cond.90
|
||||
%guard.cond.93 = and i1 %guard.cond.92, %guard.cond.91
|
||||
%guard.cond.94 = and i1 %guard.cond.93, %guard.cond.92
|
||||
%guard.cond.95 = and i1 %guard.cond.94, %guard.cond.93
|
||||
%guard.cond.96 = and i1 %guard.cond.95, %guard.cond.94
|
||||
%guard.cond.97 = and i1 %guard.cond.96, %guard.cond.95
|
||||
%guard.cond.98 = and i1 %guard.cond.97, %guard.cond.96
|
||||
%guard.cond.99 = and i1 %guard.cond.98, %guard.cond.97
|
||||
call void (i1, ...) @llvm.experimental.guard(i1 %guard.cond.99, i32 9) [ "deopt"() ]
|
||||
|
||||
%i.i64 = zext i32 %i to i64
|
||||
%array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
|
||||
%array.i = load i32, i32* %array.i.ptr, align 4
|
||||
%loop.acc.next = add i32 %loop.acc, %array.i
|
||||
|
||||
%i.next = add nuw i32 %i, 1
|
||||
%continue = icmp ult i32 %i.next, %n
|
||||
br i1 %continue, label %loop, label %exit
|
||||
|
||||
exit:
|
||||
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %loop ]
|
||||
ret i32 %result
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
; RUN: opt -S -loop-predication -loop-predication-enable-iv-truncation=true < %s 2>&1 | FileCheck %s
|
||||
declare void @llvm.experimental.guard(i1, ...)
|
||||
|
||||
declare i32 @length(i8*)
|
||||
|
||||
declare i16 @short_length(i8*)
|
||||
; Consider range check of type i16 and i32, while IV is of type i64
|
||||
; We can loop predicate this because the IV range is within i16 and within i32.
|
||||
define i64 @iv_wider_type_rc_two_narrow_types(i32 %offA, i16 %offB, i8* %arrA, i8* %arrB) {
|
||||
; CHECK-LABEL: iv_wider_type_rc_two_narrow_types
|
||||
entry:
|
||||
; CHECK-LABEL: entry:
|
||||
; CHECK: [[idxB:[^ ]+]] = sub i16 %lengthB, %offB
|
||||
; CHECK-NEXT: [[limit_checkB:[^ ]+]] = icmp ule i16 16, [[idxB]]
|
||||
; CHECK-NEXT: [[first_iteration_checkB:[^ ]+]] = icmp ult i16 %offB, %lengthB
|
||||
; CHECK-NEXT: [[WideChkB:[^ ]+]] = and i1 [[first_iteration_checkB]], [[limit_checkB]]
|
||||
; CHECK-NEXT: [[idxA:[^ ]+]] = sub i32 %lengthA, %offA
|
||||
; CHECK-NEXT: [[limit_checkA:[^ ]+]] = icmp ule i32 16, [[idxA]]
|
||||
; CHECK-NEXT: [[first_iteration_checkA:[^ ]+]] = icmp ult i32 %offA, %lengthA
|
||||
; CHECK-NEXT: [[WideChkA:[^ ]+]] = and i1 [[first_iteration_checkA]], [[limit_checkA]]
|
||||
%lengthA = call i32 @length(i8* %arrA)
|
||||
%lengthB = call i16 @short_length(i8* %arrB)
|
||||
br label %loop
|
||||
|
||||
loop:
|
||||
; CHECK-LABEL: loop:
|
||||
; CHECK: [[invariant_check:[^ ]+]] = and i1 [[WideChkB]], [[WideChkA]]
|
||||
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[invariant_check]], i32 9)
|
||||
%iv = phi i64 [0, %entry ], [ %iv.next, %loop ]
|
||||
%iv.trunc.32 = trunc i64 %iv to i32
|
||||
%iv.trunc.16 = trunc i64 %iv to i16
|
||||
%indexA = add i32 %iv.trunc.32, %offA
|
||||
%indexB = add i16 %iv.trunc.16, %offB
|
||||
%rcA = icmp ult i32 %indexA, %lengthA
|
||||
%rcB = icmp ult i16 %indexB, %lengthB
|
||||
%wide.chk = and i1 %rcA, %rcB
|
||||
call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk, i32 9) [ "deopt"() ]
|
||||
%indexA.ext = zext i32 %indexA to i64
|
||||
%addrA = getelementptr inbounds i8, i8* %arrA, i64 %indexA.ext
|
||||
%eltA = load i8, i8* %addrA
|
||||
%indexB.ext = zext i16 %indexB to i64
|
||||
%addrB = getelementptr inbounds i8, i8* %arrB, i64 %indexB.ext
|
||||
store i8 %eltA, i8* %addrB
|
||||
%iv.next = add nuw nsw i64 %iv, 1
|
||||
%latch.check = icmp ult i64 %iv.next, 16
|
||||
br i1 %latch.check, label %loop, label %exit
|
||||
|
||||
exit:
|
||||
ret i64 %iv
|
||||
}
|
||||
|
||||
|
||||
; Consider an IV of type long and an array access into int array.
|
||||
; IV is of type i64 while the range check operands are of type i32 and i64.
|
||||
define i64 @iv_rc_different_types(i32 %offA, i32 %offB, i8* %arrA, i8* %arrB, i64 %max)
|
||||
{
|
||||
; CHECK-LABEL: iv_rc_different_types
|
||||
entry:
|
||||
; CHECK-LABEL: entry:
|
||||
; CHECK: [[lenB:[^ ]+]] = add i32 %lengthB, -1
|
||||
; CHECK-NEXT: [[idxB:[^ ]+]] = sub i32 [[lenB]], %offB
|
||||
; CHECK-NEXT: [[limit_checkB:[^ ]+]] = icmp ule i32 15, [[idxB]]
|
||||
; CHECK-NEXT: [[first_iteration_checkB:[^ ]+]] = icmp ult i32 %offB, %lengthB
|
||||
; CHECK-NEXT: [[WideChkB:[^ ]+]] = and i1 [[first_iteration_checkB]], [[limit_checkB]]
|
||||
; CHECK-NEXT: [[maxMinusOne:[^ ]+]] = add i64 %max, -1
|
||||
; CHECK-NEXT: [[limit_checkMax:[^ ]+]] = icmp ule i64 15, [[maxMinusOne]]
|
||||
; CHECK-NEXT: [[first_iteration_checkMax:[^ ]+]] = icmp ult i64 0, %max
|
||||
; CHECK-NEXT: [[WideChkMax:[^ ]+]] = and i1 [[first_iteration_checkMax]], [[limit_checkMax]]
|
||||
; CHECK-NEXT: [[lenA:[^ ]+]] = add i32 %lengthA, -1
|
||||
; CHECK-NEXT: [[idxA:[^ ]+]] = sub i32 [[lenA]], %offA
|
||||
; CHECK-NEXT: [[limit_checkA:[^ ]+]] = icmp ule i32 15, [[idxA]]
|
||||
; CHECK-NEXT: [[first_iteration_checkA:[^ ]+]] = icmp ult i32 %offA, %lengthA
|
||||
; CHECK-NEXT: [[WideChkA:[^ ]+]] = and i1 [[first_iteration_checkA]], [[limit_checkA]]
|
||||
%lengthA = call i32 @length(i8* %arrA)
|
||||
%lengthB = call i32 @length(i8* %arrB)
|
||||
br label %loop
|
||||
|
||||
loop:
|
||||
; CHECK-LABEL: loop:
|
||||
; CHECK: [[BandMax:[^ ]+]] = and i1 [[WideChkB]], [[WideChkMax]]
|
||||
; CHECK: [[ABandMax:[^ ]+]] = and i1 [[BandMax]], [[WideChkA]]
|
||||
; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 [[ABandMax]], i32 9)
|
||||
%iv = phi i64 [0, %entry ], [ %iv.next, %loop ]
|
||||
%iv.trunc = trunc i64 %iv to i32
|
||||
%indexA = add i32 %iv.trunc, %offA
|
||||
%indexB = add i32 %iv.trunc, %offB
|
||||
%rcA = icmp ult i32 %indexA, %lengthA
|
||||
%rcIV = icmp ult i64 %iv, %max
|
||||
%wide.chk = and i1 %rcA, %rcIV
|
||||
%rcB = icmp ult i32 %indexB, %lengthB
|
||||
%wide.chk.final = and i1 %wide.chk, %rcB
|
||||
call void (i1, ...) @llvm.experimental.guard(i1 %wide.chk.final, i32 9) [ "deopt"() ]
|
||||
%indexA.ext = zext i32 %indexA to i64
|
||||
%addrA = getelementptr inbounds i8, i8* %arrA, i64 %indexA.ext
|
||||
%eltA = load i8, i8* %addrA
|
||||
%indexB.ext = zext i32 %indexB to i64
|
||||
%addrB = getelementptr inbounds i8, i8* %arrB, i64 %indexB.ext
|
||||
%eltB = load i8, i8* %addrB
|
||||
%result = xor i8 %eltA, %eltB
|
||||
store i8 %result, i8* %addrA
|
||||
%iv.next = add nuw nsw i64 %iv, 1
|
||||
%latch.check = icmp ult i64 %iv, 15
|
||||
br i1 %latch.check, label %loop, label %exit
|
||||
|
||||
exit:
|
||||
ret i64 %iv
|
||||
}
|
||||
|
||||
; cannot narrow the IV to the range type, because we lose information.
|
||||
; for (i64 i= 5; i>= 2; i++)
|
||||
; this loop wraps around after reaching 2^64.
|
||||
define i64 @iv_rc_different_type(i32 %offA, i8* %arrA) {
|
||||
; CHECK-LABEL: iv_rc_different_type
|
||||
entry:
|
||||
%lengthA = call i32 @length(i8* %arrA)
|
||||
br label %loop
|
||||
|
||||
loop:
|
||||
; CHECK-LABEL: loop:
|
||||
; CHECK: %rcA = icmp ult i32 %indexA, %lengthA
|
||||
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %rcA, i32 9)
|
||||
%iv = phi i64 [ 5, %entry ], [ %iv.next, %loop ]
|
||||
%iv.trunc.32 = trunc i64 %iv to i32
|
||||
%indexA = add i32 %iv.trunc.32, %offA
|
||||
%rcA = icmp ult i32 %indexA, %lengthA
|
||||
call void (i1, ...) @llvm.experimental.guard(i1 %rcA, i32 9) [ "deopt"() ]
|
||||
%indexA.ext = zext i32 %indexA to i64
|
||||
%addrA = getelementptr inbounds i8, i8* %arrA, i64 %indexA.ext
|
||||
%eltA = load i8, i8* %addrA
|
||||
%res = add i8 %eltA, 2
|
||||
store i8 %eltA, i8* %addrA
|
||||
%iv.next = add i64 %iv, 1
|
||||
%latch.check = icmp sge i64 %iv.next, 2
|
||||
br i1 %latch.check, label %loop, label %exit
|
||||
|
||||
exit:
|
||||
ret i64 %iv
|
||||
}
|
Reference in New Issue
Block a user