824 lines
29 KiB
LLVM
824 lines
29 KiB
LLVM
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
|
||
|
; RUN: opt < %s -passes=indvars -S | FileCheck %s
|
||
|
; RUN: opt -passes=lcssa,loop-simplify -S < %s | opt -S -passes='require<targetir>,require<scalar-evolution>,require<domtree>,loop(indvars)'
|
||
|
|
||
|
;; --- signed ---
|
||
|
|
||
|
define void @min.signed.1(ptr %a, i32 %a_len, i32 %n) {
|
||
|
; CHECK-LABEL: define void @min.signed.1(
|
||
|
; CHECK-SAME: ptr [[A:%.*]], i32 [[A_LEN:%.*]], i32 [[N:%.*]]) {
|
||
|
; CHECK-NEXT: entry:
|
||
|
; CHECK-NEXT: [[SMIN_CMP:%.*]] = icmp slt i32 [[A_LEN]], [[N]]
|
||
|
; CHECK-NEXT: [[SMIN:%.*]] = select i1 [[SMIN_CMP]], i32 [[A_LEN]], i32 [[N]]
|
||
|
; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp slt i32 0, [[SMIN]]
|
||
|
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
|
||
|
; CHECK: loop.preheader:
|
||
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||
|
; CHECK: loop:
|
||
|
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
||
|
; CHECK-NEXT: [[IDX_INC]] = add nuw nsw i32 [[IDX]], 1
|
||
|
; CHECK-NEXT: br i1 true, label [[OK:%.*]], label [[LATCH]]
|
||
|
; CHECK: ok:
|
||
|
; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
|
||
|
; CHECK-NEXT: store i32 [[IDX]], ptr [[ADDR]], align 4
|
||
|
; CHECK-NEXT: br label [[LATCH]]
|
||
|
; CHECK: latch:
|
||
|
; CHECK-NEXT: [[BE_COND:%.*]] = icmp slt i32 [[IDX_INC]], [[SMIN]]
|
||
|
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
|
||
|
; CHECK: exit.loopexit:
|
||
|
; CHECK-NEXT: br label [[EXIT]]
|
||
|
; CHECK: exit:
|
||
|
; CHECK-NEXT: ret void
|
||
|
;
|
||
|
entry:
|
||
|
%smin.cmp = icmp slt i32 %a_len, %n
|
||
|
%smin = select i1 %smin.cmp, i32 %a_len, i32 %n
|
||
|
%entry.cond = icmp slt i32 0, %smin
|
||
|
br i1 %entry.cond, label %loop, label %exit
|
||
|
|
||
|
loop:
|
||
|
%idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
|
||
|
%idx.inc = add i32 %idx, 1
|
||
|
%in.bounds = icmp slt i32 %idx, %a_len
|
||
|
br i1 %in.bounds, label %ok, label %latch
|
||
|
|
||
|
ok:
|
||
|
%addr = getelementptr i32, ptr %a, i32 %idx
|
||
|
store i32 %idx, ptr %addr
|
||
|
br label %latch
|
||
|
|
||
|
latch:
|
||
|
%be.cond = icmp slt i32 %idx.inc, %smin
|
||
|
br i1 %be.cond, label %loop, label %exit
|
||
|
|
||
|
exit:
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
define void @min.signed.2(ptr %a, i32 %a_len, i32 %n) {
|
||
|
; CHECK-LABEL: define void @min.signed.2(
|
||
|
; CHECK-SAME: ptr [[A:%.*]], i32 [[A_LEN:%.*]], i32 [[N:%.*]]) {
|
||
|
; CHECK-NEXT: entry:
|
||
|
; CHECK-NEXT: [[SMIN_CMP:%.*]] = icmp slt i32 [[A_LEN]], [[N]]
|
||
|
; CHECK-NEXT: [[SMIN:%.*]] = select i1 [[SMIN_CMP]], i32 [[A_LEN]], i32 [[N]]
|
||
|
; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp slt i32 0, [[SMIN]]
|
||
|
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
|
||
|
; CHECK: loop.preheader:
|
||
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||
|
; CHECK: loop:
|
||
|
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
||
|
; CHECK-NEXT: [[IDX_INC]] = add nuw nsw i32 [[IDX]], 1
|
||
|
; CHECK-NEXT: br i1 true, label [[OK:%.*]], label [[LATCH]]
|
||
|
; CHECK: ok:
|
||
|
; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
|
||
|
; CHECK-NEXT: store i32 [[IDX]], ptr [[ADDR]], align 4
|
||
|
; CHECK-NEXT: br label [[LATCH]]
|
||
|
; CHECK: latch:
|
||
|
; CHECK-NEXT: [[BE_COND:%.*]] = icmp slt i32 [[IDX_INC]], [[SMIN]]
|
||
|
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
|
||
|
; CHECK: exit.loopexit:
|
||
|
; CHECK-NEXT: br label [[EXIT]]
|
||
|
; CHECK: exit:
|
||
|
; CHECK-NEXT: ret void
|
||
|
;
|
||
|
entry:
|
||
|
%smin.cmp = icmp slt i32 %a_len, %n
|
||
|
%smin = select i1 %smin.cmp, i32 %a_len, i32 %n
|
||
|
%entry.cond = icmp slt i32 0, %smin
|
||
|
br i1 %entry.cond, label %loop, label %exit
|
||
|
|
||
|
loop:
|
||
|
%idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
|
||
|
%idx.inc = add i32 %idx, 1
|
||
|
%in.bounds = icmp sgt i32 %a_len, %idx
|
||
|
br i1 %in.bounds, label %ok, label %latch
|
||
|
|
||
|
ok:
|
||
|
%addr = getelementptr i32, ptr %a, i32 %idx
|
||
|
store i32 %idx, ptr %addr
|
||
|
br label %latch
|
||
|
|
||
|
latch:
|
||
|
%be.cond = icmp slt i32 %idx.inc, %smin
|
||
|
br i1 %be.cond, label %loop, label %exit
|
||
|
|
||
|
exit:
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
define void @min.signed.3(ptr %a, i32 %n) {
|
||
|
; CHECK-LABEL: define void @min.signed.3(
|
||
|
; CHECK-SAME: ptr [[A:%.*]], i32 [[N:%.*]]) {
|
||
|
; CHECK-NEXT: entry:
|
||
|
; CHECK-NEXT: [[SMIN_CMP:%.*]] = icmp slt i32 42, [[N]]
|
||
|
; CHECK-NEXT: [[SMIN:%.*]] = select i1 [[SMIN_CMP]], i32 42, i32 [[N]]
|
||
|
; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp slt i32 0, [[SMIN]]
|
||
|
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
|
||
|
; CHECK: loop.preheader:
|
||
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||
|
; CHECK: loop:
|
||
|
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
||
|
; CHECK-NEXT: [[IDX_INC]] = add nuw nsw i32 [[IDX]], 1
|
||
|
; CHECK-NEXT: br i1 true, label [[OK:%.*]], label [[LATCH]]
|
||
|
; CHECK: ok:
|
||
|
; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
|
||
|
; CHECK-NEXT: store i32 [[IDX]], ptr [[ADDR]], align 4
|
||
|
; CHECK-NEXT: br label [[LATCH]]
|
||
|
; CHECK: latch:
|
||
|
; CHECK-NEXT: [[BE_COND:%.*]] = icmp slt i32 [[IDX_INC]], [[SMIN]]
|
||
|
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
|
||
|
; CHECK: exit.loopexit:
|
||
|
; CHECK-NEXT: br label [[EXIT]]
|
||
|
; CHECK: exit:
|
||
|
; CHECK-NEXT: ret void
|
||
|
;
|
||
|
entry:
|
||
|
%smin.cmp = icmp slt i32 42, %n
|
||
|
%smin = select i1 %smin.cmp, i32 42, i32 %n
|
||
|
%entry.cond = icmp slt i32 0, %smin
|
||
|
br i1 %entry.cond, label %loop, label %exit
|
||
|
|
||
|
loop:
|
||
|
%idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
|
||
|
%idx.inc = add i32 %idx, 1
|
||
|
%in.bounds = icmp slt i32 %idx, 42
|
||
|
br i1 %in.bounds, label %ok, label %latch
|
||
|
|
||
|
ok:
|
||
|
%addr = getelementptr i32, ptr %a, i32 %idx
|
||
|
store i32 %idx, ptr %addr
|
||
|
br label %latch
|
||
|
|
||
|
latch:
|
||
|
%be.cond = icmp slt i32 %idx.inc, %smin
|
||
|
br i1 %be.cond, label %loop, label %exit
|
||
|
|
||
|
exit:
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
define void @min.signed.4(ptr %a, i32 %n) {
|
||
|
; CHECK-LABEL: define void @min.signed.4(
|
||
|
; CHECK-SAME: ptr [[A:%.*]], i32 [[N:%.*]]) {
|
||
|
; CHECK-NEXT: entry:
|
||
|
; CHECK-NEXT: [[SMIN_CMP:%.*]] = icmp slt i32 42, [[N]]
|
||
|
; CHECK-NEXT: [[SMIN:%.*]] = select i1 [[SMIN_CMP]], i32 42, i32 [[N]]
|
||
|
; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp slt i32 0, [[SMIN]]
|
||
|
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
|
||
|
; CHECK: loop.preheader:
|
||
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||
|
; CHECK: loop:
|
||
|
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
||
|
; CHECK-NEXT: [[IDX_INC]] = add nuw nsw i32 [[IDX]], 1
|
||
|
; CHECK-NEXT: br i1 true, label [[OK:%.*]], label [[LATCH]]
|
||
|
; CHECK: ok:
|
||
|
; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
|
||
|
; CHECK-NEXT: store i32 [[IDX]], ptr [[ADDR]], align 4
|
||
|
; CHECK-NEXT: br label [[LATCH]]
|
||
|
; CHECK: latch:
|
||
|
; CHECK-NEXT: [[BE_COND:%.*]] = icmp slt i32 [[IDX_INC]], [[SMIN]]
|
||
|
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
|
||
|
; CHECK: exit.loopexit:
|
||
|
; CHECK-NEXT: br label [[EXIT]]
|
||
|
; CHECK: exit:
|
||
|
; CHECK-NEXT: ret void
|
||
|
;
|
||
|
entry:
|
||
|
%smin.cmp = icmp slt i32 42, %n
|
||
|
%smin = select i1 %smin.cmp, i32 42, i32 %n
|
||
|
%entry.cond = icmp slt i32 0, %smin
|
||
|
br i1 %entry.cond, label %loop, label %exit
|
||
|
|
||
|
loop:
|
||
|
%idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
|
||
|
%idx.inc = add i32 %idx, 1
|
||
|
%in.bounds = icmp sgt i32 42, %idx
|
||
|
br i1 %in.bounds, label %ok, label %latch
|
||
|
|
||
|
ok:
|
||
|
%addr = getelementptr i32, ptr %a, i32 %idx
|
||
|
store i32 %idx, ptr %addr
|
||
|
br label %latch
|
||
|
|
||
|
latch:
|
||
|
%be.cond = icmp slt i32 %idx.inc, %smin
|
||
|
br i1 %be.cond, label %loop, label %exit
|
||
|
|
||
|
exit:
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
define void @max.signed.1(ptr %a, i32 %a_len, i32 %n) {
|
||
|
; CHECK-LABEL: define void @max.signed.1(
|
||
|
; CHECK-SAME: ptr [[A:%.*]], i32 [[A_LEN:%.*]], i32 [[N:%.*]]) {
|
||
|
; CHECK-NEXT: entry:
|
||
|
; CHECK-NEXT: [[SMAX_CMP:%.*]] = icmp sgt i32 [[A_LEN]], [[N]]
|
||
|
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[SMAX_CMP]], i32 [[A_LEN]], i32 [[N]]
|
||
|
; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp sgt i32 0, [[SMAX]]
|
||
|
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
|
||
|
; CHECK: loop.preheader:
|
||
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||
|
; CHECK: loop:
|
||
|
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
||
|
; CHECK-NEXT: [[IDX_INC]] = add i32 [[IDX]], 1
|
||
|
; CHECK-NEXT: br i1 true, label [[OK:%.*]], label [[LATCH]]
|
||
|
; CHECK: ok:
|
||
|
; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
|
||
|
; CHECK-NEXT: store i32 [[IDX]], ptr [[ADDR]], align 4
|
||
|
; CHECK-NEXT: br label [[LATCH]]
|
||
|
; CHECK: latch:
|
||
|
; CHECK-NEXT: [[BE_COND:%.*]] = icmp sgt i32 [[IDX_INC]], [[SMAX]]
|
||
|
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
|
||
|
; CHECK: exit.loopexit:
|
||
|
; CHECK-NEXT: br label [[EXIT]]
|
||
|
; CHECK: exit:
|
||
|
; CHECK-NEXT: ret void
|
||
|
;
|
||
|
entry:
|
||
|
%smax.cmp = icmp sgt i32 %a_len, %n
|
||
|
%smax = select i1 %smax.cmp, i32 %a_len, i32 %n
|
||
|
%entry.cond = icmp sgt i32 0, %smax
|
||
|
br i1 %entry.cond, label %loop, label %exit
|
||
|
|
||
|
loop:
|
||
|
%idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
|
||
|
%idx.inc = add i32 %idx, 1
|
||
|
%in.bounds = icmp sgt i32 %idx, %a_len
|
||
|
br i1 %in.bounds, label %ok, label %latch
|
||
|
|
||
|
ok:
|
||
|
%addr = getelementptr i32, ptr %a, i32 %idx
|
||
|
store i32 %idx, ptr %addr
|
||
|
br label %latch
|
||
|
|
||
|
latch:
|
||
|
%be.cond = icmp sgt i32 %idx.inc, %smax
|
||
|
br i1 %be.cond, label %loop, label %exit
|
||
|
|
||
|
exit:
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
define void @max.signed.2(ptr %a, i32 %a_len, i32 %n) {
|
||
|
; CHECK-LABEL: define void @max.signed.2(
|
||
|
; CHECK-SAME: ptr [[A:%.*]], i32 [[A_LEN:%.*]], i32 [[N:%.*]]) {
|
||
|
; CHECK-NEXT: entry:
|
||
|
; CHECK-NEXT: [[SMAX_CMP:%.*]] = icmp sgt i32 [[A_LEN]], [[N]]
|
||
|
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[SMAX_CMP]], i32 [[A_LEN]], i32 [[N]]
|
||
|
; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp sgt i32 0, [[SMAX]]
|
||
|
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
|
||
|
; CHECK: loop.preheader:
|
||
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||
|
; CHECK: loop:
|
||
|
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
|
||
|
; CHECK-NEXT: [[IDX_INC]] = add i32 [[IDX]], 1
|
||
|
; CHECK-NEXT: br i1 true, label [[OK:%.*]], label [[LATCH]]
|
||
|
; CHECK: ok:
|
||
|
; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
|
||
|
; CHECK-NEXT: store i32 [[IDX]], ptr [[ADDR]], align 4
|
||
|
; CHECK-NEXT: br label [[LATCH]]
|
||
|
; CHECK: latch:
|
||
|
; CHECK-NEXT: [[BE_COND:%.*]] = icmp sgt i32 [[IDX_INC]], [[SMAX]]
|
||
|
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
|
||
|
; CHECK: exit.loopexit:
|
||
|
; CHECK-NEXT: br label [[EXIT]]
|
||
|
; CHECK: exit:
|
||
|
; CHECK-NEXT: ret void
|
||
|
;
|
||
|
entry:
|
||
|
%smax.cmp = icmp sgt i32 %a_len, %n
|
||
|
%smax = select i1 %smax.cmp, i32 %a_len, i32 %n
|
||
|
%entry.cond = icmp sgt i32 0, %smax
|
||
|
br i1 %entry.cond, label %loop, label %exit
|
||
|
|
||
|
loop:
|
||
|
%idx = phi i32 [ 0, %entry ], [ %idx.inc, %latch ]
|
||
|
%idx.inc = add i32 %idx, 1
|
||
|
%in.bounds = icmp slt i32 %a_len, %idx
|
||
|
br i1 %in.bounds, label %ok, label %latch
|
||
|
|
||
|
ok:
|
||
|
%addr = getelementptr i32, ptr %a, i32 %idx
|
||
|
store i32 %idx, ptr %addr
|
||
|
br label %latch
|
||
|
|
||
|
latch:
|
||
|
%be.cond = icmp sgt i32 %idx.inc, %smax
|
||
|
br i1 %be.cond, label %loop, label %exit
|
||
|
|
||
|
exit:
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
define void @max.signed.3(ptr %a, i32 %n, i32 %init) {
|
||
|
; CHECK-LABEL: define void @max.signed.3(
|
||
|
; CHECK-SAME: ptr [[A:%.*]], i32 [[N:%.*]], i32 [[INIT:%.*]]) {
|
||
|
; CHECK-NEXT: entry:
|
||
|
; CHECK-NEXT: [[SMAX_CMP:%.*]] = icmp sgt i32 42, [[N]]
|
||
|
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[SMAX_CMP]], i32 42, i32 [[N]]
|
||
|
; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp sgt i32 [[INIT]], [[SMAX]]
|
||
|
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
|
||
|
; CHECK: loop.preheader:
|
||
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||
|
; CHECK: loop:
|
||
|
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ [[INIT]], [[LOOP_PREHEADER]] ]
|
||
|
; CHECK-NEXT: [[IDX_INC]] = add nuw i32 [[IDX]], 1
|
||
|
; CHECK-NEXT: br i1 true, label [[OK:%.*]], label [[LATCH]]
|
||
|
; CHECK: ok:
|
||
|
; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
|
||
|
; CHECK-NEXT: store i32 [[IDX]], ptr [[ADDR]], align 4
|
||
|
; CHECK-NEXT: br label [[LATCH]]
|
||
|
; CHECK: latch:
|
||
|
; CHECK-NEXT: [[BE_COND:%.*]] = icmp sgt i32 [[IDX_INC]], [[SMAX]]
|
||
|
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
|
||
|
; CHECK: exit.loopexit:
|
||
|
; CHECK-NEXT: br label [[EXIT]]
|
||
|
; CHECK: exit:
|
||
|
; CHECK-NEXT: ret void
|
||
|
;
|
||
|
entry:
|
||
|
%smax.cmp = icmp sgt i32 42, %n
|
||
|
%smax = select i1 %smax.cmp, i32 42, i32 %n
|
||
|
%entry.cond = icmp sgt i32 %init, %smax
|
||
|
br i1 %entry.cond, label %loop, label %exit
|
||
|
|
||
|
loop:
|
||
|
%idx = phi i32 [ %init, %entry ], [ %idx.inc, %latch ]
|
||
|
%idx.inc = add i32 %idx, 1
|
||
|
%in.bounds = icmp sgt i32 %idx, 42
|
||
|
br i1 %in.bounds, label %ok, label %latch
|
||
|
|
||
|
ok:
|
||
|
%addr = getelementptr i32, ptr %a, i32 %idx
|
||
|
store i32 %idx, ptr %addr
|
||
|
br label %latch
|
||
|
|
||
|
latch:
|
||
|
%be.cond = icmp sgt i32 %idx.inc, %smax
|
||
|
br i1 %be.cond, label %loop, label %exit
|
||
|
|
||
|
exit:
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
define void @max.signed.4(ptr %a, i32 %n, i32 %init) {
|
||
|
; CHECK-LABEL: define void @max.signed.4(
|
||
|
; CHECK-SAME: ptr [[A:%.*]], i32 [[N:%.*]], i32 [[INIT:%.*]]) {
|
||
|
; CHECK-NEXT: entry:
|
||
|
; CHECK-NEXT: [[SMAX_CMP:%.*]] = icmp sgt i32 42, [[N]]
|
||
|
; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[SMAX_CMP]], i32 42, i32 [[N]]
|
||
|
; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp sgt i32 [[INIT]], [[SMAX]]
|
||
|
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
|
||
|
; CHECK: loop.preheader:
|
||
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||
|
; CHECK: loop:
|
||
|
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ [[INIT]], [[LOOP_PREHEADER]] ]
|
||
|
; CHECK-NEXT: [[IDX_INC]] = add nuw i32 [[IDX]], 1
|
||
|
; CHECK-NEXT: br i1 true, label [[OK:%.*]], label [[LATCH]]
|
||
|
; CHECK: ok:
|
||
|
; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
|
||
|
; CHECK-NEXT: store i32 [[IDX]], ptr [[ADDR]], align 4
|
||
|
; CHECK-NEXT: br label [[LATCH]]
|
||
|
; CHECK: latch:
|
||
|
; CHECK-NEXT: [[BE_COND:%.*]] = icmp sgt i32 [[IDX_INC]], [[SMAX]]
|
||
|
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
|
||
|
; CHECK: exit.loopexit:
|
||
|
; CHECK-NEXT: br label [[EXIT]]
|
||
|
; CHECK: exit:
|
||
|
; CHECK-NEXT: ret void
|
||
|
;
|
||
|
entry:
|
||
|
%smax.cmp = icmp sgt i32 42, %n
|
||
|
%smax = select i1 %smax.cmp, i32 42, i32 %n
|
||
|
%entry.cond = icmp sgt i32 %init, %smax
|
||
|
br i1 %entry.cond, label %loop, label %exit
|
||
|
|
||
|
loop:
|
||
|
%idx = phi i32 [ %init, %entry ], [ %idx.inc, %latch ]
|
||
|
%idx.inc = add i32 %idx, 1
|
||
|
%in.bounds = icmp slt i32 42, %idx
|
||
|
br i1 %in.bounds, label %ok, label %latch
|
||
|
|
||
|
ok:
|
||
|
%addr = getelementptr i32, ptr %a, i32 %idx
|
||
|
store i32 %idx, ptr %addr
|
||
|
br label %latch
|
||
|
|
||
|
latch:
|
||
|
%be.cond = icmp sgt i32 %idx.inc, %smax
|
||
|
br i1 %be.cond, label %loop, label %exit
|
||
|
|
||
|
exit:
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
;; --- unsigned ---
|
||
|
|
||
|
define void @min.unsigned.1(ptr %a, i32 %a_len, i32 %n) {
|
||
|
; CHECK-LABEL: define void @min.unsigned.1(
|
||
|
; CHECK-SAME: ptr [[A:%.*]], i32 [[A_LEN:%.*]], i32 [[N:%.*]]) {
|
||
|
; CHECK-NEXT: entry:
|
||
|
; CHECK-NEXT: [[UMIN_CMP:%.*]] = icmp ult i32 [[A_LEN]], [[N]]
|
||
|
; CHECK-NEXT: [[UMIN:%.*]] = select i1 [[UMIN_CMP]], i32 [[A_LEN]], i32 [[N]]
|
||
|
; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp ult i32 5, [[UMIN]]
|
||
|
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
|
||
|
; CHECK: loop.preheader:
|
||
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||
|
; CHECK: loop:
|
||
|
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 5, [[LOOP_PREHEADER]] ]
|
||
|
; CHECK-NEXT: [[IDX_INC]] = add nuw i32 [[IDX]], 1
|
||
|
; CHECK-NEXT: br i1 true, label [[OK:%.*]], label [[LATCH]]
|
||
|
; CHECK: ok:
|
||
|
; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
|
||
|
; CHECK-NEXT: store i32 [[IDX]], ptr [[ADDR]], align 4
|
||
|
; CHECK-NEXT: br label [[LATCH]]
|
||
|
; CHECK: latch:
|
||
|
; CHECK-NEXT: [[BE_COND:%.*]] = icmp ult i32 [[IDX_INC]], [[UMIN]]
|
||
|
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
|
||
|
; CHECK: exit.loopexit:
|
||
|
; CHECK-NEXT: br label [[EXIT]]
|
||
|
; CHECK: exit:
|
||
|
; CHECK-NEXT: ret void
|
||
|
;
|
||
|
entry:
|
||
|
%umin.cmp = icmp ult i32 %a_len, %n
|
||
|
%umin = select i1 %umin.cmp, i32 %a_len, i32 %n
|
||
|
%entry.cond = icmp ult i32 5, %umin
|
||
|
br i1 %entry.cond, label %loop, label %exit
|
||
|
|
||
|
loop:
|
||
|
%idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
|
||
|
%idx.inc = add i32 %idx, 1
|
||
|
%in.bounds = icmp ult i32 %idx, %a_len
|
||
|
br i1 %in.bounds, label %ok, label %latch
|
||
|
|
||
|
ok:
|
||
|
%addr = getelementptr i32, ptr %a, i32 %idx
|
||
|
store i32 %idx, ptr %addr
|
||
|
br label %latch
|
||
|
|
||
|
latch:
|
||
|
%be.cond = icmp ult i32 %idx.inc, %umin
|
||
|
br i1 %be.cond, label %loop, label %exit
|
||
|
|
||
|
exit:
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
define void @min.unsigned.2(ptr %a, i32 %a_len, i32 %n) {
|
||
|
; CHECK-LABEL: define void @min.unsigned.2(
|
||
|
; CHECK-SAME: ptr [[A:%.*]], i32 [[A_LEN:%.*]], i32 [[N:%.*]]) {
|
||
|
; CHECK-NEXT: entry:
|
||
|
; CHECK-NEXT: [[UMIN_CMP:%.*]] = icmp ult i32 [[A_LEN]], [[N]]
|
||
|
; CHECK-NEXT: [[UMIN:%.*]] = select i1 [[UMIN_CMP]], i32 [[A_LEN]], i32 [[N]]
|
||
|
; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp ult i32 5, [[UMIN]]
|
||
|
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
|
||
|
; CHECK: loop.preheader:
|
||
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||
|
; CHECK: loop:
|
||
|
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 5, [[LOOP_PREHEADER]] ]
|
||
|
; CHECK-NEXT: [[IDX_INC]] = add nuw i32 [[IDX]], 1
|
||
|
; CHECK-NEXT: br i1 true, label [[OK:%.*]], label [[LATCH]]
|
||
|
; CHECK: ok:
|
||
|
; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
|
||
|
; CHECK-NEXT: store i32 [[IDX]], ptr [[ADDR]], align 4
|
||
|
; CHECK-NEXT: br label [[LATCH]]
|
||
|
; CHECK: latch:
|
||
|
; CHECK-NEXT: [[BE_COND:%.*]] = icmp ult i32 [[IDX_INC]], [[UMIN]]
|
||
|
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
|
||
|
; CHECK: exit.loopexit:
|
||
|
; CHECK-NEXT: br label [[EXIT]]
|
||
|
; CHECK: exit:
|
||
|
; CHECK-NEXT: ret void
|
||
|
;
|
||
|
entry:
|
||
|
%umin.cmp = icmp ult i32 %a_len, %n
|
||
|
%umin = select i1 %umin.cmp, i32 %a_len, i32 %n
|
||
|
%entry.cond = icmp ult i32 5, %umin
|
||
|
br i1 %entry.cond, label %loop, label %exit
|
||
|
|
||
|
loop:
|
||
|
%idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
|
||
|
%idx.inc = add i32 %idx, 1
|
||
|
%in.bounds = icmp ugt i32 %a_len, %idx
|
||
|
br i1 %in.bounds, label %ok, label %latch
|
||
|
|
||
|
ok:
|
||
|
%addr = getelementptr i32, ptr %a, i32 %idx
|
||
|
store i32 %idx, ptr %addr
|
||
|
br label %latch
|
||
|
|
||
|
latch:
|
||
|
%be.cond = icmp ult i32 %idx.inc, %umin
|
||
|
br i1 %be.cond, label %loop, label %exit
|
||
|
|
||
|
exit:
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
define void @min.unsigned.3(ptr %a, i32 %n) {
|
||
|
; CHECK-LABEL: define void @min.unsigned.3(
|
||
|
; CHECK-SAME: ptr [[A:%.*]], i32 [[N:%.*]]) {
|
||
|
; CHECK-NEXT: entry:
|
||
|
; CHECK-NEXT: [[UMIN_CMP:%.*]] = icmp ult i32 42, [[N]]
|
||
|
; CHECK-NEXT: [[UMIN:%.*]] = select i1 [[UMIN_CMP]], i32 42, i32 [[N]]
|
||
|
; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp ult i32 5, [[UMIN]]
|
||
|
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
|
||
|
; CHECK: loop.preheader:
|
||
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||
|
; CHECK: loop:
|
||
|
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 5, [[LOOP_PREHEADER]] ]
|
||
|
; CHECK-NEXT: [[IDX_INC]] = add nuw nsw i32 [[IDX]], 1
|
||
|
; CHECK-NEXT: br i1 true, label [[OK:%.*]], label [[LATCH]]
|
||
|
; CHECK: ok:
|
||
|
; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
|
||
|
; CHECK-NEXT: store i32 [[IDX]], ptr [[ADDR]], align 4
|
||
|
; CHECK-NEXT: br label [[LATCH]]
|
||
|
; CHECK: latch:
|
||
|
; CHECK-NEXT: [[BE_COND:%.*]] = icmp ult i32 [[IDX_INC]], [[UMIN]]
|
||
|
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
|
||
|
; CHECK: exit.loopexit:
|
||
|
; CHECK-NEXT: br label [[EXIT]]
|
||
|
; CHECK: exit:
|
||
|
; CHECK-NEXT: ret void
|
||
|
;
|
||
|
entry:
|
||
|
%umin.cmp = icmp ult i32 42, %n
|
||
|
%umin = select i1 %umin.cmp, i32 42, i32 %n
|
||
|
%entry.cond = icmp ult i32 5, %umin
|
||
|
br i1 %entry.cond, label %loop, label %exit
|
||
|
|
||
|
loop:
|
||
|
%idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
|
||
|
%idx.inc = add i32 %idx, 1
|
||
|
%in.bounds = icmp ult i32 %idx, 42
|
||
|
br i1 %in.bounds, label %ok, label %latch
|
||
|
|
||
|
ok:
|
||
|
%addr = getelementptr i32, ptr %a, i32 %idx
|
||
|
store i32 %idx, ptr %addr
|
||
|
br label %latch
|
||
|
|
||
|
latch:
|
||
|
%be.cond = icmp ult i32 %idx.inc, %umin
|
||
|
br i1 %be.cond, label %loop, label %exit
|
||
|
|
||
|
exit:
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
define void @min.unsigned.4(ptr %a, i32 %n) {
|
||
|
; CHECK-LABEL: define void @min.unsigned.4(
|
||
|
; CHECK-SAME: ptr [[A:%.*]], i32 [[N:%.*]]) {
|
||
|
; CHECK-NEXT: entry:
|
||
|
; CHECK-NEXT: [[UMIN_CMP:%.*]] = icmp ult i32 42, [[N]]
|
||
|
; CHECK-NEXT: [[UMIN:%.*]] = select i1 [[UMIN_CMP]], i32 42, i32 [[N]]
|
||
|
; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp ult i32 5, [[UMIN]]
|
||
|
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
|
||
|
; CHECK: loop.preheader:
|
||
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||
|
; CHECK: loop:
|
||
|
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 5, [[LOOP_PREHEADER]] ]
|
||
|
; CHECK-NEXT: [[IDX_INC]] = add nuw nsw i32 [[IDX]], 1
|
||
|
; CHECK-NEXT: br i1 true, label [[OK:%.*]], label [[LATCH]]
|
||
|
; CHECK: ok:
|
||
|
; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
|
||
|
; CHECK-NEXT: store i32 [[IDX]], ptr [[ADDR]], align 4
|
||
|
; CHECK-NEXT: br label [[LATCH]]
|
||
|
; CHECK: latch:
|
||
|
; CHECK-NEXT: [[BE_COND:%.*]] = icmp ult i32 [[IDX_INC]], [[UMIN]]
|
||
|
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
|
||
|
; CHECK: exit.loopexit:
|
||
|
; CHECK-NEXT: br label [[EXIT]]
|
||
|
; CHECK: exit:
|
||
|
; CHECK-NEXT: ret void
|
||
|
;
|
||
|
entry:
|
||
|
%umin.cmp = icmp ult i32 42, %n
|
||
|
%umin = select i1 %umin.cmp, i32 42, i32 %n
|
||
|
%entry.cond = icmp ult i32 5, %umin
|
||
|
br i1 %entry.cond, label %loop, label %exit
|
||
|
|
||
|
loop:
|
||
|
%idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
|
||
|
%idx.inc = add i32 %idx, 1
|
||
|
%in.bounds = icmp ugt i32 42, %idx
|
||
|
br i1 %in.bounds, label %ok, label %latch
|
||
|
|
||
|
ok:
|
||
|
%addr = getelementptr i32, ptr %a, i32 %idx
|
||
|
store i32 %idx, ptr %addr
|
||
|
br label %latch
|
||
|
|
||
|
latch:
|
||
|
%be.cond = icmp ult i32 %idx.inc, %umin
|
||
|
br i1 %be.cond, label %loop, label %exit
|
||
|
|
||
|
exit:
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
define void @max.unsigned.1(ptr %a, i32 %a_len, i32 %n) {
|
||
|
; CHECK-LABEL: define void @max.unsigned.1(
|
||
|
; CHECK-SAME: ptr [[A:%.*]], i32 [[A_LEN:%.*]], i32 [[N:%.*]]) {
|
||
|
; CHECK-NEXT: entry:
|
||
|
; CHECK-NEXT: [[UMAX_CMP:%.*]] = icmp ugt i32 [[A_LEN]], [[N]]
|
||
|
; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[UMAX_CMP]], i32 [[A_LEN]], i32 [[N]]
|
||
|
; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp ugt i32 5, [[UMAX]]
|
||
|
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
|
||
|
; CHECK: loop.preheader:
|
||
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||
|
; CHECK: loop:
|
||
|
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 5, [[LOOP_PREHEADER]] ]
|
||
|
; CHECK-NEXT: [[IDX_INC]] = add i32 [[IDX]], 1
|
||
|
; CHECK-NEXT: br i1 true, label [[OK:%.*]], label [[LATCH]]
|
||
|
; CHECK: ok:
|
||
|
; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
|
||
|
; CHECK-NEXT: store i32 [[IDX]], ptr [[ADDR]], align 4
|
||
|
; CHECK-NEXT: br label [[LATCH]]
|
||
|
; CHECK: latch:
|
||
|
; CHECK-NEXT: [[BE_COND:%.*]] = icmp ugt i32 [[IDX_INC]], [[UMAX]]
|
||
|
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
|
||
|
; CHECK: exit.loopexit:
|
||
|
; CHECK-NEXT: br label [[EXIT]]
|
||
|
; CHECK: exit:
|
||
|
; CHECK-NEXT: ret void
|
||
|
;
|
||
|
entry:
|
||
|
%umax.cmp = icmp ugt i32 %a_len, %n
|
||
|
%umax = select i1 %umax.cmp, i32 %a_len, i32 %n
|
||
|
%entry.cond = icmp ugt i32 5, %umax
|
||
|
br i1 %entry.cond, label %loop, label %exit
|
||
|
|
||
|
loop:
|
||
|
%idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
|
||
|
%idx.inc = add i32 %idx, 1
|
||
|
%in.bounds = icmp ugt i32 %idx, %a_len
|
||
|
br i1 %in.bounds, label %ok, label %latch
|
||
|
|
||
|
ok:
|
||
|
%addr = getelementptr i32, ptr %a, i32 %idx
|
||
|
store i32 %idx, ptr %addr
|
||
|
br label %latch
|
||
|
|
||
|
latch:
|
||
|
%be.cond = icmp ugt i32 %idx.inc, %umax
|
||
|
br i1 %be.cond, label %loop, label %exit
|
||
|
|
||
|
exit:
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
define void @max.unsigned.2(ptr %a, i32 %a_len, i32 %n) {
|
||
|
; CHECK-LABEL: define void @max.unsigned.2(
|
||
|
; CHECK-SAME: ptr [[A:%.*]], i32 [[A_LEN:%.*]], i32 [[N:%.*]]) {
|
||
|
; CHECK-NEXT: entry:
|
||
|
; CHECK-NEXT: [[UMAX_CMP:%.*]] = icmp ugt i32 [[A_LEN]], [[N]]
|
||
|
; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[UMAX_CMP]], i32 [[A_LEN]], i32 [[N]]
|
||
|
; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp ugt i32 5, [[UMAX]]
|
||
|
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
|
||
|
; CHECK: loop.preheader:
|
||
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||
|
; CHECK: loop:
|
||
|
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ 5, [[LOOP_PREHEADER]] ]
|
||
|
; CHECK-NEXT: [[IDX_INC]] = add i32 [[IDX]], 1
|
||
|
; CHECK-NEXT: br i1 true, label [[OK:%.*]], label [[LATCH]]
|
||
|
; CHECK: ok:
|
||
|
; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
|
||
|
; CHECK-NEXT: store i32 [[IDX]], ptr [[ADDR]], align 4
|
||
|
; CHECK-NEXT: br label [[LATCH]]
|
||
|
; CHECK: latch:
|
||
|
; CHECK-NEXT: [[BE_COND:%.*]] = icmp ugt i32 [[IDX_INC]], [[UMAX]]
|
||
|
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
|
||
|
; CHECK: exit.loopexit:
|
||
|
; CHECK-NEXT: br label [[EXIT]]
|
||
|
; CHECK: exit:
|
||
|
; CHECK-NEXT: ret void
|
||
|
;
|
||
|
entry:
|
||
|
%umax.cmp = icmp ugt i32 %a_len, %n
|
||
|
%umax = select i1 %umax.cmp, i32 %a_len, i32 %n
|
||
|
%entry.cond = icmp ugt i32 5, %umax
|
||
|
br i1 %entry.cond, label %loop, label %exit
|
||
|
|
||
|
loop:
|
||
|
%idx = phi i32 [ 5, %entry ], [ %idx.inc, %latch ]
|
||
|
%idx.inc = add i32 %idx, 1
|
||
|
%in.bounds = icmp ult i32 %a_len, %idx
|
||
|
br i1 %in.bounds, label %ok, label %latch
|
||
|
|
||
|
ok:
|
||
|
%addr = getelementptr i32, ptr %a, i32 %idx
|
||
|
store i32 %idx, ptr %addr
|
||
|
br label %latch
|
||
|
|
||
|
latch:
|
||
|
%be.cond = icmp ugt i32 %idx.inc, %umax
|
||
|
br i1 %be.cond, label %loop, label %exit
|
||
|
|
||
|
exit:
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
define void @max.unsigned.3(ptr %a, i32 %n, i32 %init) {
|
||
|
; CHECK-LABEL: define void @max.unsigned.3(
|
||
|
; CHECK-SAME: ptr [[A:%.*]], i32 [[N:%.*]], i32 [[INIT:%.*]]) {
|
||
|
; CHECK-NEXT: entry:
|
||
|
; CHECK-NEXT: [[UMAX_CMP:%.*]] = icmp ugt i32 42, [[N]]
|
||
|
; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[UMAX_CMP]], i32 42, i32 [[N]]
|
||
|
; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp ugt i32 [[INIT]], [[UMAX]]
|
||
|
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
|
||
|
; CHECK: loop.preheader:
|
||
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||
|
; CHECK: loop:
|
||
|
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ [[INIT]], [[LOOP_PREHEADER]] ]
|
||
|
; CHECK-NEXT: [[IDX_INC]] = add i32 [[IDX]], 1
|
||
|
; CHECK-NEXT: br i1 true, label [[OK:%.*]], label [[LATCH]]
|
||
|
; CHECK: ok:
|
||
|
; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
|
||
|
; CHECK-NEXT: store i32 [[IDX]], ptr [[ADDR]], align 4
|
||
|
; CHECK-NEXT: br label [[LATCH]]
|
||
|
; CHECK: latch:
|
||
|
; CHECK-NEXT: [[BE_COND:%.*]] = icmp ugt i32 [[IDX_INC]], [[UMAX]]
|
||
|
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
|
||
|
; CHECK: exit.loopexit:
|
||
|
; CHECK-NEXT: br label [[EXIT]]
|
||
|
; CHECK: exit:
|
||
|
; CHECK-NEXT: ret void
|
||
|
;
|
||
|
entry:
|
||
|
%umax.cmp = icmp ugt i32 42, %n
|
||
|
%umax = select i1 %umax.cmp, i32 42, i32 %n
|
||
|
%entry.cond = icmp ugt i32 %init, %umax
|
||
|
br i1 %entry.cond, label %loop, label %exit
|
||
|
|
||
|
loop:
|
||
|
%idx = phi i32 [ %init, %entry ], [ %idx.inc, %latch ]
|
||
|
%idx.inc = add i32 %idx, 1
|
||
|
%in.bounds = icmp ugt i32 %idx, 42
|
||
|
br i1 %in.bounds, label %ok, label %latch
|
||
|
|
||
|
ok:
|
||
|
%addr = getelementptr i32, ptr %a, i32 %idx
|
||
|
store i32 %idx, ptr %addr
|
||
|
br label %latch
|
||
|
|
||
|
latch:
|
||
|
%be.cond = icmp ugt i32 %idx.inc, %umax
|
||
|
br i1 %be.cond, label %loop, label %exit
|
||
|
|
||
|
exit:
|
||
|
ret void
|
||
|
}
|
||
|
|
||
|
define void @max.unsigned.4(ptr %a, i32 %n, i32 %init) {
|
||
|
; CHECK-LABEL: define void @max.unsigned.4(
|
||
|
; CHECK-SAME: ptr [[A:%.*]], i32 [[N:%.*]], i32 [[INIT:%.*]]) {
|
||
|
; CHECK-NEXT: entry:
|
||
|
; CHECK-NEXT: [[UMAX_CMP:%.*]] = icmp ugt i32 42, [[N]]
|
||
|
; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[UMAX_CMP]], i32 42, i32 [[N]]
|
||
|
; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp ugt i32 [[INIT]], [[UMAX]]
|
||
|
; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
|
||
|
; CHECK: loop.preheader:
|
||
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
||
|
; CHECK: loop:
|
||
|
; CHECK-NEXT: [[IDX:%.*]] = phi i32 [ [[IDX_INC:%.*]], [[LATCH:%.*]] ], [ [[INIT]], [[LOOP_PREHEADER]] ]
|
||
|
; CHECK-NEXT: [[IDX_INC]] = add i32 [[IDX]], 1
|
||
|
; CHECK-NEXT: br i1 true, label [[OK:%.*]], label [[LATCH]]
|
||
|
; CHECK: ok:
|
||
|
; CHECK-NEXT: [[ADDR:%.*]] = getelementptr i32, ptr [[A]], i32 [[IDX]]
|
||
|
; CHECK-NEXT: store i32 [[IDX]], ptr [[ADDR]], align 4
|
||
|
; CHECK-NEXT: br label [[LATCH]]
|
||
|
; CHECK: latch:
|
||
|
; CHECK-NEXT: [[BE_COND:%.*]] = icmp ugt i32 [[IDX_INC]], [[UMAX]]
|
||
|
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
|
||
|
; CHECK: exit.loopexit:
|
||
|
; CHECK-NEXT: br label [[EXIT]]
|
||
|
; CHECK: exit:
|
||
|
; CHECK-NEXT: ret void
|
||
|
;
|
||
|
entry:
|
||
|
%umax.cmp = icmp ugt i32 42, %n
|
||
|
%umax = select i1 %umax.cmp, i32 42, i32 %n
|
||
|
%entry.cond = icmp ugt i32 %init, %umax
|
||
|
br i1 %entry.cond, label %loop, label %exit
|
||
|
|
||
|
loop:
|
||
|
%idx = phi i32 [ %init, %entry ], [ %idx.inc, %latch ]
|
||
|
%idx.inc = add i32 %idx, 1
|
||
|
%in.bounds = icmp ult i32 42, %idx
|
||
|
br i1 %in.bounds, label %ok, label %latch
|
||
|
|
||
|
ok:
|
||
|
%addr = getelementptr i32, ptr %a, i32 %idx
|
||
|
store i32 %idx, ptr %addr
|
||
|
br label %latch
|
||
|
|
||
|
latch:
|
||
|
%be.cond = icmp ugt i32 %idx.inc, %umax
|
||
|
br i1 %be.cond, label %loop, label %exit
|
||
|
|
||
|
exit:
|
||
|
ret void
|
||
|
}
|