2019-04-17 12:52:47 +08:00
|
|
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
|
|
; RUN: opt -S -loop-predication -loop-predication-predicate-widenable-branches-to-deopt=true < %s 2>&1 | FileCheck %s
|
2021-08-26 04:19:18 +08:00
|
|
|
; RUN: opt -S -passes='require<scalar-evolution>,loop-mssa(loop-predication)' -verify-memoryssa -loop-predication-predicate-widenable-branches-to-deopt=true < %s 2>&1 | FileCheck %s
|
|
|
|
; RUN: opt -S -passes='require<scalar-evolution>,require<branch-prob>,loop-mssa(loop-predication)' -verify-memoryssa -loop-predication-predicate-widenable-branches-to-deopt=true < %s 2>&1 | FileCheck %s
|
2019-04-17 12:52:47 +08:00
|
|
|
|
|
|
|
declare void @llvm.experimental.guard(i1, ...)
|
|
|
|
|
|
|
|
define i32 @unsigned_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) {
|
|
|
|
; CHECK-LABEL: @unsigned_loop_0_to_n_ult_check(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1:![0-9]+]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp eq i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds = icmp ult i32 %i, %length
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @unsigned_loop_0_to_n_ule_latch_ult_check(i32* %array, i32 %length, i32 %n) {
|
|
|
|
; CHECK-LABEL: @unsigned_loop_0_to_n_ule_latch_ult_check(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[N]], [[LENGTH:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ule i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp eq i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds = icmp ult i32 %i, %length
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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 ule i32 %i.next, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @unsigned_loop_0_to_n_ugt_check(i32* %array, i32 %length, i32 %n) {
|
|
|
|
; CHECK-LABEL: @unsigned_loop_0_to_n_ugt_check(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp eq i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds = icmp ugt i32 %length, %i
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @signed_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) {
|
|
|
|
; CHECK-LABEL: @signed_loop_0_to_n_ult_check(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp sle i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds = icmp ult i32 %i, %length
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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 slt i32 %i.next, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @signed_loop_0_to_n_ult_check_length_range_known(i32* %array, i32* %length.ptr, i32 %n) {
|
|
|
|
; CHECK-LABEL: @signed_loop_0_to_n_ult_check_length_range_known(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, !range [[RNG2:![0-9]+]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH]]
|
2021-10-28 07:00:05 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i1 true, [[TMP0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
2021-10-28 07:00:05 +08:00
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]]
|
|
|
|
; CHECK-NEXT: br i1 [[TMP2]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp sle i32 %n, 0
|
|
|
|
%length = load i32, i32* %length.ptr, !range !1
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds = icmp ult i32 %i, %length
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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 slt i32 %i.next, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @signed_loop_0_to_n_inverse_latch_predicate(i32* %array, i32 %length, i32 %n) {
|
|
|
|
; CHECK-LABEL: @signed_loop_0_to_n_inverse_latch_predicate(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp sle i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds = icmp ult i32 %i, %length
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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 sgt i32 %i.next, %n
|
|
|
|
br i1 %continue, label %exit, label %loop, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @signed_loop_0_to_n_sle_latch_ult_check(i32* %array, i32 %length, i32 %n) {
|
|
|
|
; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_ult_check(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp sle i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds = icmp ult i32 %i, %length
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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 sle i32 %i.next, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @signed_loop_0_to_n_preincrement_latch_check(i32* %array, i32 %length, i32 %n) {
|
|
|
|
; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 0, [[LENGTH]]
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp sle i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds = icmp ult i32 %i, %length
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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 i32 %i, 1
|
|
|
|
%continue = icmp slt i32 %i, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(i32* %array, i32 %length, i32 %n) {
|
|
|
|
; CHECK-LABEL: @signed_loop_0_to_n_preincrement_latch_check_postincrement_guard_check(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -2
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp sle i32 [[N]], [[TMP0]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]]
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp sle i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i.next = add i32 %i, 1
|
|
|
|
%within.bounds = icmp ult i32 %i.next, %length
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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
|
|
|
|
%continue = icmp slt i32 %i, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @signed_loop_0_to_n_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) {
|
|
|
|
; CHECK-LABEL: @signed_loop_0_to_n_sle_latch_offset_ult_check(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], -1
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[N]], [[TMP0]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 1, [[LENGTH]]
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp sle i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i.offset = add i32 %i, 1
|
|
|
|
%within.bounds = icmp ult i32 %i.offset, %length
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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 i32 %i, 1
|
|
|
|
%continue = icmp sle i32 %i.next, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(i32* %array, i32 %length, i32 %n) {
|
|
|
|
; CHECK-LABEL: @signed_loop_0_to_n_offset_sle_latch_offset_ult_check(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i32 [[N]], [[LENGTH:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 1, [[LENGTH]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[I_NEXT_OFFSET:%.*]] = add i32 [[I_NEXT]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp sle i32 [[I_NEXT_OFFSET]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp sle i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i.offset = add i32 %i, 1
|
|
|
|
%within.bounds = icmp ult i32 %i.offset, %length
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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 i32 %i, 1
|
|
|
|
%i.next.offset = add i32 %i.next, 1
|
|
|
|
%continue = icmp sle i32 %i.next.offset, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @unsupported_latch_pred_loop_0_to_n(i32* %array, i32 %length, i32 %n) {
|
|
|
|
; CHECK-LABEL: @unsupported_latch_pred_loop_0_to_n(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ne i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp sle i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds = icmp ult i32 %i, %length
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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 nsw i32 %i, 1
|
|
|
|
%continue = icmp ne i32 %i.next, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @signed_loop_0_to_n_unsupported_iv_step(i32* %array, i32 %length, i32 %n) {
|
|
|
|
; CHECK-LABEL: @signed_loop_0_to_n_unsupported_iv_step(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 2
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp sle i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds = icmp ult i32 %i, %length
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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 nsw i32 %i, 2
|
|
|
|
%continue = icmp slt i32 %i.next, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @signed_loop_0_to_n_equal_iv_range_check(i32* %array, i32 %length, i32 %n) {
|
|
|
|
; CHECK-LABEL: @signed_loop_0_to_n_equal_iv_range_check(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp sle i32 [[N]], [[LENGTH:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 1
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp sle i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%j = phi i32 [ %j.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds = icmp ult i32 %j, %length
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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
|
|
|
|
%j.next = add nsw i32 %j, 1
|
|
|
|
%i.next = add nsw i32 %i, 1
|
|
|
|
%continue = icmp slt i32 %i.next, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @signed_loop_start_to_n_offset_iv_range_check(i32* %array, i32 %start.i, i32 %start.j, i32 %length, i32 %n) {
|
|
|
|
; CHECK-LABEL: @signed_loop_start_to_n_offset_iv_range_check(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[LENGTH:%.*]], [[START_I:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], [[START_J:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp sle i32 [[N]], [[TMP1]]
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i32 [[START_J]], [[LENGTH]]
|
|
|
|
; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[TMP2]]
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ [[START_I]], [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ [[START_J]], [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[J_NEXT]] = add i32 [[J]], 1
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp sle i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ %start.i, %loop.preheader ]
|
|
|
|
%j = phi i32 [ %j.next, %guarded ], [ %start.j, %loop.preheader ]
|
|
|
|
%within.bounds = icmp ult i32 %j, %length
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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
|
|
|
|
%j.next = add i32 %j, 1
|
|
|
|
%i.next = add i32 %i, 1
|
|
|
|
%continue = icmp slt i32 %i.next, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @signed_loop_0_to_n_different_iv_types(i32* %array, i16 %length, i32 %n) {
|
|
|
|
; CHECK-LABEL: @signed_loop_0_to_n_different_iv_types(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[J:%.*]] = phi i16 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i16 [[J]], [[LENGTH:%.*]]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[J_NEXT]] = add i16 [[J]], 1
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp sle i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%j = phi i16 [ %j.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds = icmp ult i16 %j, %length
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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
|
|
|
|
%j.next = add i16 %j, 1
|
|
|
|
%i.next = add i32 %i, 1
|
|
|
|
%continue = icmp slt i32 %i.next, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @signed_loop_0_to_n_different_iv_strides(i32* %array, i32 %length, i32 %n) {
|
|
|
|
; CHECK-LABEL: @signed_loop_0_to_n_different_iv_strides(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[J:%.*]] = phi i32 [ [[J_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[J]], [[LENGTH:%.*]]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 2
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp sle i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%j = phi i32 [ %j.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds = icmp ult i32 %j, %length
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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
|
|
|
|
%j.next = add nsw i32 %j, 2
|
|
|
|
%i.next = add nsw i32 %i, 1
|
|
|
|
%continue = icmp slt i32 %i.next, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @two_range_checks(i32* %array.1, i32 %length.1, i32* %array.2, i32 %length.2, i32 %n) {
|
|
|
|
; CHECK-LABEL: @two_range_checks(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_2]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_1]]
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[TMP2]], [[TMP5]]
|
|
|
|
; CHECK-NEXT: [[TMP7:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP7]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp eq i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds.1 = icmp ult i32 %i, %length.1
|
|
|
|
%within.bounds.2 = icmp ult i32 %i, %length.2
|
|
|
|
%within.bounds = and i1 %within.bounds.1, %within.bounds.2
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%i.i64 = zext i32 %i to i64
|
|
|
|
%array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64
|
|
|
|
%array.1.i = load i32, i32* %array.1.i.ptr, align 4
|
|
|
|
%loop.acc.1 = add i32 %loop.acc, %array.1.i
|
|
|
|
%array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64
|
|
|
|
%array.2.i = load i32, i32* %array.2.i.ptr, align 4
|
|
|
|
%loop.acc.next = add i32 %loop.acc.1, %array.2.i
|
|
|
|
%i.next = add nuw i32 %i, 1
|
|
|
|
%continue = icmp ult i32 %i.next, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @three_range_checks(i32* %array.1, i32 %length.1, i32* %array.2, i32 %length.2, i32* %array.3, i32 %length.3, i32 %n) {
|
|
|
|
; CHECK-LABEL: @three_range_checks(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_3]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_2]]
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
|
|
|
|
; CHECK-NEXT: [[TMP6:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP7:%.*]] = icmp ult i32 0, [[LENGTH_1]]
|
|
|
|
; CHECK-NEXT: [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]]
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP9:%.*]] = and i1 [[TMP2]], [[TMP5]]
|
|
|
|
; CHECK-NEXT: [[TMP10:%.*]] = and i1 [[TMP9]], [[TMP8]]
|
|
|
|
; CHECK-NEXT: [[TMP11:%.*]] = and i1 [[TMP10]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP11]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_3:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_3_I:%.*]] = load i32, i32* [[ARRAY_3_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp eq i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds.1 = icmp ult i32 %i, %length.1
|
|
|
|
%within.bounds.2 = icmp ult i32 %i, %length.2
|
|
|
|
%within.bounds.3 = icmp ult i32 %i, %length.3
|
|
|
|
%within.bounds.1.and.2 = and i1 %within.bounds.1, %within.bounds.2
|
|
|
|
%within.bounds = and i1 %within.bounds.1.and.2, %within.bounds.3
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%i.i64 = zext i32 %i to i64
|
|
|
|
%array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64
|
|
|
|
%array.1.i = load i32, i32* %array.1.i.ptr, align 4
|
|
|
|
%loop.acc.1 = add i32 %loop.acc, %array.1.i
|
|
|
|
%array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64
|
|
|
|
%array.2.i = load i32, i32* %array.2.i.ptr, align 4
|
|
|
|
%loop.acc.2 = add i32 %loop.acc.1, %array.2.i
|
|
|
|
%array.3.i.ptr = getelementptr inbounds i32, i32* %array.3, i64 %i.i64
|
|
|
|
%array.3.i = load i32, i32* %array.3.i.ptr, align 4
|
|
|
|
%loop.acc.next = add i32 %loop.acc.2, %array.3.i
|
|
|
|
%i.next = add nuw i32 %i, 1
|
|
|
|
%continue = icmp ult i32 %i.next, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @three_guards(i32* %array.1, i32 %length.1, i32* %array.2, i32 %length.2, i32* %array.3, i32 %length.3, i32 %n) {
|
|
|
|
; CHECK-LABEL: @three_guards(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_1:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_1]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ule i32 [[N]], [[LENGTH_2:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i32 0, [[LENGTH_2]]
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP3]]
|
|
|
|
; CHECK-NEXT: [[TMP6:%.*]] = icmp ule i32 [[N]], [[LENGTH_3:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP7:%.*]] = icmp ult i32 0, [[LENGTH_3]]
|
|
|
|
; CHECK-NEXT: [[TMP8:%.*]] = and i1 [[TMP7]], [[TMP6]]
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED6:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED6]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP9:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP9]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_1_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_1:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_1_I:%.*]] = load i32, i32* [[ARRAY_1_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_1:%.*]] = add i32 [[LOOP_ACC]], [[ARRAY_1_I]]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND4:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP10:%.*]] = and i1 [[TMP5]], [[WIDENABLE_COND4]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP10]], label [[GUARDED1:%.*]], label [[DEOPT2:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt2:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL3]]
|
|
|
|
; CHECK: guarded1:
|
|
|
|
; CHECK-NEXT: [[ARRAY_2_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_2:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_2_I:%.*]] = load i32, i32* [[ARRAY_2_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_2:%.*]] = add i32 [[LOOP_ACC_1]], [[ARRAY_2_I]]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND9:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP11:%.*]] = and i1 [[TMP8]], [[WIDENABLE_COND9]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP11]], label [[GUARDED6]], label [[DEOPT7:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt7:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL8:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL8]]
|
|
|
|
; CHECK: guarded6:
|
|
|
|
; CHECK-NEXT: [[ARRAY_3_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY_3:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_3_I:%.*]] = load i32, i32* [[ARRAY_3_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC_2]], [[ARRAY_3_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED6]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp eq i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded6, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded6 ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded6 ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds.1 = icmp ult i32 %i, %length.1
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds.1, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%i.i64 = zext i32 %i to i64
|
|
|
|
%array.1.i.ptr = getelementptr inbounds i32, i32* %array.1, i64 %i.i64
|
|
|
|
%array.1.i = load i32, i32* %array.1.i.ptr, align 4
|
|
|
|
%loop.acc.1 = add i32 %loop.acc, %array.1.i
|
|
|
|
%within.bounds.2 = icmp ult i32 %i, %length.2
|
|
|
|
%widenable_cond4 = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond5 = and i1 %within.bounds.2, %widenable_cond4
|
|
|
|
br i1 %exiplicit_guard_cond5, label %guarded1, label %deopt2, !prof !0
|
|
|
|
|
|
|
|
deopt2: ; preds = %guarded
|
|
|
|
%deoptcall3 = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall3
|
|
|
|
|
|
|
|
guarded1: ; preds = %guarded
|
|
|
|
%array.2.i.ptr = getelementptr inbounds i32, i32* %array.2, i64 %i.i64
|
|
|
|
%array.2.i = load i32, i32* %array.2.i.ptr, align 4
|
|
|
|
%loop.acc.2 = add i32 %loop.acc.1, %array.2.i
|
|
|
|
%within.bounds.3 = icmp ult i32 %i, %length.3
|
|
|
|
%widenable_cond9 = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond10 = and i1 %within.bounds.3, %widenable_cond9
|
|
|
|
br i1 %exiplicit_guard_cond10, label %guarded6, label %deopt7, !prof !0
|
|
|
|
|
|
|
|
deopt7: ; preds = %guarded1
|
|
|
|
%deoptcall8 = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall8
|
|
|
|
|
|
|
|
guarded6: ; preds = %guarded1
|
|
|
|
%array.3.i.ptr = getelementptr inbounds i32, i32* %array.3, i64 %i.i64
|
|
|
|
%array.3.i = load i32, i32* %array.3.i.ptr, align 4
|
|
|
|
%loop.acc.next = add i32 %loop.acc.2, %array.3.i
|
|
|
|
%i.next = add nuw i32 %i, 1
|
|
|
|
%continue = icmp ult i32 %i.next, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded6, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded6 ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @unsigned_loop_0_to_n_unrelated_condition(i32* %array, i32 %length, i32 %n, i32 %x) {
|
|
|
|
; CHECK-LABEL: @unsigned_loop_0_to_n_unrelated_condition(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[UNRELATED_COND:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH]]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[UNRELATED_COND]], [[TMP2]]
|
|
|
|
; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp eq i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds = icmp ult i32 %i, %length
|
|
|
|
%unrelated.cond = icmp ult i32 %x, %length
|
|
|
|
%guard.cond = and i1 %within.bounds, %unrelated.cond
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %guard.cond, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @test_no_widened_conditions(i32* %array, i32 %length, i32 %n, i32 %x1, i32 %x2, i32 %x3) {
|
|
|
|
; CHECK-LABEL: @test_no_widened_conditions(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[UNRELATED_COND_1:%.*]] = icmp eq i32 [[X1:%.*]], [[I]]
|
|
|
|
; CHECK-NEXT: [[UNRELATED_COND_2:%.*]] = icmp eq i32 [[X2:%.*]], [[I]]
|
|
|
|
; CHECK-NEXT: [[UNRELATED_COND_3:%.*]] = icmp eq i32 [[X3:%.*]], [[I]]
|
|
|
|
; CHECK-NEXT: [[UNRELATED_COND_AND_1:%.*]] = and i1 [[UNRELATED_COND_1]], [[UNRELATED_COND_2]]
|
|
|
|
; CHECK-NEXT: [[GUARD_COND:%.*]] = and i1 [[UNRELATED_COND_AND_1]], [[UNRELATED_COND_3]]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[GUARD_COND]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp eq i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%unrelated.cond.1 = icmp eq i32 %x1, %i
|
|
|
|
%unrelated.cond.2 = icmp eq i32 %x2, %i
|
|
|
|
%unrelated.cond.3 = icmp eq i32 %x3, %i
|
|
|
|
%unrelated.cond.and.1 = and i1 %unrelated.cond.1, %unrelated.cond.2
|
|
|
|
%guard.cond = and i1 %unrelated.cond.and.1, %unrelated.cond.3
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %guard.cond, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @signed_loop_start_to_n_loop_variant_bound(i32* %array, i32 %x, i32 %start, i32 %n) {
|
|
|
|
; CHECK-LABEL: @signed_loop_start_to_n_loop_variant_bound(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[BOUND:%.*]] = add i32 [[I]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[BOUND]]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WITHIN_BOUNDS]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp sle i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ %start, %loop.preheader ]
|
|
|
|
%bound = add i32 %i, %x
|
|
|
|
%within.bounds = icmp ult i32 %i, %bound
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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 nsw i32 %i, 1
|
|
|
|
%continue = icmp slt i32 %i.next, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @signed_loop_start_to_n_non_monotonic_predicate(i32* %array, i32 %x, i32 %start, i32 %n) {
|
|
|
|
; CHECK-LABEL: @signed_loop_start_to_n_non_monotonic_predicate(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp sle i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ [[START:%.*]], [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[GUARD_COND:%.*]] = icmp eq i32 [[I]], [[X:%.*]]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[GUARD_COND]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp sle i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ %start, %loop.preheader ]
|
|
|
|
%guard.cond = icmp eq i32 %i, %x
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %guard.cond, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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 nsw i32 %i, 1
|
|
|
|
%continue = icmp slt i32 %i.next, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @unsigned_loop_0_to_n_hoist_length(i32* %array, i16 %length.i16, i32 %n) {
|
|
|
|
; CHECK-LABEL: @unsigned_loop_0_to_n_hoist_length(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[LENGTH_I16:%.*]] to i32
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i32 [[N]], [[TMP0]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 0, [[TMP0]]
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]]
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp eq i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%length = zext i16 %length.i16 to i32
|
|
|
|
%within.bounds = icmp ult i32 %i, %length
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @unsigned_loop_0_to_n_cant_hoist_length(i32* %array, i32 %length, i32 %divider, i32 %n) {
|
|
|
|
; CHECK-LABEL: @unsigned_loop_0_to_n_cant_hoist_length(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[LENGTH_UDIV:%.*]] = udiv i32 [[LENGTH:%.*]], [[DIVIDER:%.*]]
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
[LoopPredication] Allow predication of loop invariant computations (within the loop)
The purpose of this patch is to eliminate a pass ordering dependence between LoopPredication and LICM. To understand the purpose, consider the following snippet of code inside some loop 'L' with IV 'i'
A = _a.length;
guard (i < A)
a = _a[i]
B = _b.length;
guard (i < B);
b = _b[i];
...
Z = _z.length;
guard (i < Z)
z = _z[i]
accum += a + b + ... + z;
Today, we need LICM to hoist the length loads, LoopPredication to make the guards loop invariant, and TrivialUnswitch to eliminate the loop invariant guard to establish must execute for the next length load. Today, if we can't prove speculation safety, we'd have to iterate these three passes 26 times to reduce this example down to the minimal form.
Using the fact that the array lengths are known to be invariant, we can short circuit this iteration. By forming the loop invariant form of all the guards at once, we remove the need for LoopPredication from the iterative cycle. At the moment, we'd still have to iterate LICM and TrivialUnswitch; we'll leave that part for later.
As a secondary benefit, this allows LoopPred to expose peeling oppurtunities in a much more obvious manner. See the udiv test changes as an example. If the udiv was not hoistable (i.e. we couldn't prove speculation safety) this would be an example where peeling becomes obviously profitable whereas it wasn't before.
A couple of subtleties in the implementation:
- SCEV's isSafeToExpand guarantees speculation safety (i.e. let's us expand at a new point). It is not a precondition for expansion if we know the SCEV corresponds to a Value which dominates the requested expansion point.
- SCEV's isLoopInvariant returns true for expressions which compute the same value across all iterations executed, regardless of where the original Value is located. (i.e. it can be in the loop) This implies we have a speculation burden to prove before expanding them outside loops.
- invariant_loads and AA->pointsToConstantMemory are two cases that SCEV currently does not handle, but meets the SCEV definition of invariance. I plan to sink this part into SCEV once this has baked for a bit.
Differential Revision: https://reviews.llvm.org/D60093
llvm-svn: 358684
2019-04-19 00:33:17 +08:00
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH_UDIV]]
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH_UDIV]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp eq i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%length.udiv = udiv i32 %length, %divider
|
|
|
|
%within.bounds = icmp ult i32 %i, %length.udiv
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
%exiplicit_guard_cond = and i1 %within.bounds, %widenable_cond
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
|
|
|
|
|
|
|
; Make sure that if we're going to consider a branch widenable, that the
|
|
|
|
; call to widenable condition is actually present.
|
|
|
|
define i32 @negative_WC_required(i32* %array, i32 %length, i32 %n, i1 %unrelated) {
|
|
|
|
; CHECK-LABEL: @negative_WC_required(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
|
|
|
|
; CHECK-NEXT: [[NOT_WIDENABLE:%.*]] = and i1 [[WITHIN_BOUNDS]], [[UNRELATED:%.*]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[NOT_WIDENABLE]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-04-17 12:52:47 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: ret i32 0
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp eq i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop:
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds = icmp ult i32 %i, %length
|
|
|
|
%not_widenable = and i1 %within.bounds, %unrelated
|
|
|
|
br i1 %not_widenable, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt:
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%i.i64 = zext i32 %i to i64
|
|
|
|
%array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
|
|
|
|
store i32 0, i32* %array.i.ptr, align 4
|
|
|
|
%i.next = add nuw i32 %i, 1
|
|
|
|
%continue = icmp ult i32 %i.next, %n
|
|
|
|
br i1 %continue, label %loop, label %exit, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
ret i32 0
|
|
|
|
}
|
|
|
|
|
2019-11-22 02:44:13 +08:00
|
|
|
define i32 @swapped_wb(i32* %array, i32 %length, i32 %n) {
|
|
|
|
; CHECK-LABEL: @swapped_wb(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
|
|
|
|
; CHECK: loop.preheader:
|
|
|
|
; CHECK-NEXT: [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i32 [[N]], [[LENGTH:%.*]]
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 0, [[LENGTH]]
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[TMP0]]
|
|
|
|
; CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
|
|
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
|
|
; CHECK: loop:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
|
|
|
; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0]]
|
2019-11-22 02:44:13 +08:00
|
|
|
; CHECK: deopt:
|
|
|
|
; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
; CHECK-NEXT: ret i32 [[DEOPTCALL]]
|
|
|
|
; CHECK: guarded:
|
|
|
|
; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
|
|
|
|
; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
|
|
|
|
; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
|
|
|
|
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
|
|
|
|
; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
|
2021-10-27 20:58:40 +08:00
|
|
|
; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]], !prof [[PROF1]]
|
2019-11-22 02:44:13 +08:00
|
|
|
; CHECK: exit.loopexit:
|
|
|
|
; CHECK-NEXT: [[LOOP_ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
|
|
|
|
; CHECK-NEXT: br label [[EXIT]]
|
|
|
|
; CHECK: exit:
|
|
|
|
; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[LOOP_ACC_NEXT_LCSSA]], [[EXIT_LOOPEXIT]] ]
|
|
|
|
; CHECK-NEXT: ret i32 [[RESULT]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp5 = icmp eq i32 %n, 0
|
|
|
|
br i1 %tmp5, label %exit, label %loop.preheader
|
|
|
|
|
|
|
|
loop.preheader: ; preds = %entry
|
|
|
|
%widenable_cond = call i1 @llvm.experimental.widenable.condition()
|
|
|
|
br label %loop
|
|
|
|
|
|
|
|
loop: ; preds = %guarded, %loop.preheader
|
|
|
|
%loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
|
|
|
|
%within.bounds = icmp ult i32 %i, %length
|
|
|
|
%exiplicit_guard_cond = and i1 %widenable_cond, %within.bounds
|
|
|
|
br i1 %exiplicit_guard_cond, label %guarded, label %deopt, !prof !0
|
|
|
|
|
|
|
|
deopt: ; preds = %loop
|
|
|
|
%deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
|
|
|
|
ret i32 %deoptcall
|
|
|
|
|
|
|
|
guarded: ; preds = %loop
|
|
|
|
%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, !prof !2
|
|
|
|
|
|
|
|
exit: ; preds = %guarded, %entry
|
|
|
|
%result = phi i32 [ 0, %entry ], [ %loop.acc.next, %guarded ]
|
|
|
|
ret i32 %result
|
|
|
|
}
|
2019-04-17 12:52:47 +08:00
|
|
|
|
|
|
|
declare i32 @llvm.experimental.deoptimize.i32(...)
|
|
|
|
|
|
|
|
; Function Attrs: inaccessiblememonly nounwind
|
|
|
|
declare i1 @llvm.experimental.widenable.condition() #0
|
|
|
|
|
|
|
|
attributes #0 = { inaccessiblememonly nounwind }
|
|
|
|
|
|
|
|
!0 = !{!"branch_weights", i32 1048576, i32 1}
|
|
|
|
!1 = !{i32 1, i32 -2147483648}
|
|
|
|
!2 = !{!"branch_weights", i32 1024, i32 1}
|