blob: a0f46fb6ed908209469a0745feccd08359f5cd45 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -S -passes='loop(loop-reduce)' -mtriple=riscv64 < %s | FileCheck %s --check-prefix=BASE
; RUN: opt -S -passes='loop(loop-reduce)' -mtriple=riscv64 -mattr=+experimental-zibi < %s | FileCheck %s --check-prefix=ZIBI
; LSR only changes relational exits when the target prefers the exact exit
; value as an equality immediate. The BASE checks ensure the default target
; retains the relational form.
define void @increment_to_17(ptr %p, i32 %start) {
; BASE-LABEL: define void @increment_to_17(
; BASE-SAME: ptr [[P:%.*]], i32 [[START:%.*]]) {
; BASE-NEXT: [[ENTRY:.*:]]
; BASE-NEXT: [[ENTER:%.*]] = icmp slt i32 [[START]], 17
; BASE-NEXT: br i1 [[ENTER]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
; BASE: [[LOOP_PREHEADER]]:
; BASE-NEXT: br label %[[LOOP:.*]]
; BASE: [[LOOP]]:
; BASE-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
; BASE-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; BASE-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
; BASE-NEXT: [[CONTINUE:%.*]] = icmp slt i32 [[IV]], 16
; BASE-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
; BASE: [[EXIT_LOOPEXIT]]:
; BASE-NEXT: br label %[[EXIT]]
; BASE: [[EXIT]]:
; BASE-NEXT: ret void
;
; ZIBI-LABEL: define void @increment_to_17(
; ZIBI-SAME: ptr [[P:%.*]], i32 [[START:%.*]]) #[[ATTR0:[0-9]+]] {
; ZIBI-NEXT: [[ENTRY:.*:]]
; ZIBI-NEXT: [[ENTER:%.*]] = icmp slt i32 [[START]], 17
; ZIBI-NEXT: br i1 [[ENTER]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
; ZIBI: [[LOOP_PREHEADER]]:
; ZIBI-NEXT: br label %[[LOOP:.*]]
; ZIBI: [[LOOP]]:
; ZIBI-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
; ZIBI-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; ZIBI-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
; ZIBI-NEXT: [[LSR_EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], 17
; ZIBI-NEXT: br i1 [[LSR_EXITCOND]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
; ZIBI: [[EXIT_LOOPEXIT]]:
; ZIBI-NEXT: br label %[[EXIT]]
; ZIBI: [[EXIT]]:
; ZIBI-NEXT: ret void
;
entry:
%enter = icmp slt i32 %start, 17
br i1 %enter, label %loop, label %exit
loop:
%iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
store volatile i32 %iv, ptr %p
%iv.next = add i32 %iv, 1
%continue = icmp slt i32 %iv, 16
br i1 %continue, label %loop, label %exit
exit:
ret void
}
define void @decrement_to_17(ptr %p, i32 %start) {
; BASE-LABEL: define void @decrement_to_17(
; BASE-SAME: ptr [[P:%.*]], i32 [[START:%.*]]) {
; BASE-NEXT: [[ENTRY:.*:]]
; BASE-NEXT: [[ENTER:%.*]] = icmp sgt i32 [[START]], 17
; BASE-NEXT: br i1 [[ENTER]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
; BASE: [[LOOP_PREHEADER]]:
; BASE-NEXT: br label %[[LOOP:.*]]
; BASE: [[LOOP]]:
; BASE-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
; BASE-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; BASE-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1
; BASE-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[IV]], 18
; BASE-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
; BASE: [[EXIT_LOOPEXIT]]:
; BASE-NEXT: br label %[[EXIT]]
; BASE: [[EXIT]]:
; BASE-NEXT: ret void
;
; ZIBI-LABEL: define void @decrement_to_17(
; ZIBI-SAME: ptr [[P:%.*]], i32 [[START:%.*]]) #[[ATTR0]] {
; ZIBI-NEXT: [[ENTRY:.*:]]
; ZIBI-NEXT: [[ENTER:%.*]] = icmp sgt i32 [[START]], 17
; ZIBI-NEXT: br i1 [[ENTER]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
; ZIBI: [[LOOP_PREHEADER]]:
; ZIBI-NEXT: br label %[[LOOP:.*]]
; ZIBI: [[LOOP]]:
; ZIBI-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
; ZIBI-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; ZIBI-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1
; ZIBI-NEXT: [[LSR_EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], 17
; ZIBI-NEXT: br i1 [[LSR_EXITCOND]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
; ZIBI: [[EXIT_LOOPEXIT]]:
; ZIBI-NEXT: br label %[[EXIT]]
; ZIBI: [[EXIT]]:
; ZIBI-NEXT: ret void
;
entry:
%enter = icmp sgt i32 %start, 17
br i1 %enter, label %loop, label %exit
loop:
%iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
store volatile i32 %iv, ptr %p
%iv.next = add i32 %iv, -1
%continue = icmp sgt i32 %iv, 18
br i1 %continue, label %loop, label %exit
exit:
ret void
}
define void @decrement_by_two_to_17(ptr %p) {
; BASE-LABEL: define void @decrement_by_two_to_17(
; BASE-SAME: ptr [[P:%.*]]) {
; BASE-NEXT: [[ENTRY:.*]]:
; BASE-NEXT: br label %[[LOOP:.*]]
; BASE: [[LOOP]]:
; BASE-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[LOOP]] ], [ 1003, %[[ENTRY]] ]
; BASE-NEXT: [[TMP0:%.*]] = add i32 [[LSR_IV]], -2
; BASE-NEXT: store volatile i32 [[TMP0]], ptr [[P]], align 4
; BASE-NEXT: [[LSR_IV_NEXT]] = add nsw i32 [[LSR_IV]], -2
; BASE-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[LSR_IV_NEXT]], 19
; BASE-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT:.*]]
; BASE: [[EXIT]]:
; BASE-NEXT: ret void
;
; ZIBI-LABEL: define void @decrement_by_two_to_17(
; ZIBI-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
; ZIBI-NEXT: [[ENTRY:.*]]:
; ZIBI-NEXT: br label %[[LOOP:.*]]
; ZIBI: [[LOOP]]:
; ZIBI-NEXT: [[IV:%.*]] = phi i32 [ 1001, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
; ZIBI-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; ZIBI-NEXT: [[IV_NEXT]] = add i32 [[IV]], -2
; ZIBI-NEXT: [[LSR_EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], 17
; ZIBI-NEXT: br i1 [[LSR_EXITCOND]], label %[[LOOP]], label %[[EXIT:.*]]
; ZIBI: [[EXIT]]:
; ZIBI-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i32 [ 1001, %entry ], [ %iv.next, %loop ]
store volatile i32 %iv, ptr %p
%iv.next = add i32 %iv, -2
%continue = icmp sgt i32 %iv, 19
br i1 %continue, label %loop, label %exit
exit:
ret void
}
define void @outside_zibi_immediate_range(ptr %p, i32 %start) {
; BASE-LABEL: define void @outside_zibi_immediate_range(
; BASE-SAME: ptr [[P:%.*]], i32 [[START:%.*]]) {
; BASE-NEXT: [[ENTRY:.*:]]
; BASE-NEXT: [[ENTER:%.*]] = icmp sgt i32 [[START]], 32
; BASE-NEXT: br i1 [[ENTER]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
; BASE: [[LOOP_PREHEADER]]:
; BASE-NEXT: br label %[[LOOP:.*]]
; BASE: [[LOOP]]:
; BASE-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
; BASE-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; BASE-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1
; BASE-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[IV]], 33
; BASE-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
; BASE: [[EXIT_LOOPEXIT]]:
; BASE-NEXT: br label %[[EXIT]]
; BASE: [[EXIT]]:
; BASE-NEXT: ret void
;
; ZIBI-LABEL: define void @outside_zibi_immediate_range(
; ZIBI-SAME: ptr [[P:%.*]], i32 [[START:%.*]]) #[[ATTR0]] {
; ZIBI-NEXT: [[ENTRY:.*:]]
; ZIBI-NEXT: [[ENTER:%.*]] = icmp sgt i32 [[START]], 32
; ZIBI-NEXT: br i1 [[ENTER]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
; ZIBI: [[LOOP_PREHEADER]]:
; ZIBI-NEXT: br label %[[LOOP:.*]]
; ZIBI: [[LOOP]]:
; ZIBI-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
; ZIBI-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; ZIBI-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1
; ZIBI-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[IV]], 33
; ZIBI-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
; ZIBI: [[EXIT_LOOPEXIT]]:
; ZIBI-NEXT: br label %[[EXIT]]
; ZIBI: [[EXIT]]:
; ZIBI-NEXT: ret void
;
entry:
%enter = icmp sgt i32 %start, 32
br i1 %enter, label %loop, label %exit
loop:
%iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
store volatile i32 %iv, ptr %p
%iv.next = add i32 %iv, -1
%continue = icmp sgt i32 %iv, 33
br i1 %continue, label %loop, label %exit
exit:
ret void
}
define void @dynamic_exit_value(ptr %p, i32 %start, i32 %limit) {
; BASE-LABEL: define void @dynamic_exit_value(
; BASE-SAME: ptr [[P:%.*]], i32 [[START:%.*]], i32 [[LIMIT:%.*]]) {
; BASE-NEXT: [[ENTRY:.*:]]
; BASE-NEXT: [[ENTER:%.*]] = icmp sgt i32 [[START]], [[LIMIT]]
; BASE-NEXT: br i1 [[ENTER]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
; BASE: [[LOOP_PREHEADER]]:
; BASE-NEXT: br label %[[LOOP:.*]]
; BASE: [[LOOP]]:
; BASE-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
; BASE-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; BASE-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1
; BASE-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[IV]], [[LIMIT]]
; BASE-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
; BASE: [[EXIT_LOOPEXIT]]:
; BASE-NEXT: br label %[[EXIT]]
; BASE: [[EXIT]]:
; BASE-NEXT: ret void
;
; ZIBI-LABEL: define void @dynamic_exit_value(
; ZIBI-SAME: ptr [[P:%.*]], i32 [[START:%.*]], i32 [[LIMIT:%.*]]) #[[ATTR0]] {
; ZIBI-NEXT: [[ENTRY:.*:]]
; ZIBI-NEXT: [[ENTER:%.*]] = icmp sgt i32 [[START]], [[LIMIT]]
; ZIBI-NEXT: br i1 [[ENTER]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
; ZIBI: [[LOOP_PREHEADER]]:
; ZIBI-NEXT: br label %[[LOOP:.*]]
; ZIBI: [[LOOP]]:
; ZIBI-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
; ZIBI-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; ZIBI-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1
; ZIBI-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[IV]], [[LIMIT]]
; ZIBI-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
; ZIBI: [[EXIT_LOOPEXIT]]:
; ZIBI-NEXT: br label %[[EXIT]]
; ZIBI: [[EXIT]]:
; ZIBI-NEXT: ret void
;
entry:
%enter = icmp sgt i32 %start, %limit
br i1 %enter, label %loop, label %exit
loop:
%iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
store volatile i32 %iv, ptr %p
%iv.next = add i32 %iv, -1
%continue = icmp sgt i32 %iv, %limit
br i1 %continue, label %loop, label %exit
exit:
ret void
}
define void @poison_no_self_wrap(ptr %p) {
; BASE-LABEL: define void @poison_no_self_wrap(
; BASE-SAME: ptr [[P:%.*]]) {
; BASE-NEXT: [[ENTRY:.*]]:
; BASE-NEXT: br label %[[LOOP:.*]]
; BASE: [[LOOP]]:
; BASE-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
; BASE-NEXT: [[COUNT:%.*]] = phi i8 [ -56, %[[ENTRY]] ], [ [[COUNT_NEXT:%.*]], %[[LOOP]] ]
; BASE-NEXT: [[IV_FROZEN:%.*]] = freeze i8 [[IV]]
; BASE-NEXT: store volatile i8 [[IV_FROZEN]], ptr [[P]], align 1
; BASE-NEXT: [[IV_NEXT]] = add nsw i8 [[IV]], 2
; BASE-NEXT: [[COUNT_NEXT]] = add i8 [[COUNT]], -1
; BASE-NEXT: [[CONTINUE:%.*]] = icmp ugt i8 [[COUNT_NEXT]], 0
; BASE-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT:.*]]
; BASE: [[EXIT]]:
; BASE-NEXT: ret void
;
; ZIBI-LABEL: define void @poison_no_self_wrap(
; ZIBI-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
; ZIBI-NEXT: [[ENTRY:.*]]:
; ZIBI-NEXT: br label %[[LOOP:.*]]
; ZIBI: [[LOOP]]:
; ZIBI-NEXT: [[IV:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
; ZIBI-NEXT: [[COUNT:%.*]] = phi i8 [ -56, %[[ENTRY]] ], [ [[COUNT_NEXT:%.*]], %[[LOOP]] ]
; ZIBI-NEXT: [[IV_FROZEN:%.*]] = freeze i8 [[IV]]
; ZIBI-NEXT: store volatile i8 [[IV_FROZEN]], ptr [[P]], align 1
; ZIBI-NEXT: [[IV_NEXT]] = add nsw i8 [[IV]], 2
; ZIBI-NEXT: [[COUNT_NEXT]] = add i8 [[COUNT]], -1
; ZIBI-NEXT: [[CONTINUE:%.*]] = icmp ugt i8 [[COUNT_NEXT]], 0
; ZIBI-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT:.*]]
; ZIBI: [[EXIT]]:
; ZIBI-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i8 [ 0, %entry ], [ %iv.next, %loop ]
%count = phi i8 [ -56, %entry ], [ %count.next, %loop ]
%iv.frozen = freeze i8 %iv
store volatile i8 %iv.frozen, ptr %p
%iv.next = add nsw i8 %iv, 2
%count.next = add i8 %count, -1
%continue = icmp ugt i8 %count.next, 0
br i1 %continue, label %loop, label %exit
exit:
ret void
}
; LSR may drop poison-generating flags when it rewrites the IV. Make sure the
; equality rewrite does not rely on nowrap flags derived from those flags.
define void @drop_poison_on_postinc(ptr %p, i32 %start) {
; BASE-LABEL: define void @drop_poison_on_postinc(
; BASE-SAME: ptr [[P:%.*]], i32 [[START:%.*]]) {
; BASE-NEXT: [[ENTRY:.*:]]
; BASE-NEXT: [[ENTER:%.*]] = icmp sgt i32 [[START]], 17
; BASE-NEXT: br i1 [[ENTER]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
; BASE: [[LOOP_PREHEADER]]:
; BASE-NEXT: br label %[[LOOP:.*]]
; BASE: [[LOOP]]:
; BASE-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
; BASE-NEXT: [[IV_FROZEN:%.*]] = freeze i32 [[IV]]
; BASE-NEXT: store volatile i32 [[IV_FROZEN]], ptr [[P]], align 4
; BASE-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1
; BASE-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[IV]], 18
; BASE-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
; BASE: [[EXIT_LOOPEXIT]]:
; BASE-NEXT: br label %[[EXIT]]
; BASE: [[EXIT]]:
; BASE-NEXT: ret void
;
; ZIBI-LABEL: define void @drop_poison_on_postinc(
; ZIBI-SAME: ptr [[P:%.*]], i32 [[START:%.*]]) #[[ATTR0]] {
; ZIBI-NEXT: [[ENTRY:.*:]]
; ZIBI-NEXT: [[ENTER:%.*]] = icmp sgt i32 [[START]], 17
; ZIBI-NEXT: br i1 [[ENTER]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
; ZIBI: [[LOOP_PREHEADER]]:
; ZIBI-NEXT: br label %[[LOOP:.*]]
; ZIBI: [[LOOP]]:
; ZIBI-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
; ZIBI-NEXT: [[IV_FROZEN:%.*]] = freeze i32 [[IV]]
; ZIBI-NEXT: store volatile i32 [[IV_FROZEN]], ptr [[P]], align 4
; ZIBI-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1
; ZIBI-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], 17
; ZIBI-NEXT: br i1 [[EXITCOND]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
; ZIBI: [[EXIT_LOOPEXIT]]:
; ZIBI-NEXT: br label %[[EXIT]]
; ZIBI: [[EXIT]]:
; ZIBI-NEXT: ret void
;
entry:
%enter = icmp sgt i32 %start, 17
br i1 %enter, label %loop, label %exit
loop:
%iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
%iv.frozen = freeze i32 %iv
store volatile i32 %iv.frozen, ptr %p
%iv.next = add nsw i32 %iv, -1
%continue = icmp sgt i32 %iv, 18
br i1 %continue, label %loop, label %exit
exit:
ret void
}
define void @false_successor_continues(ptr %p) {
; BASE-LABEL: define void @false_successor_continues(
; BASE-SAME: ptr [[P:%.*]]) {
; BASE-NEXT: [[ENTRY:.*]]:
; BASE-NEXT: br label %[[LOOP:.*]]
; BASE: [[LOOP]]:
; BASE-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[LOOP]] ], [ 32, %[[ENTRY]] ]
; BASE-NEXT: [[TMP0:%.*]] = add i32 [[LSR_IV]], -1
; BASE-NEXT: store volatile i32 [[TMP0]], ptr [[P]], align 4
; BASE-NEXT: [[LSR_IV_NEXT]] = add nsw i32 [[LSR_IV]], -1
; BASE-NEXT: [[EXIT_COND:%.*]] = icmp sle i32 [[LSR_IV_NEXT]], 18
; BASE-NEXT: br i1 [[EXIT_COND]], label %[[EXIT:.*]], label %[[LOOP]]
; BASE: [[EXIT]]:
; BASE-NEXT: ret void
;
; ZIBI-LABEL: define void @false_successor_continues(
; ZIBI-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
; ZIBI-NEXT: [[ENTRY:.*]]:
; ZIBI-NEXT: br label %[[LOOP:.*]]
; ZIBI: [[LOOP]]:
; ZIBI-NEXT: [[IV:%.*]] = phi i32 [ 31, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
; ZIBI-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; ZIBI-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1
; ZIBI-NEXT: [[LSR_EXITCOND:%.*]] = icmp eq i32 [[IV_NEXT]], 17
; ZIBI-NEXT: br i1 [[LSR_EXITCOND]], label %[[EXIT:.*]], label %[[LOOP]]
; ZIBI: [[EXIT]]:
; ZIBI-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i32 [ 31, %entry ], [ %iv.next, %loop ]
store volatile i32 %iv, ptr %p
%iv.next = add i32 %iv, -1
%exit.cond = icmp sle i32 %iv, 18
br i1 %exit.cond, label %exit, label %loop
exit:
ret void
}
define void @zero_exit_value(ptr %p, i32 %start) {
; BASE-LABEL: define void @zero_exit_value(
; BASE-SAME: ptr [[P:%.*]], i32 [[START:%.*]]) {
; BASE-NEXT: [[ENTRY:.*:]]
; BASE-NEXT: [[ENTER:%.*]] = icmp sgt i32 [[START]], 0
; BASE-NEXT: br i1 [[ENTER]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
; BASE: [[LOOP_PREHEADER]]:
; BASE-NEXT: br label %[[LOOP:.*]]
; BASE: [[LOOP]]:
; BASE-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
; BASE-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; BASE-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1
; BASE-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[IV]], 0
; BASE-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
; BASE: [[EXIT_LOOPEXIT]]:
; BASE-NEXT: br label %[[EXIT]]
; BASE: [[EXIT]]:
; BASE-NEXT: ret void
;
; ZIBI-LABEL: define void @zero_exit_value(
; ZIBI-SAME: ptr [[P:%.*]], i32 [[START:%.*]]) #[[ATTR0]] {
; ZIBI-NEXT: [[ENTRY:.*:]]
; ZIBI-NEXT: [[ENTER:%.*]] = icmp sgt i32 [[START]], 0
; ZIBI-NEXT: br i1 [[ENTER]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
; ZIBI: [[LOOP_PREHEADER]]:
; ZIBI-NEXT: br label %[[LOOP:.*]]
; ZIBI: [[LOOP]]:
; ZIBI-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
; ZIBI-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; ZIBI-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1
; ZIBI-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[IV]], 0
; ZIBI-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
; ZIBI: [[EXIT_LOOPEXIT]]:
; ZIBI-NEXT: br label %[[EXIT]]
; ZIBI: [[EXIT]]:
; ZIBI-NEXT: ret void
;
entry:
%enter = icmp sgt i32 %start, 0
br i1 %enter, label %loop, label %exit
loop:
%iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
store volatile i32 %iv, ptr %p
%iv.next = add i32 %iv, -1
%continue = icmp sgt i32 %iv, 0
br i1 %continue, label %loop, label %exit
exit:
ret void
}
define void @minus_one_exit_value(ptr %p) {
; BASE-LABEL: define void @minus_one_exit_value(
; BASE-SAME: ptr [[P:%.*]]) {
; BASE-NEXT: [[ENTRY:.*]]:
; BASE-NEXT: br label %[[LOOP:.*]]
; BASE: [[LOOP]]:
; BASE-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[LOOP]] ], [ 33, %[[ENTRY]] ]
; BASE-NEXT: [[TMP0:%.*]] = add i32 [[LSR_IV]], -2
; BASE-NEXT: store volatile i32 [[TMP0]], ptr [[P]], align 4
; BASE-NEXT: [[LSR_IV_NEXT]] = add nsw i32 [[LSR_IV]], -2
; BASE-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[LSR_IV_NEXT]], 1
; BASE-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT:.*]]
; BASE: [[EXIT]]:
; BASE-NEXT: ret void
;
; ZIBI-LABEL: define void @minus_one_exit_value(
; ZIBI-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
; ZIBI-NEXT: [[ENTRY:.*]]:
; ZIBI-NEXT: br label %[[LOOP:.*]]
; ZIBI: [[LOOP]]:
; ZIBI-NEXT: [[IV:%.*]] = phi i32 [ 31, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
; ZIBI-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; ZIBI-NEXT: [[IV_NEXT]] = add i32 [[IV]], -2
; ZIBI-NEXT: [[LSR_EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], -1
; ZIBI-NEXT: br i1 [[LSR_EXITCOND]], label %[[LOOP]], label %[[EXIT:.*]]
; ZIBI: [[EXIT]]:
; ZIBI-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i32 [ 31, %entry ], [ %iv.next, %loop ]
store volatile i32 %iv, ptr %p
%iv.next = add i32 %iv, -2
%continue = icmp sgt i32 %iv, 1
br i1 %continue, label %loop, label %exit
exit:
ret void
}
define void @minus_one_relational_exit(ptr %p) {
; BASE-LABEL: define void @minus_one_relational_exit(
; BASE-SAME: ptr [[P:%.*]]) {
; BASE-NEXT: [[ENTRY:.*]]:
; BASE-NEXT: br label %[[LOOP:.*]]
; BASE: [[LOOP]]:
; BASE-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[LOOP]] ], [ 32, %[[ENTRY]] ]
; BASE-NEXT: [[TMP0:%.*]] = add i32 [[LSR_IV]], -1
; BASE-NEXT: store volatile i32 [[TMP0]], ptr [[P]], align 4
; BASE-NEXT: [[LSR_IV_NEXT]] = add nsw i32 [[LSR_IV]], -1
; BASE-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[LSR_IV_NEXT]], -1
; BASE-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT:.*]]
; BASE: [[EXIT]]:
; BASE-NEXT: ret void
;
; ZIBI-LABEL: define void @minus_one_relational_exit(
; ZIBI-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
; ZIBI-NEXT: [[ENTRY:.*]]:
; ZIBI-NEXT: br label %[[LOOP:.*]]
; ZIBI: [[LOOP]]:
; ZIBI-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[LOOP]] ], [ 32, %[[ENTRY]] ]
; ZIBI-NEXT: [[TMP0:%.*]] = add i32 [[LSR_IV]], -1
; ZIBI-NEXT: store volatile i32 [[TMP0]], ptr [[P]], align 4
; ZIBI-NEXT: [[LSR_IV_NEXT]] = add nsw i32 [[LSR_IV]], -1
; ZIBI-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[LSR_IV_NEXT]], -1
; ZIBI-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT:.*]]
; ZIBI: [[EXIT]]:
; ZIBI-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i32 [ 31, %entry ], [ %iv.next, %loop ]
store volatile i32 %iv, ptr %p
%iv.next = add i32 %iv, -1
%continue = icmp sgt i32 %iv, -1
br i1 %continue, label %loop, label %exit
exit:
ret void
}
define void @shared_condition(ptr %p, i32 %start) {
; BASE-LABEL: define void @shared_condition(
; BASE-SAME: ptr [[P:%.*]], i32 [[START:%.*]]) {
; BASE-NEXT: [[ENTRY:.*:]]
; BASE-NEXT: [[ENTER:%.*]] = icmp sgt i32 [[START]], 17
; BASE-NEXT: br i1 [[ENTER]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
; BASE: [[LOOP_PREHEADER]]:
; BASE-NEXT: br label %[[LOOP:.*]]
; BASE: [[LOOP]]:
; BASE-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
; BASE-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; BASE-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1
; BASE-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[IV]], 18
; BASE-NEXT: call void @use_condition(i1 [[CONTINUE]])
; BASE-NEXT: [[LOOP_TERMCOND:%.*]] = icmp sgt i32 [[IV]], 18
; BASE-NEXT: br i1 [[LOOP_TERMCOND]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
; BASE: [[EXIT_LOOPEXIT]]:
; BASE-NEXT: br label %[[EXIT]]
; BASE: [[EXIT]]:
; BASE-NEXT: ret void
;
; ZIBI-LABEL: define void @shared_condition(
; ZIBI-SAME: ptr [[P:%.*]], i32 [[START:%.*]]) #[[ATTR0]] {
; ZIBI-NEXT: [[ENTRY:.*:]]
; ZIBI-NEXT: [[ENTER:%.*]] = icmp sgt i32 [[START]], 17
; ZIBI-NEXT: br i1 [[ENTER]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
; ZIBI: [[LOOP_PREHEADER]]:
; ZIBI-NEXT: br label %[[LOOP:.*]]
; ZIBI: [[LOOP]]:
; ZIBI-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
; ZIBI-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; ZIBI-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1
; ZIBI-NEXT: [[CONTINUE:%.*]] = icmp sgt i32 [[IV]], 18
; ZIBI-NEXT: call void @use_condition(i1 [[CONTINUE]])
; ZIBI-NEXT: [[LSR_EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], 17
; ZIBI-NEXT: br i1 [[LSR_EXITCOND]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
; ZIBI: [[EXIT_LOOPEXIT]]:
; ZIBI-NEXT: br label %[[EXIT]]
; ZIBI: [[EXIT]]:
; ZIBI-NEXT: ret void
;
entry:
%enter = icmp sgt i32 %start, 17
br i1 %enter, label %loop, label %exit
loop:
%iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
store volatile i32 %iv, ptr %p
%iv.next = add i32 %iv, -1
%continue = icmp sgt i32 %iv, 18
call void @use_condition(i1 %continue)
br i1 %continue, label %loop, label %exit
exit:
ret void
}
define void @increment_to_17_samesign(ptr %p, i32 %start) {
; BASE-LABEL: define void @increment_to_17_samesign(
; BASE-SAME: ptr [[P:%.*]], i32 [[START:%.*]]) {
; BASE-NEXT: [[ENTRY:.*:]]
; BASE-NEXT: [[ENTER:%.*]] = icmp ult i32 [[START]], 17
; BASE-NEXT: br i1 [[ENTER]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
; BASE: [[LOOP_PREHEADER]]:
; BASE-NEXT: br label %[[LOOP:.*]]
; BASE: [[LOOP]]:
; BASE-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
; BASE-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; BASE-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
; BASE-NEXT: [[CONTINUE:%.*]] = icmp samesign ult i32 [[IV]], 16
; BASE-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
; BASE: [[EXIT_LOOPEXIT]]:
; BASE-NEXT: br label %[[EXIT]]
; BASE: [[EXIT]]:
; BASE-NEXT: ret void
;
; ZIBI-LABEL: define void @increment_to_17_samesign(
; ZIBI-SAME: ptr [[P:%.*]], i32 [[START:%.*]]) #[[ATTR0]] {
; ZIBI-NEXT: [[ENTRY:.*:]]
; ZIBI-NEXT: [[ENTER:%.*]] = icmp ult i32 [[START]], 17
; ZIBI-NEXT: br i1 [[ENTER]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
; ZIBI: [[LOOP_PREHEADER]]:
; ZIBI-NEXT: br label %[[LOOP:.*]]
; ZIBI: [[LOOP]]:
; ZIBI-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
; ZIBI-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; ZIBI-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
; ZIBI-NEXT: [[LSR_EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], 17
; ZIBI-NEXT: br i1 [[LSR_EXITCOND]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
; ZIBI: [[EXIT_LOOPEXIT]]:
; ZIBI-NEXT: br label %[[EXIT]]
; ZIBI: [[EXIT]]:
; ZIBI-NEXT: ret void
;
entry:
%enter = icmp ult i32 %start, 17
br i1 %enter, label %loop, label %exit
loop:
%iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
store volatile i32 %iv, ptr %p
%iv.next = add i32 %iv, 1
%continue = icmp samesign ult i32 %iv, 16
br i1 %continue, label %loop, label %exit
exit:
ret void
}
define void @decrement_to_17_samesign(ptr %p, i32 %start) {
; BASE-LABEL: define void @decrement_to_17_samesign(
; BASE-SAME: ptr [[P:%.*]], i32 [[START:%.*]]) {
; BASE-NEXT: [[ENTRY:.*:]]
; BASE-NEXT: [[ENTER:%.*]] = icmp sgt i32 [[START]], 17
; BASE-NEXT: br i1 [[ENTER]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
; BASE: [[LOOP_PREHEADER]]:
; BASE-NEXT: br label %[[LOOP:.*]]
; BASE: [[LOOP]]:
; BASE-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
; BASE-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; BASE-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1
; BASE-NEXT: [[CONTINUE:%.*]] = icmp samesign ugt i32 [[IV]], 18
; BASE-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
; BASE: [[EXIT_LOOPEXIT]]:
; BASE-NEXT: br label %[[EXIT]]
; BASE: [[EXIT]]:
; BASE-NEXT: ret void
;
; ZIBI-LABEL: define void @decrement_to_17_samesign(
; ZIBI-SAME: ptr [[P:%.*]], i32 [[START:%.*]]) #[[ATTR0]] {
; ZIBI-NEXT: [[ENTRY:.*:]]
; ZIBI-NEXT: [[ENTER:%.*]] = icmp sgt i32 [[START]], 17
; ZIBI-NEXT: br i1 [[ENTER]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
; ZIBI: [[LOOP_PREHEADER]]:
; ZIBI-NEXT: br label %[[LOOP:.*]]
; ZIBI: [[LOOP]]:
; ZIBI-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
; ZIBI-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; ZIBI-NEXT: [[IV_NEXT]] = add i32 [[IV]], -1
; ZIBI-NEXT: [[LSR_EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], 17
; ZIBI-NEXT: br i1 [[LSR_EXITCOND]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
; ZIBI: [[EXIT_LOOPEXIT]]:
; ZIBI-NEXT: br label %[[EXIT]]
; ZIBI: [[EXIT]]:
; ZIBI-NEXT: ret void
;
entry:
%enter = icmp sgt i32 %start, 17
br i1 %enter, label %loop, label %exit
loop:
%iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
store volatile i32 %iv, ptr %p
%iv.next = add i32 %iv, -1
%continue = icmp samesign ugt i32 %iv, 18
br i1 %continue, label %loop, label %exit
exit:
ret void
}
define void @decrement_by_two_to_17_samesign(ptr %p) {
; BASE-LABEL: define void @decrement_by_two_to_17_samesign(
; BASE-SAME: ptr [[P:%.*]]) {
; BASE-NEXT: [[ENTRY:.*]]:
; BASE-NEXT: br label %[[LOOP:.*]]
; BASE: [[LOOP]]:
; BASE-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[LOOP]] ], [ 1003, %[[ENTRY]] ]
; BASE-NEXT: [[TMP0:%.*]] = add i32 [[LSR_IV]], -2
; BASE-NEXT: store volatile i32 [[TMP0]], ptr [[P]], align 4
; BASE-NEXT: [[LSR_IV_NEXT]] = add nsw i32 [[LSR_IV]], -2
; BASE-NEXT: [[CONTINUE:%.*]] = icmp samesign ugt i32 [[LSR_IV_NEXT]], 19
; BASE-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT:.*]]
; BASE: [[EXIT]]:
; BASE-NEXT: ret void
;
; ZIBI-LABEL: define void @decrement_by_two_to_17_samesign(
; ZIBI-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
; ZIBI-NEXT: [[ENTRY:.*]]:
; ZIBI-NEXT: br label %[[LOOP:.*]]
; ZIBI: [[LOOP]]:
; ZIBI-NEXT: [[IV:%.*]] = phi i32 [ 1001, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
; ZIBI-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; ZIBI-NEXT: [[IV_NEXT]] = add i32 [[IV]], -2
; ZIBI-NEXT: [[LSR_EXITCOND:%.*]] = icmp ne i32 [[IV_NEXT]], 17
; ZIBI-NEXT: br i1 [[LSR_EXITCOND]], label %[[LOOP]], label %[[EXIT:.*]]
; ZIBI: [[EXIT]]:
; ZIBI-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i32 [ 1001, %entry ], [ %iv.next, %loop ]
store volatile i32 %iv, ptr %p
%iv.next = add i32 %iv, -2
%continue = icmp samesign ugt i32 %iv, 19
br i1 %continue, label %loop, label %exit
exit:
ret void
}
; The IV has period 8 and the exact exit count is also 8. Its exit value was
; already visited on the first iteration, so an equality exit would exit early.
define void @exit_count_reaches_recurrence_period(ptr %p) {
; BASE-LABEL: define void @exit_count_reaches_recurrence_period(
; BASE-SAME: ptr [[P:%.*]]) {
; BASE-NEXT: [[ENTRY:.*]]:
; BASE-NEXT: br label %[[LOOP:.*]]
; BASE: [[LOOP]]:
; BASE-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[LOOP]] ], [ -536870912, %[[ENTRY]] ]
; BASE-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
; BASE-NEXT: [[LIMIT:%.*]] = phi i32 [ -1, %[[ENTRY]] ], [ [[LIMIT_NEXT:%.*]], %[[LOOP]] ]
; BASE-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; BASE-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 536870912
; BASE-NEXT: [[LIMIT_NEXT]] = add nuw i32 [[LIMIT]], -1
; BASE-NEXT: [[LSR_IV_NEXT]] = add i32 [[LSR_IV]], 536870912
; BASE-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[LSR_IV_NEXT]], [[LIMIT]]
; BASE-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT:.*]]
; BASE: [[EXIT]]:
; BASE-NEXT: ret void
;
; ZIBI-LABEL: define void @exit_count_reaches_recurrence_period(
; ZIBI-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
; ZIBI-NEXT: [[ENTRY:.*]]:
; ZIBI-NEXT: br label %[[LOOP:.*]]
; ZIBI: [[LOOP]]:
; ZIBI-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[LOOP]] ], [ -536870912, %[[ENTRY]] ]
; ZIBI-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
; ZIBI-NEXT: [[LIMIT:%.*]] = phi i32 [ -1, %[[ENTRY]] ], [ [[LIMIT_NEXT:%.*]], %[[LOOP]] ]
; ZIBI-NEXT: store volatile i32 [[IV]], ptr [[P]], align 4
; ZIBI-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 536870912
; ZIBI-NEXT: [[LIMIT_NEXT]] = add nuw i32 [[LIMIT]], -1
; ZIBI-NEXT: [[LSR_IV_NEXT]] = add i32 [[LSR_IV]], 536870912
; ZIBI-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[LSR_IV_NEXT]], [[LIMIT]]
; ZIBI-NEXT: br i1 [[CONTINUE]], label %[[LOOP]], label %[[EXIT:.*]]
; ZIBI: [[EXIT]]:
; ZIBI-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
%limit = phi i32 [ -1, %entry ], [ %limit.next, %loop ]
store volatile i32 %iv, ptr %p
%iv.next = add nuw i32 %iv, 536870912
%limit.next = add nuw i32 %limit, -1
%continue = icmp ult i32 %iv, %limit
br i1 %continue, label %loop, label %exit
exit:
ret void
}
declare void @use_condition(i1)