1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -loop-reduce -S | FileCheck %s 3; REQUIRES: x86-registered-target 4 5target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2" 6target triple = "x86_64-unknown-linux-gnu" 7 8; FIXME: iv.next is supposed to be inserted in the backedge. 9define i32 @test_01(i32* %p, i64 %len, i32 %x) { 10; CHECK-LABEL: @test_01( 11; CHECK-NEXT: entry: 12; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 -1 13; CHECK-NEXT: br label [[LOOP:%.*]] 14; CHECK: loop: 15; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[LEN:%.*]], [[ENTRY:%.*]] ] 16; CHECK-NEXT: [[COND_1:%.*]] = icmp eq i64 [[IV]], 0 17; CHECK-NEXT: br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]] 18; CHECK: backedge: 19; CHECK-NEXT: [[SCEVGEP1:%.*]] = getelementptr i32, i32* [[SCEVGEP]], i64 [[IV]] 20; CHECK-NEXT: [[LOADED:%.*]] = load atomic i32, i32* [[SCEVGEP1]] unordered, align 4 21; CHECK-NEXT: [[COND_2:%.*]] = icmp eq i32 [[LOADED]], [[X:%.*]] 22; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], -1 23; CHECK-NEXT: br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]] 24; CHECK: exit: 25; CHECK-NEXT: ret i32 -1 26; CHECK: failure: 27; CHECK-NEXT: unreachable 28; 29entry: 30 br label %loop 31 32loop: ; preds = %backedge, %entry 33 %iv = phi i64 [ %iv.next, %backedge ], [ %len, %entry ] 34 %iv.next = add nsw i64 %iv, -1 35 %cond_1 = icmp eq i64 %iv, 0 36 br i1 %cond_1, label %exit, label %backedge 37 38backedge: ; preds = %loop 39 %addr = getelementptr inbounds i32, i32* %p, i64 %iv.next 40 %loaded = load atomic i32, i32* %addr unordered, align 4 41 %cond_2 = icmp eq i32 %loaded, %x 42 br i1 %cond_2, label %failure, label %loop 43 44exit: ; preds = %loop 45 ret i32 -1 46 47failure: ; preds = %backedge 48 unreachable 49} 50 51define i32 @test_02(i32* %p, i64 %len, i32 %x) { 52; CHECK-LABEL: @test_02( 53; CHECK-NEXT: entry: 54; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 -1 55; CHECK-NEXT: br label [[LOOP:%.*]] 56; CHECK: loop: 57; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[LEN:%.*]], [[ENTRY:%.*]] ] 58; CHECK-NEXT: [[COND_1:%.*]] = icmp eq i64 [[LSR_IV]], 0 59; CHECK-NEXT: br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]] 60; CHECK: backedge: 61; CHECK-NEXT: [[SCEVGEP1:%.*]] = getelementptr i32, i32* [[SCEVGEP]], i64 [[LSR_IV]] 62; CHECK-NEXT: [[LOADED:%.*]] = load atomic i32, i32* [[SCEVGEP1]] unordered, align 4 63; CHECK-NEXT: [[COND_2:%.*]] = icmp eq i32 [[LOADED]], [[X:%.*]] 64; CHECK-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -1 65; CHECK-NEXT: br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]] 66; CHECK: exit: 67; CHECK-NEXT: ret i32 -1 68; CHECK: failure: 69; CHECK-NEXT: unreachable 70; 71entry: 72 %start = add i64 %len, -1 73 br label %loop 74 75loop: ; preds = %backedge, %entry 76 %iv = phi i64 [ %iv.next, %backedge ], [ %start, %entry ] 77 %iv.next = add nsw i64 %iv, -1 78 %iv.offset = add i64 %iv, 1 79 %iv.next.offset = add i64 %iv.next, 1 80 %cond_1 = icmp eq i64 %iv.offset, 0 81 br i1 %cond_1, label %exit, label %backedge 82 83backedge: ; preds = %loop 84 %addr = getelementptr inbounds i32, i32* %p, i64 %iv.next.offset 85 %loaded = load atomic i32, i32* %addr unordered, align 4 86 %cond_2 = icmp eq i32 %loaded, %x 87 br i1 %cond_2, label %failure, label %loop 88 89exit: ; preds = %loop 90 ret i32 -1 91 92failure: ; preds = %backedge 93 unreachable 94} 95 96define i32 @test_03(i32* %p, i64 %len, i32 %x) { 97; CHECK-LABEL: @test_03( 98; CHECK-NEXT: entry: 99; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 -1 100; CHECK-NEXT: br label [[LOOP:%.*]] 101; CHECK: loop: 102; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[LEN:%.*]], [[ENTRY:%.*]] ] 103; CHECK-NEXT: [[COND_1:%.*]] = icmp eq i64 [[LSR_IV]], 0 104; CHECK-NEXT: br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]] 105; CHECK: backedge: 106; CHECK-NEXT: [[SCEVGEP1:%.*]] = getelementptr i32, i32* [[SCEVGEP]], i64 [[LSR_IV]] 107; CHECK-NEXT: [[LOADED:%.*]] = load atomic i32, i32* [[SCEVGEP1]] unordered, align 4 108; CHECK-NEXT: [[COND_2:%.*]] = icmp eq i32 [[LOADED]], [[X:%.*]] 109; CHECK-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -1 110; CHECK-NEXT: br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]] 111; CHECK: exit: 112; CHECK-NEXT: ret i32 -1 113; CHECK: failure: 114; CHECK-NEXT: unreachable 115; 116entry: 117 %start = add i64 %len, -100 118 br label %loop 119 120loop: ; preds = %backedge, %entry 121 %iv = phi i64 [ %iv.next, %backedge ], [ %start, %entry ] 122 %iv.next = add nsw i64 %iv, -1 123 %iv.offset = add i64 %iv, 100 124 %iv.next.offset = add i64 %iv.next, 100 125 %cond_1 = icmp eq i64 %iv.offset, 0 126 br i1 %cond_1, label %exit, label %backedge 127 128backedge: ; preds = %loop 129 %addr = getelementptr inbounds i32, i32* %p, i64 %iv.next.offset 130 %loaded = load atomic i32, i32* %addr unordered, align 4 131 %cond_2 = icmp eq i32 %loaded, %x 132 br i1 %cond_2, label %failure, label %loop 133 134exit: ; preds = %loop 135 ret i32 -1 136 137failure: ; preds = %backedge 138 unreachable 139} 140 141define i32 @test_04(i32* %p, i64 %len, i32 %x) { 142; CHECK-LABEL: @test_04( 143; CHECK-NEXT: entry: 144; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 -1 145; CHECK-NEXT: br label [[LOOP:%.*]] 146; CHECK: loop: 147; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[LEN:%.*]], [[ENTRY:%.*]] ] 148; CHECK-NEXT: [[COND_1:%.*]] = icmp eq i64 [[IV]], 0 149; CHECK-NEXT: br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]] 150; CHECK: backedge: 151; CHECK-NEXT: [[SCEVGEP1:%.*]] = getelementptr i32, i32* [[SCEVGEP]], i64 [[IV]] 152; CHECK-NEXT: [[LOADED:%.*]] = load atomic i32, i32* [[SCEVGEP1]] unordered, align 4 153; CHECK-NEXT: [[COND_2:%.*]] = icmp eq i32 [[LOADED]], [[X:%.*]] 154; CHECK-NEXT: [[IV_NEXT]] = sub i64 [[IV]], 1 155; CHECK-NEXT: br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]] 156; CHECK: exit: 157; CHECK-NEXT: ret i32 -1 158; CHECK: failure: 159; CHECK-NEXT: unreachable 160; 161entry: 162 br label %loop 163 164loop: ; preds = %backedge, %entry 165 %iv = phi i64 [ %iv.next, %backedge ], [ %len, %entry ] 166 %iv.next = sub i64 %iv, 1 167 %cond_1 = icmp eq i64 %iv, 0 168 br i1 %cond_1, label %exit, label %backedge 169 170backedge: ; preds = %loop 171 %addr = getelementptr inbounds i32, i32* %p, i64 %iv.next 172 %loaded = load atomic i32, i32* %addr unordered, align 4 173 %cond_2 = icmp eq i32 %loaded, %x 174 br i1 %cond_2, label %failure, label %loop 175 176exit: ; preds = %loop 177 ret i32 -1 178 179failure: ; preds = %backedge 180 unreachable 181} 182 183define i32 @test_05(i32* %p, i64 %len, i32 %x) { 184; CHECK-LABEL: @test_05( 185; CHECK-NEXT: entry: 186; CHECK-NEXT: br label [[LOOP:%.*]] 187; CHECK: loop: 188; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[LEN:%.*]], [[ENTRY:%.*]] ] 189; CHECK-NEXT: [[IV_NEXT]] = mul i64 [[IV]], 2 190; CHECK-NEXT: [[COND_1:%.*]] = icmp eq i64 [[IV]], 0 191; CHECK-NEXT: br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]] 192; CHECK: backedge: 193; CHECK-NEXT: [[ADDR:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 [[IV_NEXT]] 194; CHECK-NEXT: [[LOADED:%.*]] = load atomic i32, i32* [[ADDR]] unordered, align 4 195; CHECK-NEXT: [[COND_2:%.*]] = icmp eq i32 [[LOADED]], [[X:%.*]] 196; CHECK-NEXT: br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]] 197; CHECK: exit: 198; CHECK-NEXT: ret i32 -1 199; CHECK: failure: 200; CHECK-NEXT: unreachable 201; 202entry: 203 br label %loop 204 205loop: ; preds = %backedge, %entry 206 %iv = phi i64 [ %iv.next, %backedge ], [ %len, %entry ] 207 %iv.next = mul i64 %iv, 2 208 %cond_1 = icmp eq i64 %iv, 0 209 br i1 %cond_1, label %exit, label %backedge 210 211backedge: ; preds = %loop 212 %addr = getelementptr inbounds i32, i32* %p, i64 %iv.next 213 %loaded = load atomic i32, i32* %addr unordered, align 4 214 %cond_2 = icmp eq i32 %loaded, %x 215 br i1 %cond_2, label %failure, label %loop 216 217exit: ; preds = %loop 218 ret i32 -1 219 220failure: ; preds = %backedge 221 unreachable 222} 223 224define i32 @test_06(i32* %p, i64 %len, i32 %x, i64 %step) { 225; CHECK-LABEL: @test_06( 226; CHECK-NEXT: entry: 227; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[STEP:%.*]] 228; CHECK-NEXT: br label [[LOOP:%.*]] 229; CHECK: loop: 230; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[LEN:%.*]], [[ENTRY:%.*]] ] 231; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], [[STEP]] 232; CHECK-NEXT: [[COND_1:%.*]] = icmp eq i64 [[STEP]], [[IV_NEXT]] 233; CHECK-NEXT: br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]] 234; CHECK: backedge: 235; CHECK-NEXT: [[SCEVGEP1:%.*]] = getelementptr i32, i32* [[SCEVGEP]], i64 [[IV]] 236; CHECK-NEXT: [[LOADED:%.*]] = load atomic i32, i32* [[SCEVGEP1]] unordered, align 4 237; CHECK-NEXT: [[COND_2:%.*]] = icmp eq i32 [[LOADED]], [[X:%.*]] 238; CHECK-NEXT: br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]] 239; CHECK: exit: 240; CHECK-NEXT: ret i32 -1 241; CHECK: failure: 242; CHECK-NEXT: unreachable 243; 244entry: 245 br label %loop 246 247loop: ; preds = %backedge, %entry 248 %iv = phi i64 [ %iv.next, %backedge ], [ %len, %entry ] 249 %iv.next = add nsw i64 %iv, %step 250 %cond_1 = icmp eq i64 %iv, 0 251 br i1 %cond_1, label %exit, label %backedge 252 253backedge: ; preds = %loop 254 %addr = getelementptr inbounds i32, i32* %p, i64 %iv.next 255 %loaded = load atomic i32, i32* %addr unordered, align 4 256 %cond_2 = icmp eq i32 %loaded, %x 257 br i1 %cond_2, label %failure, label %loop 258 259exit: ; preds = %loop 260 ret i32 -1 261 262failure: ; preds = %backedge 263 unreachable 264} 265