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