
While sinking instructions (that are loop invariant) from preheader to the exit block, we are skipping instructions due to decrementing instruction iterator twice.
107 lines
3.3 KiB
LLVM
107 lines
3.3 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -passes=indvars -S | FileCheck %s
|
|
|
|
define i32 @logical_and_2ops(i32 %n, i32 %m) {
|
|
; CHECK-LABEL: @logical_and_2ops(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
; CHECK: loop:
|
|
; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]]
|
|
; CHECK: exit:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = freeze i32 [[M:%.*]]
|
|
; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP0]], i32 [[N:%.*]])
|
|
; CHECK-NEXT: ret i32 [[UMIN]]
|
|
;
|
|
entry:
|
|
br label %loop
|
|
loop:
|
|
%i = phi i32 [0, %entry], [%i.next, %loop]
|
|
%i.next = add i32 %i, 1
|
|
%cond_p0 = icmp ult i32 %i, %n
|
|
%cond_p1 = icmp ult i32 %i, %m
|
|
%cond = select i1 %cond_p0, i1 %cond_p1, i1 false
|
|
br i1 %cond, label %loop, label %exit
|
|
exit:
|
|
ret i32 %i
|
|
}
|
|
|
|
define i32 @logical_or_2ops(i32 %n, i32 %m) {
|
|
; CHECK-LABEL: @logical_or_2ops(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
; CHECK: loop:
|
|
; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[LOOP]]
|
|
; CHECK: exit:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = freeze i32 [[M:%.*]]
|
|
; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP0]], i32 [[N:%.*]])
|
|
; CHECK-NEXT: ret i32 [[UMIN]]
|
|
;
|
|
entry:
|
|
br label %loop
|
|
loop:
|
|
%i = phi i32 [0, %entry], [%i.next, %loop]
|
|
%i.next = add i32 %i, 1
|
|
%cond_p0 = icmp uge i32 %i, %n
|
|
%cond_p1 = icmp uge i32 %i, %m
|
|
%cond = select i1 %cond_p0, i1 true, i1 %cond_p1
|
|
br i1 %cond, label %exit, label %loop
|
|
exit:
|
|
ret i32 %i
|
|
}
|
|
|
|
define i32 @logical_and_3ops(i32 %n, i32 %m, i32 %k) {
|
|
; CHECK-LABEL: @logical_and_3ops(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
; CHECK: loop:
|
|
; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]]
|
|
; CHECK: exit:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = freeze i32 [[K:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = freeze i32 [[M:%.*]]
|
|
; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP0]], i32 [[TMP1]])
|
|
; CHECK-NEXT: [[UMIN1:%.*]] = call i32 @llvm.umin.i32(i32 [[UMIN]], i32 [[N:%.*]])
|
|
; CHECK-NEXT: ret i32 [[UMIN1]]
|
|
;
|
|
entry:
|
|
br label %loop
|
|
loop:
|
|
%i = phi i32 [0, %entry], [%i.next, %loop]
|
|
%i.next = add i32 %i, 1
|
|
%cond_p0 = icmp ult i32 %i, %n
|
|
%cond_p1 = icmp ult i32 %i, %m
|
|
%cond_p2 = icmp ult i32 %i, %k
|
|
%cond_p3 = select i1 %cond_p0, i1 %cond_p1, i1 false
|
|
%cond = select i1 %cond_p3, i1 %cond_p2, i1 false
|
|
br i1 %cond, label %loop, label %exit
|
|
exit:
|
|
ret i32 %i
|
|
}
|
|
|
|
define i32 @logical_or_3ops(i32 %n, i32 %m, i32 %k) {
|
|
; CHECK-LABEL: @logical_or_3ops(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
; CHECK: loop:
|
|
; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[LOOP]]
|
|
; CHECK: exit:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = freeze i32 [[K:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = freeze i32 [[M:%.*]]
|
|
; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP0]], i32 [[TMP1]])
|
|
; CHECK-NEXT: [[UMIN1:%.*]] = call i32 @llvm.umin.i32(i32 [[UMIN]], i32 [[N:%.*]])
|
|
; CHECK-NEXT: ret i32 [[UMIN1]]
|
|
;
|
|
entry:
|
|
br label %loop
|
|
loop:
|
|
%i = phi i32 [0, %entry], [%i.next, %loop]
|
|
%i.next = add i32 %i, 1
|
|
%cond_p0 = icmp uge i32 %i, %n
|
|
%cond_p1 = icmp uge i32 %i, %m
|
|
%cond_p2 = icmp uge i32 %i, %k
|
|
%cond_p3 = select i1 %cond_p0, i1 true, i1 %cond_p1
|
|
%cond = select i1 %cond_p3, i1 true, i1 %cond_p2
|
|
br i1 %cond, label %exit, label %loop
|
|
exit:
|
|
ret i32 %i
|
|
}
|