1d34bc66eSFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2d34bc66eSFlorian Hahn; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 3d34bc66eSFlorian Hahn 4d34bc66eSFlorian Hahntarget datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 5d34bc66eSFlorian Hahn 6d34bc66eSFlorian Hahn 7d34bc66eSFlorian Hahndeclare void @use(ptr) 8d34bc66eSFlorian Hahndeclare i1 @cond() 9d34bc66eSFlorian Hahn 10d34bc66eSFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_eq_to_uge(ptr %start) { 11d34bc66eSFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_eq_to_uge( 12d34bc66eSFlorian Hahn; CHECK-NEXT: loop.ph: 13d34bc66eSFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 10 14d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 15d34bc66eSFlorian Hahn; CHECK: loop.header: 16d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 17d34bc66eSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 18d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 19d34bc66eSFlorian Hahn; CHECK: for.body: 20*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 21d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 22d34bc66eSFlorian Hahn; CHECK: loop.latch: 23d34bc66eSFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 24d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 25d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 26d34bc66eSFlorian Hahn; CHECK: exit: 27d34bc66eSFlorian Hahn; CHECK-NEXT: ret void 28d34bc66eSFlorian Hahn; 29d34bc66eSFlorian Hahnloop.ph: 30d34bc66eSFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 10 31d34bc66eSFlorian Hahn br label %loop.header 32d34bc66eSFlorian Hahn 33d34bc66eSFlorian Hahnloop.header: 34d34bc66eSFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 35d34bc66eSFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 36d34bc66eSFlorian Hahn br i1 %c, label %exit, label %for.body 37d34bc66eSFlorian Hahn 38d34bc66eSFlorian Hahnfor.body: 39d34bc66eSFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 40d34bc66eSFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 41d34bc66eSFlorian Hahn %and = and i1 %t.1, %t.2 42d34bc66eSFlorian Hahn br i1 %and, label %loop.latch, label %exit 43d34bc66eSFlorian Hahn 44d34bc66eSFlorian Hahnloop.latch: 45d34bc66eSFlorian Hahn call void @use(ptr %ptr.iv) 46d34bc66eSFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 47d34bc66eSFlorian Hahn br label %loop.header 48d34bc66eSFlorian Hahn 49d34bc66eSFlorian Hahnexit: 50d34bc66eSFlorian Hahn ret void 51d34bc66eSFlorian Hahn} 52d34bc66eSFlorian Hahn 53d34bc66eSFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_upper_is_multiple_1(ptr %start) { 54d34bc66eSFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_multiple_1( 55d34bc66eSFlorian Hahn; CHECK-NEXT: loop.ph: 56d34bc66eSFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 15 57d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 58d34bc66eSFlorian Hahn; CHECK: loop.header: 59d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 60d34bc66eSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 61d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 62d34bc66eSFlorian Hahn; CHECK: for.body: 63*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 64d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 65d34bc66eSFlorian Hahn; CHECK: loop.latch: 66d34bc66eSFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 67d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1 68d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 69d34bc66eSFlorian Hahn; CHECK: exit: 70d34bc66eSFlorian Hahn; CHECK-NEXT: ret void 71d34bc66eSFlorian Hahn; 72d34bc66eSFlorian Hahnloop.ph: 73d34bc66eSFlorian Hahn %upper = getelementptr inbounds i8, ptr %start, i16 15 74d34bc66eSFlorian Hahn br label %loop.header 75d34bc66eSFlorian Hahn 76d34bc66eSFlorian Hahnloop.header: 77d34bc66eSFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 78d34bc66eSFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 79d34bc66eSFlorian Hahn br i1 %c, label %exit, label %for.body 80d34bc66eSFlorian Hahn 81d34bc66eSFlorian Hahnfor.body: 82d34bc66eSFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 83d34bc66eSFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 84d34bc66eSFlorian Hahn %and = and i1 %t.1, %t.2 85d34bc66eSFlorian Hahn br i1 %and, label %loop.latch, label %exit 86d34bc66eSFlorian Hahn 87d34bc66eSFlorian Hahnloop.latch: 88d34bc66eSFlorian Hahn call void @use(ptr %ptr.iv) 89d34bc66eSFlorian Hahn %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1 90d34bc66eSFlorian Hahn br label %loop.header 91d34bc66eSFlorian Hahn 92d34bc66eSFlorian Hahnexit: 93d34bc66eSFlorian Hahn ret void 94d34bc66eSFlorian Hahn} 95d34bc66eSFlorian Hahn 96d34bc66eSFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_upper_is_multiple_2(ptr %start) { 97d34bc66eSFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_multiple_2( 98d34bc66eSFlorian Hahn; CHECK-NEXT: loop.ph: 99d34bc66eSFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 16 100d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 101d34bc66eSFlorian Hahn; CHECK: loop.header: 102d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 103d34bc66eSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 104d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 105d34bc66eSFlorian Hahn; CHECK: for.body: 106*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 107d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 108d34bc66eSFlorian Hahn; CHECK: loop.latch: 109d34bc66eSFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 110d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i16 1 111d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 112d34bc66eSFlorian Hahn; CHECK: exit: 113d34bc66eSFlorian Hahn; CHECK-NEXT: ret void 114d34bc66eSFlorian Hahn; 115d34bc66eSFlorian Hahnloop.ph: 116d34bc66eSFlorian Hahn %upper = getelementptr inbounds i8, ptr %start, i16 16 117d34bc66eSFlorian Hahn br label %loop.header 118d34bc66eSFlorian Hahn 119d34bc66eSFlorian Hahnloop.header: 120d34bc66eSFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 121d34bc66eSFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 122d34bc66eSFlorian Hahn br i1 %c, label %exit, label %for.body 123d34bc66eSFlorian Hahn 124d34bc66eSFlorian Hahnfor.body: 125d34bc66eSFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 126d34bc66eSFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 127d34bc66eSFlorian Hahn %and = and i1 %t.1, %t.2 128d34bc66eSFlorian Hahn br i1 %and, label %loop.latch, label %exit 129d34bc66eSFlorian Hahn 130d34bc66eSFlorian Hahnloop.latch: 131d34bc66eSFlorian Hahn call void @use(ptr %ptr.iv) 132d34bc66eSFlorian Hahn %ptr.iv.next = getelementptr inbounds i16, ptr %ptr.iv, i16 1 133d34bc66eSFlorian Hahn br label %loop.header 134d34bc66eSFlorian Hahn 135d34bc66eSFlorian Hahnexit: 136d34bc66eSFlorian Hahn ret void 137d34bc66eSFlorian Hahn} 138d34bc66eSFlorian Hahn 139d34bc66eSFlorian Hahndefine void @test_monotonic_ptr_iv_inc_upper_is_not_multiple_1(ptr %start) { 140d34bc66eSFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_upper_is_not_multiple_1( 141d34bc66eSFlorian Hahn; CHECK-NEXT: loop.ph: 142d34bc66eSFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 15 143d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 144d34bc66eSFlorian Hahn; CHECK: loop.header: 145d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 146d34bc66eSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 147d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 148d34bc66eSFlorian Hahn; CHECK: for.body: 149d34bc66eSFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 150*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 151d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 152d34bc66eSFlorian Hahn; CHECK: loop.latch: 153d34bc66eSFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 154d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 155d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 156d34bc66eSFlorian Hahn; CHECK: exit: 157d34bc66eSFlorian Hahn; CHECK-NEXT: ret void 158d34bc66eSFlorian Hahn; 159d34bc66eSFlorian Hahnloop.ph: 160d34bc66eSFlorian Hahn %upper = getelementptr inbounds i8, ptr %start, i16 15 161d34bc66eSFlorian Hahn br label %loop.header 162d34bc66eSFlorian Hahn 163d34bc66eSFlorian Hahnloop.header: 164d34bc66eSFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 165d34bc66eSFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 166d34bc66eSFlorian Hahn br i1 %c, label %exit, label %for.body 167d34bc66eSFlorian Hahn 168d34bc66eSFlorian Hahnfor.body: 169d34bc66eSFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 170d34bc66eSFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 171d34bc66eSFlorian Hahn %and = and i1 %t.1, %t.2 172d34bc66eSFlorian Hahn br i1 %and, label %loop.latch, label %exit 173d34bc66eSFlorian Hahn 174d34bc66eSFlorian Hahnloop.latch: 175d34bc66eSFlorian Hahn call void @use(ptr %ptr.iv) 176d34bc66eSFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 177d34bc66eSFlorian Hahn br label %loop.header 178d34bc66eSFlorian Hahn 179d34bc66eSFlorian Hahnexit: 180d34bc66eSFlorian Hahn ret void 181d34bc66eSFlorian Hahn} 182d34bc66eSFlorian Hahn 183d34bc66eSFlorian Hahndefine void @test_monotonic_ptr_iv_inc_upper_is_not_multiple_2(ptr %start) { 184d34bc66eSFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_upper_is_not_multiple_2( 185d34bc66eSFlorian Hahn; CHECK-NEXT: loop.ph: 186d34bc66eSFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 15 187d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 188d34bc66eSFlorian Hahn; CHECK: loop.header: 189d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 190d34bc66eSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 191d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 192d34bc66eSFlorian Hahn; CHECK: for.body: 193d34bc66eSFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 194*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 195d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 196d34bc66eSFlorian Hahn; CHECK: loop.latch: 197d34bc66eSFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 198d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 199d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 200d34bc66eSFlorian Hahn; CHECK: exit: 201d34bc66eSFlorian Hahn; CHECK-NEXT: ret void 202d34bc66eSFlorian Hahn; 203d34bc66eSFlorian Hahnloop.ph: 204d34bc66eSFlorian Hahn %upper = getelementptr inbounds i8, ptr %start, i16 15 205d34bc66eSFlorian Hahn br label %loop.header 206d34bc66eSFlorian Hahn 207d34bc66eSFlorian Hahnloop.header: 208d34bc66eSFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 209d34bc66eSFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 210d34bc66eSFlorian Hahn br i1 %c, label %exit, label %for.body 211d34bc66eSFlorian Hahn 212d34bc66eSFlorian Hahnfor.body: 213d34bc66eSFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 214d34bc66eSFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 215d34bc66eSFlorian Hahn %and = and i1 %t.1, %t.2 216d34bc66eSFlorian Hahn br i1 %and, label %loop.latch, label %exit 217d34bc66eSFlorian Hahn 218d34bc66eSFlorian Hahnloop.latch: 219d34bc66eSFlorian Hahn call void @use(ptr %ptr.iv) 220d34bc66eSFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 221d34bc66eSFlorian Hahn br label %loop.header 222d34bc66eSFlorian Hahn 223d34bc66eSFlorian Hahnexit: 224d34bc66eSFlorian Hahn ret void 225d34bc66eSFlorian Hahn} 226d34bc66eSFlorian Hahn 227d34bc66eSFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_upper_is_multiple_with_early_exit_1(ptr %start) { 228d34bc66eSFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_multiple_with_early_exit_1( 229d34bc66eSFlorian Hahn; CHECK-NEXT: loop.ph: 230d34bc66eSFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 10 231d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 232d34bc66eSFlorian Hahn; CHECK: loop.header: 233d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 234d34bc66eSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 235d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 236d34bc66eSFlorian Hahn; CHECK: for.body: 237d34bc66eSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 238d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 239d34bc66eSFlorian Hahn; CHECK: loop.next: 240*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 241d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 242d34bc66eSFlorian Hahn; CHECK: loop.latch: 243d34bc66eSFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 244d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1 245d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 246d34bc66eSFlorian Hahn; CHECK: exit: 247d34bc66eSFlorian Hahn; CHECK-NEXT: ret void 248d34bc66eSFlorian Hahn; 249d34bc66eSFlorian Hahnloop.ph: 250d34bc66eSFlorian Hahn %upper = getelementptr inbounds i8, ptr %start, i16 10 251d34bc66eSFlorian Hahn br label %loop.header 252d34bc66eSFlorian Hahn 253d34bc66eSFlorian Hahnloop.header: 254d34bc66eSFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 255d34bc66eSFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 256d34bc66eSFlorian Hahn br i1 %c, label %exit, label %for.body 257d34bc66eSFlorian Hahn 258d34bc66eSFlorian Hahnfor.body: 259d34bc66eSFlorian Hahn %c.1 = call i1 @cond() 260d34bc66eSFlorian Hahn br i1 %c.1, label %loop.next, label %exit 261d34bc66eSFlorian Hahn 262d34bc66eSFlorian Hahnloop.next: 263d34bc66eSFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 264d34bc66eSFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 265d34bc66eSFlorian Hahn %and = and i1 %t.1, %t.2 266d34bc66eSFlorian Hahn br i1 %and, label %loop.latch, label %exit 267d34bc66eSFlorian Hahn 268d34bc66eSFlorian Hahnloop.latch: 269d34bc66eSFlorian Hahn call void @use(ptr %ptr.iv) 270d34bc66eSFlorian Hahn %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1 271d34bc66eSFlorian Hahn br label %loop.header 272d34bc66eSFlorian Hahn 273d34bc66eSFlorian Hahnexit: 274d34bc66eSFlorian Hahn ret void 275d34bc66eSFlorian Hahn} 276d34bc66eSFlorian Hahn 277d34bc66eSFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_upper_is_multiple_with_early_exit_2(ptr %start) { 278d34bc66eSFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_multiple_with_early_exit_2( 279d34bc66eSFlorian Hahn; CHECK-NEXT: loop.ph: 280d34bc66eSFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 10 281d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 282d34bc66eSFlorian Hahn; CHECK: loop.header: 283d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 284d34bc66eSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 285d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 286d34bc66eSFlorian Hahn; CHECK: for.body: 287d34bc66eSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 288d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 289d34bc66eSFlorian Hahn; CHECK: loop.next: 290*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 291d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 292d34bc66eSFlorian Hahn; CHECK: loop.latch: 293d34bc66eSFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 294d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i16 1 295d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 296d34bc66eSFlorian Hahn; CHECK: exit: 297d34bc66eSFlorian Hahn; CHECK-NEXT: ret void 298d34bc66eSFlorian Hahn; 299d34bc66eSFlorian Hahnloop.ph: 300d34bc66eSFlorian Hahn %upper = getelementptr inbounds i8, ptr %start, i16 10 301d34bc66eSFlorian Hahn br label %loop.header 302d34bc66eSFlorian Hahn 303d34bc66eSFlorian Hahnloop.header: 304d34bc66eSFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 305d34bc66eSFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 306d34bc66eSFlorian Hahn br i1 %c, label %exit, label %for.body 307d34bc66eSFlorian Hahn 308d34bc66eSFlorian Hahnfor.body: 309d34bc66eSFlorian Hahn %c.1 = call i1 @cond() 310d34bc66eSFlorian Hahn br i1 %c.1, label %loop.next, label %exit 311d34bc66eSFlorian Hahn 312d34bc66eSFlorian Hahnloop.next: 313d34bc66eSFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 314d34bc66eSFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 315d34bc66eSFlorian Hahn %and = and i1 %t.1, %t.2 316d34bc66eSFlorian Hahn br i1 %and, label %loop.latch, label %exit 317d34bc66eSFlorian Hahn 318d34bc66eSFlorian Hahnloop.latch: 319d34bc66eSFlorian Hahn call void @use(ptr %ptr.iv) 320d34bc66eSFlorian Hahn %ptr.iv.next = getelementptr inbounds i16, ptr %ptr.iv, i16 1 321d34bc66eSFlorian Hahn br label %loop.header 322d34bc66eSFlorian Hahn 323d34bc66eSFlorian Hahnexit: 324d34bc66eSFlorian Hahn ret void 325d34bc66eSFlorian Hahn} 326d34bc66eSFlorian Hahn 327d34bc66eSFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_upper_is_multiple_with_early_exit_3(ptr %start) { 328d34bc66eSFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_multiple_with_early_exit_3( 329d34bc66eSFlorian Hahn; CHECK-NEXT: loop.ph: 330d34bc66eSFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i16, ptr [[START:%.*]], i16 16 331d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 332d34bc66eSFlorian Hahn; CHECK: loop.header: 333d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 334d34bc66eSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 335d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 336d34bc66eSFlorian Hahn; CHECK: for.body: 337d34bc66eSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 338d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 339d34bc66eSFlorian Hahn; CHECK: loop.next: 340*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 341d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 342d34bc66eSFlorian Hahn; CHECK: loop.latch: 343d34bc66eSFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 344d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 345d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 346d34bc66eSFlorian Hahn; CHECK: exit: 347d34bc66eSFlorian Hahn; CHECK-NEXT: ret void 348d34bc66eSFlorian Hahn; 349d34bc66eSFlorian Hahnloop.ph: 350d34bc66eSFlorian Hahn %upper = getelementptr inbounds i16, ptr %start, i16 16 351d34bc66eSFlorian Hahn br label %loop.header 352d34bc66eSFlorian Hahn 353d34bc66eSFlorian Hahnloop.header: 354d34bc66eSFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 355d34bc66eSFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 356d34bc66eSFlorian Hahn br i1 %c, label %exit, label %for.body 357d34bc66eSFlorian Hahn 358d34bc66eSFlorian Hahnfor.body: 359d34bc66eSFlorian Hahn %c.1 = call i1 @cond() 360d34bc66eSFlorian Hahn br i1 %c.1, label %loop.next, label %exit 361d34bc66eSFlorian Hahn 362d34bc66eSFlorian Hahnloop.next: 363d34bc66eSFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 364d34bc66eSFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 365d34bc66eSFlorian Hahn %and = and i1 %t.1, %t.2 366d34bc66eSFlorian Hahn br i1 %and, label %loop.latch, label %exit 367d34bc66eSFlorian Hahn 368d34bc66eSFlorian Hahnloop.latch: 369d34bc66eSFlorian Hahn call void @use(ptr %ptr.iv) 370d34bc66eSFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 371d34bc66eSFlorian Hahn br label %loop.header 372d34bc66eSFlorian Hahn 373d34bc66eSFlorian Hahnexit: 374d34bc66eSFlorian Hahn ret void 375d34bc66eSFlorian Hahn} 376d34bc66eSFlorian Hahn 377d34bc66eSFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_upper_is_no_multiple_with_early_exit_1(ptr %start) { 378d34bc66eSFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_no_multiple_with_early_exit_1( 379d34bc66eSFlorian Hahn; CHECK-NEXT: loop.ph: 380d34bc66eSFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 10 381d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 382d34bc66eSFlorian Hahn; CHECK: loop.header: 383d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 384d34bc66eSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 385d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 386d34bc66eSFlorian Hahn; CHECK: for.body: 387d34bc66eSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 388d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 389d34bc66eSFlorian Hahn; CHECK: loop.next: 390d34bc66eSFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 391*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 392d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 393d34bc66eSFlorian Hahn; CHECK: loop.latch: 394d34bc66eSFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 395d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 396d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 397d34bc66eSFlorian Hahn; CHECK: exit: 398d34bc66eSFlorian Hahn; CHECK-NEXT: ret void 399d34bc66eSFlorian Hahn; 400d34bc66eSFlorian Hahnloop.ph: 401d34bc66eSFlorian Hahn %upper = getelementptr inbounds i8, ptr %start, i16 10 402d34bc66eSFlorian Hahn br label %loop.header 403d34bc66eSFlorian Hahn 404d34bc66eSFlorian Hahnloop.header: 405d34bc66eSFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 406d34bc66eSFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 407d34bc66eSFlorian Hahn br i1 %c, label %exit, label %for.body 408d34bc66eSFlorian Hahn 409d34bc66eSFlorian Hahnfor.body: 410d34bc66eSFlorian Hahn %c.1 = call i1 @cond() 411d34bc66eSFlorian Hahn br i1 %c.1, label %loop.next, label %exit 412d34bc66eSFlorian Hahn 413d34bc66eSFlorian Hahnloop.next: 414d34bc66eSFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 415d34bc66eSFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 416d34bc66eSFlorian Hahn %and = and i1 %t.1, %t.2 417d34bc66eSFlorian Hahn br i1 %and, label %loop.latch, label %exit 418d34bc66eSFlorian Hahn 419d34bc66eSFlorian Hahnloop.latch: 420d34bc66eSFlorian Hahn call void @use(ptr %ptr.iv) 421d34bc66eSFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 422d34bc66eSFlorian Hahn br label %loop.header 423d34bc66eSFlorian Hahn 424d34bc66eSFlorian Hahnexit: 425d34bc66eSFlorian Hahn ret void 426d34bc66eSFlorian Hahn} 427d34bc66eSFlorian Hahn 428d34bc66eSFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_upper_is_no_multiple_with_early_exit_2(ptr %start) { 429d34bc66eSFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_no_multiple_with_early_exit_2( 430d34bc66eSFlorian Hahn; CHECK-NEXT: loop.ph: 431d34bc66eSFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 11 432d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 433d34bc66eSFlorian Hahn; CHECK: loop.header: 434d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 435d34bc66eSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 436d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 437d34bc66eSFlorian Hahn; CHECK: for.body: 438d34bc66eSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 439d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 440d34bc66eSFlorian Hahn; CHECK: loop.next: 441d34bc66eSFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 442*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 443d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 444d34bc66eSFlorian Hahn; CHECK: loop.latch: 445d34bc66eSFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 446d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i16 1 447d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 448d34bc66eSFlorian Hahn; CHECK: exit: 449d34bc66eSFlorian Hahn; CHECK-NEXT: ret void 450d34bc66eSFlorian Hahn; 451d34bc66eSFlorian Hahnloop.ph: 452d34bc66eSFlorian Hahn %upper = getelementptr inbounds i8, ptr %start, i16 11 453d34bc66eSFlorian Hahn br label %loop.header 454d34bc66eSFlorian Hahn 455d34bc66eSFlorian Hahnloop.header: 456d34bc66eSFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 457d34bc66eSFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 458d34bc66eSFlorian Hahn br i1 %c, label %exit, label %for.body 459d34bc66eSFlorian Hahn 460d34bc66eSFlorian Hahnfor.body: 461d34bc66eSFlorian Hahn %c.1 = call i1 @cond() 462d34bc66eSFlorian Hahn br i1 %c.1, label %loop.next, label %exit 463d34bc66eSFlorian Hahn 464d34bc66eSFlorian Hahnloop.next: 465d34bc66eSFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 466d34bc66eSFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 467d34bc66eSFlorian Hahn %and = and i1 %t.1, %t.2 468d34bc66eSFlorian Hahn br i1 %and, label %loop.latch, label %exit 469d34bc66eSFlorian Hahn 470d34bc66eSFlorian Hahnloop.latch: 471d34bc66eSFlorian Hahn call void @use(ptr %ptr.iv) 472d34bc66eSFlorian Hahn %ptr.iv.next = getelementptr inbounds i16, ptr %ptr.iv, i16 1 473d34bc66eSFlorian Hahn br label %loop.header 474d34bc66eSFlorian Hahn 475d34bc66eSFlorian Hahnexit: 476d34bc66eSFlorian Hahn ret void 477d34bc66eSFlorian Hahn} 478d34bc66eSFlorian Hahn 479d34bc66eSFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_upper_is_no_multiple_with_early_exit_3(ptr %start) { 480d34bc66eSFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_upper_is_no_multiple_with_early_exit_3( 481d34bc66eSFlorian Hahn; CHECK-NEXT: loop.ph: 482d34bc66eSFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i16, ptr [[START:%.*]], i16 9 483d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 484d34bc66eSFlorian Hahn; CHECK: loop.header: 485d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH:%.*]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 486d34bc66eSFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 487d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[FOR_BODY:%.*]] 488d34bc66eSFlorian Hahn; CHECK: for.body: 489d34bc66eSFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 490d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 491d34bc66eSFlorian Hahn; CHECK: loop.next: 492d34bc66eSFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 493*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 494d34bc66eSFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 495d34bc66eSFlorian Hahn; CHECK: loop.latch: 496d34bc66eSFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 497d34bc66eSFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 498d34bc66eSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 499d34bc66eSFlorian Hahn; CHECK: exit: 500d34bc66eSFlorian Hahn; CHECK-NEXT: ret void 501d34bc66eSFlorian Hahn; 502d34bc66eSFlorian Hahnloop.ph: 503d34bc66eSFlorian Hahn %upper = getelementptr inbounds i16, ptr %start, i16 9 504d34bc66eSFlorian Hahn br label %loop.header 505d34bc66eSFlorian Hahn 506d34bc66eSFlorian Hahnloop.header: 507d34bc66eSFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 508d34bc66eSFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 509d34bc66eSFlorian Hahn br i1 %c, label %exit, label %for.body 510d34bc66eSFlorian Hahn 511d34bc66eSFlorian Hahnfor.body: 512d34bc66eSFlorian Hahn %c.1 = call i1 @cond() 513d34bc66eSFlorian Hahn br i1 %c.1, label %loop.next, label %exit 514d34bc66eSFlorian Hahn 515d34bc66eSFlorian Hahnloop.next: 516d34bc66eSFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 517d34bc66eSFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 518d34bc66eSFlorian Hahn %and = and i1 %t.1, %t.2 519d34bc66eSFlorian Hahn br i1 %and, label %loop.latch, label %exit 520d34bc66eSFlorian Hahn 521d34bc66eSFlorian Hahnloop.latch: 522d34bc66eSFlorian Hahn call void @use(ptr %ptr.iv) 523d34bc66eSFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 524d34bc66eSFlorian Hahn br label %loop.header 525d34bc66eSFlorian Hahn 526d34bc66eSFlorian Hahnexit: 527d34bc66eSFlorian Hahn ret void 528d34bc66eSFlorian Hahn} 529