; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes='function(loop-unroll)' -unroll-count=8 -S %s | FileCheck %s
; Make sure non-SCEVable types are handled properly when invalidating SCEV
; dispositions.
define void @test(i32 %shift, ptr %dst, <8 x i32> %broadcast.splat) {
; CHECK-LABEL: @test(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = trunc <8 x i32> [[BROADCAST_SPLAT:%.*]] to <8 x i16>
; CHECK-NEXT: br label [[OUTER_HEADER:%.*]]
; CHECK: outer.header:
; CHECK-NEXT: br label [[INNER:%.*]]
; CHECK: inner:
; CHECK-NEXT: store <8 x i16> [[TMP0]], ptr [[DST:%.*]], align 2
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[SHIFT:%.*]], 0
; CHECK-NEXT: br i1 [[CMP]], label [[OUTER_HEADER_1:%.*]], label [[EXIT:%.*]]
; CHECK: outer.header.1:
; CHECK-NEXT: br label [[INNER_1:%.*]]
; CHECK: inner.1:
; CHECK-NEXT: store <8 x i16> [[TMP0]], ptr [[DST]], align 2
; CHECK-NEXT: [[CMP_1:%.*]] = icmp eq i32 [[SHIFT]], 0
; CHECK-NEXT: br i1 [[CMP_1]], label [[OUTER_HEADER_2:%.*]], label [[EXIT]]
; CHECK: outer.header.2:
; CHECK-NEXT: br label [[INNER_2:%.*]]
; CHECK: inner.2:
; CHECK-NEXT: store <8 x i16> [[TMP0]], ptr [[DST]], align 2
; CHECK-NEXT: [[CMP_2:%.*]] = icmp eq i32 [[SHIFT]], 0
; CHECK-NEXT: br i1 [[CMP_2]], label [[OUTER_HEADER_3:%.*]], label [[EXIT]]
; CHECK: outer.header.3:
; CHECK-NEXT: br label [[INNER_3:%.*]]
; CHECK: inner.3:
; CHECK-NEXT: store <8 x i16> [[TMP0]], ptr [[DST]], align 2
; CHECK-NEXT: [[CMP_3:%.*]] = icmp eq i32 [[SHIFT]], 0
; CHECK-NEXT: br i1 [[CMP_3]], label [[OUTER_HEADER_4:%.*]], label [[EXIT]]
; CHECK: outer.header.4:
; CHECK-NEXT: br label [[INNER_4:%.*]]
; CHECK: inner.4:
; CHECK-NEXT: store <8 x i16> [[TMP0]], ptr [[DST]], align 2
; CHECK-NEXT: [[CMP_4:%.*]] = icmp eq i32 [[SHIFT]], 0
; CHECK-NEXT: br i1 [[CMP_4]], label [[OUTER_HEADER_5:%.*]], label [[EXIT]]
; CHECK: outer.header.5:
; CHECK-NEXT: br label [[INNER_5:%.*]]
; CHECK: inner.5:
; CHECK-NEXT: store <8 x i16> [[TMP0]], ptr [[DST]], align 2
; CHECK-NEXT: [[CMP_5:%.*]] = icmp eq i32 [[SHIFT]], 0
; CHECK-NEXT: br i1 [[CMP_5]], label [[OUTER_HEADER_6:%.*]], label [[EXIT]]
; CHECK: outer.header.6:
; CHECK-NEXT: br label [[INNER_6:%.*]]
; CHECK: inner.6:
; CHECK-NEXT: store <8 x i16> [[TMP0]], ptr [[DST]], align 2
; CHECK-NEXT: [[CMP_6:%.*]] = icmp eq i32 [[SHIFT]], 0
; CHECK-NEXT: br i1 [[CMP_6]], label [[OUTER_HEADER_7:%.*]], label [[EXIT]]
; CHECK: outer.header.7:
; CHECK-NEXT: br label [[INNER_7:%.*]]
; CHECK: inner.7:
; CHECK-NEXT: store <8 x i16> [[TMP0]], ptr [[DST]], align 2
; CHECK-NEXT: [[CMP_7:%.*]] = icmp eq i32 [[SHIFT]], 0
; CHECK-NEXT: br i1 [[CMP_7]], label [[OUTER_HEADER]], label [[EXIT]], !llvm.loop [[LOOP0:![0-9]+]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %outer.header
outer.header:
br label %inner
inner:
%0 = trunc <8 x i32> %broadcast.splat to <8 x i16>
store <8 x i16> %0, ptr %dst, align 2
br i1 true, label %outer.latch, label %inner
outer.latch:
%cmp = icmp eq i32 %shift, 0
br i1 %cmp, label %outer.header, label %exit
exit:
ret void
}