blob: 221f4e86df60ab068da17de988fe46b604df23ec [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=indvars -S %s | FileCheck %s
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
define i32 @last_loaded_with_or_exit(i32 %n, ptr %arr) mustprogress {
; CHECK-LABEL: define i32 @last_loaded_with_or_exit(
; CHECK-SAME: i32 [[N:%.*]], ptr [[ARR:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: br label %[[HEADER:.*]]
; CHECK: [[HEADER]]:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ], [ 0, %[[ENTRY]] ]
; CHECK-NEXT: [[LAST_LOADED:%.*]] = phi i32 [ [[LAST_LOADED_NEXT:%.*]], %[[LATCH]] ], [ 0, %[[ENTRY]] ]
; CHECK-NEXT: [[IV_LT_N:%.*]] = icmp ult i32 [[IV]], [[N]]
; CHECK-NEXT: [[IV_MINUS_ONE:%.*]] = add i32 -1, [[IV]]
; CHECK-NEXT: [[IV_MINUS_ONE_LT_N:%.*]] = icmp ult i32 [[IV_MINUS_ONE]], [[N]]
; CHECK-NEXT: [[STAY:%.*]] = or i1 [[IV_LT_N]], [[IV_MINUS_ONE_LT_N]]
; CHECK-NEXT: br i1 [[STAY]], label %[[BODY:.*]], label %[[EXIT:.*]]
; CHECK: [[BODY]]:
; CHECK-NEXT: [[BODY_IV_MINUS_ONE:%.*]] = add i32 -1, [[IV]]
; CHECK-NEXT: [[BODY_IV_MINUS_ONE_NONNEG:%.*]] = icmp sgt i32 [[BODY_IV_MINUS_ONE]], -1
; CHECK-NEXT: br i1 [[BODY_IV_MINUS_ONE_NONNEG]], label %[[DO_LOAD:.*]], label %[[LATCH]]
; CHECK: [[DO_LOAD]]:
; CHECK-NEXT: [[IDX:%.*]] = zext nneg i32 [[BODY_IV_MINUS_ONE]] to i64
; CHECK-NEXT: [[ADDR:%.*]] = getelementptr inbounds i32, ptr [[ARR]], i64 [[IDX]]
; CHECK-NEXT: [[LOADED:%.*]] = load i32, ptr [[ADDR]], align 4
; CHECK-NEXT: br label %[[LATCH]]
; CHECK: [[LATCH]]:
; CHECK-NEXT: [[LAST_LOADED_NEXT]] = phi i32 [ [[LAST_LOADED]], %[[BODY]] ], [ [[LOADED]], %[[DO_LOAD]] ]
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
; CHECK-NEXT: br label %[[HEADER]]
; CHECK: [[EXIT]]:
; CHECK-NEXT: [[LAST_LOADED_LCSSA:%.*]] = phi i32 [ [[LAST_LOADED]], %[[HEADER]] ]
; CHECK-NEXT: ret i32 [[LAST_LOADED_LCSSA]]
;
entry:
br label %header
header:
%iv = phi i32 [ %iv.next, %latch ], [ 0, %entry ]
%last_loaded = phi i32 [ %last_loaded.next, %latch ], [ 0, %entry ]
%iv_lt_n = icmp ult i32 %iv, %n
%iv_minus_one = add i32 -1, %iv
%iv_minus_one_lt_n = icmp ult i32 %iv_minus_one, %n
%stay = or i1 %iv_lt_n, %iv_minus_one_lt_n
br i1 %stay, label %body, label %exit
body:
%body_iv_minus_one = add i32 -1, %iv
%body_iv_minus_one_nonneg = icmp sgt i32 %body_iv_minus_one, -1
br i1 %body_iv_minus_one_nonneg, label %do_load, label %latch
do_load:
%idx = zext nneg i32 %body_iv_minus_one to i64
%addr = getelementptr inbounds i32, ptr %arr, i64 %idx
%loaded = load i32, ptr %addr
br label %latch
latch:
%last_loaded.next = phi i32 [ %last_loaded, %body ], [ %loaded, %do_load ]
%iv.next = add i32 %iv, 1
br label %header
exit:
ret i32 %last_loaded
}