1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes='function(loop-unroll)' -unroll-count=8 -S %s | FileCheck %s 3 4; Make sure non-SCEVable types are handled properly when invalidating SCEV 5; dispositions. 6define void @test(i32 %shift, ptr %dst, <8 x i32> %broadcast.splat) { 7; CHECK-LABEL: @test( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: [[TMP0:%.*]] = trunc <8 x i32> [[BROADCAST_SPLAT:%.*]] to <8 x i16> 10; CHECK-NEXT: br label [[OUTER_HEADER:%.*]] 11; CHECK: outer.header: 12; CHECK-NEXT: br label [[INNER:%.*]] 13; CHECK: inner: 14; CHECK-NEXT: store <8 x i16> [[TMP0]], ptr [[DST:%.*]], align 2 15; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[SHIFT:%.*]], 0 16; CHECK-NEXT: br i1 [[CMP]], label [[OUTER_HEADER_1:%.*]], label [[EXIT:%.*]] 17; CHECK: outer.header.1: 18; CHECK-NEXT: br label [[INNER_1:%.*]] 19; CHECK: inner.1: 20; CHECK-NEXT: store <8 x i16> [[TMP0]], ptr [[DST]], align 2 21; CHECK-NEXT: [[CMP_1:%.*]] = icmp eq i32 [[SHIFT]], 0 22; CHECK-NEXT: br i1 [[CMP_1]], label [[OUTER_HEADER_2:%.*]], label [[EXIT]] 23; CHECK: outer.header.2: 24; CHECK-NEXT: br label [[INNER_2:%.*]] 25; CHECK: inner.2: 26; CHECK-NEXT: store <8 x i16> [[TMP0]], ptr [[DST]], align 2 27; CHECK-NEXT: [[CMP_2:%.*]] = icmp eq i32 [[SHIFT]], 0 28; CHECK-NEXT: br i1 [[CMP_2]], label [[OUTER_HEADER_3:%.*]], label [[EXIT]] 29; CHECK: outer.header.3: 30; CHECK-NEXT: br label [[INNER_3:%.*]] 31; CHECK: inner.3: 32; CHECK-NEXT: store <8 x i16> [[TMP0]], ptr [[DST]], align 2 33; CHECK-NEXT: [[CMP_3:%.*]] = icmp eq i32 [[SHIFT]], 0 34; CHECK-NEXT: br i1 [[CMP_3]], label [[OUTER_HEADER_4:%.*]], label [[EXIT]] 35; CHECK: outer.header.4: 36; CHECK-NEXT: br label [[INNER_4:%.*]] 37; CHECK: inner.4: 38; CHECK-NEXT: store <8 x i16> [[TMP0]], ptr [[DST]], align 2 39; CHECK-NEXT: [[CMP_4:%.*]] = icmp eq i32 [[SHIFT]], 0 40; CHECK-NEXT: br i1 [[CMP_4]], label [[OUTER_HEADER_5:%.*]], label [[EXIT]] 41; CHECK: outer.header.5: 42; CHECK-NEXT: br label [[INNER_5:%.*]] 43; CHECK: inner.5: 44; CHECK-NEXT: store <8 x i16> [[TMP0]], ptr [[DST]], align 2 45; CHECK-NEXT: [[CMP_5:%.*]] = icmp eq i32 [[SHIFT]], 0 46; CHECK-NEXT: br i1 [[CMP_5]], label [[OUTER_HEADER_6:%.*]], label [[EXIT]] 47; CHECK: outer.header.6: 48; CHECK-NEXT: br label [[INNER_6:%.*]] 49; CHECK: inner.6: 50; CHECK-NEXT: store <8 x i16> [[TMP0]], ptr [[DST]], align 2 51; CHECK-NEXT: [[CMP_6:%.*]] = icmp eq i32 [[SHIFT]], 0 52; CHECK-NEXT: br i1 [[CMP_6]], label [[OUTER_HEADER_7:%.*]], label [[EXIT]] 53; CHECK: outer.header.7: 54; CHECK-NEXT: br label [[INNER_7:%.*]] 55; CHECK: inner.7: 56; CHECK-NEXT: store <8 x i16> [[TMP0]], ptr [[DST]], align 2 57; CHECK-NEXT: [[CMP_7:%.*]] = icmp eq i32 [[SHIFT]], 0 58; CHECK-NEXT: br i1 [[CMP_7]], label [[OUTER_HEADER]], label [[EXIT]], !llvm.loop [[LOOP0:![0-9]+]] 59; CHECK: exit: 60; CHECK-NEXT: ret void 61; 62entry: 63 br label %outer.header 64 65outer.header: 66 br label %inner 67 68inner: 69 %0 = trunc <8 x i32> %broadcast.splat to <8 x i16> 70 store <8 x i16> %0, ptr %dst, align 2 71 br i1 true, label %outer.latch, label %inner 72 73outer.latch: 74 %cmp = icmp eq i32 %shift, 0 75 br i1 %cmp, label %outer.header, label %exit 76 77exit: 78 ret void 79} 80