1cbacab26SFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2cbacab26SFlorian Hahn; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 3cbacab26SFlorian Hahn 4cbacab26SFlorian Hahntarget datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 5cbacab26SFlorian Hahn 6cbacab26SFlorian Hahn 7cbacab26SFlorian Hahndeclare void @use(ptr) 8cbacab26SFlorian Hahndeclare void @use.i1(i1) 9cbacab26SFlorian Hahndeclare void @llvm.assume(i1) 10cbacab26SFlorian Hahndeclare i1 @cond() 11cbacab26SFlorian Hahn 12cbacab26SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_different_element_types_1_with_early_exit(ptr %start, i16 %len) { 13cbacab26SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types_1_with_early_exit( 14cbacab26SFlorian Hahn; CHECK-NEXT: entry: 15cbacab26SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 16cbacab26SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 17cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 18cbacab26SFlorian Hahn; CHECK: loop.ph: 19cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 20cbacab26SFlorian Hahn; CHECK: loop.header: 21cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 22cbacab26SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 23cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 24cbacab26SFlorian Hahn; CHECK: for.body: 25cbacab26SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 26cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 27cbacab26SFlorian Hahn; CHECK: loop.next: 28*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 29cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 30cbacab26SFlorian Hahn; CHECK: loop.latch: 31cbacab26SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 32cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1 33cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 34cbacab26SFlorian Hahn; CHECK: exit: 35cbacab26SFlorian Hahn; CHECK-NEXT: ret void 36cbacab26SFlorian Hahn; 37cbacab26SFlorian Hahnentry: 38cbacab26SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 39cbacab26SFlorian Hahn %len.neg = icmp slt i16 %len, 0 40cbacab26SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 41cbacab26SFlorian Hahn 42cbacab26SFlorian Hahnloop.ph: 43cbacab26SFlorian Hahn br label %loop.header 44cbacab26SFlorian Hahn 45cbacab26SFlorian Hahnloop.header: 46cbacab26SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 47cbacab26SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 48cbacab26SFlorian Hahn br i1 %c, label %exit, label %for.body 49cbacab26SFlorian Hahn 50cbacab26SFlorian Hahnfor.body: 51cbacab26SFlorian Hahn %c.1 = call i1 @cond() 52cbacab26SFlorian Hahn br i1 %c.1, label %loop.next, label %exit 53cbacab26SFlorian Hahn 54cbacab26SFlorian Hahnloop.next: 55cbacab26SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 56cbacab26SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 57cbacab26SFlorian Hahn %and = and i1 %t.1, %t.2 58cbacab26SFlorian Hahn br i1 %and, label %loop.latch, label %exit 59cbacab26SFlorian Hahn 60cbacab26SFlorian Hahnloop.latch: 61cbacab26SFlorian Hahn call void @use(ptr %ptr.iv) 62cbacab26SFlorian Hahn %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1 63cbacab26SFlorian Hahn br label %loop.header 64cbacab26SFlorian Hahn 65cbacab26SFlorian Hahnexit: 66cbacab26SFlorian Hahn ret void 67cbacab26SFlorian Hahn} 68cbacab26SFlorian Hahn 69cbacab26SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_2_different_element_types_1_with_early_exit(ptr %start, i16 %len) { 70cbacab26SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_2_different_element_types_1_with_early_exit( 71cbacab26SFlorian Hahn; CHECK-NEXT: entry: 72cbacab26SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i8, ptr [[START:%.*]], i16 [[LEN:%.*]] 73cbacab26SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 74cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 75cbacab26SFlorian Hahn; CHECK: loop.ph: 76cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 77cbacab26SFlorian Hahn; CHECK: loop.header: 78cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 79cbacab26SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 80cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 81cbacab26SFlorian Hahn; CHECK: for.body: 82cbacab26SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 83cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 84cbacab26SFlorian Hahn; CHECK: loop.next: 85cbacab26SFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 86*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 87cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 88cbacab26SFlorian Hahn; CHECK: loop.latch: 89cbacab26SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 90cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 91cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 92cbacab26SFlorian Hahn; CHECK: exit: 93cbacab26SFlorian Hahn; CHECK-NEXT: ret void 94cbacab26SFlorian Hahn; 95cbacab26SFlorian Hahnentry: 96cbacab26SFlorian Hahn %upper = getelementptr inbounds i8, ptr %start, i16 %len 97cbacab26SFlorian Hahn %len.neg = icmp slt i16 %len, 0 98cbacab26SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 99cbacab26SFlorian Hahn 100cbacab26SFlorian Hahnloop.ph: 101cbacab26SFlorian Hahn br label %loop.header 102cbacab26SFlorian Hahn 103cbacab26SFlorian Hahnloop.header: 104cbacab26SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 105cbacab26SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 106cbacab26SFlorian Hahn br i1 %c, label %exit, label %for.body 107cbacab26SFlorian Hahn 108cbacab26SFlorian Hahnfor.body: 109cbacab26SFlorian Hahn %c.1 = call i1 @cond() 110cbacab26SFlorian Hahn br i1 %c.1, label %loop.next, label %exit 111cbacab26SFlorian Hahn 112cbacab26SFlorian Hahnloop.next: 113cbacab26SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 114cbacab26SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 115cbacab26SFlorian Hahn %and = and i1 %t.1, %t.2 116cbacab26SFlorian Hahn br i1 %and, label %loop.latch, label %exit 117cbacab26SFlorian Hahn 118cbacab26SFlorian Hahnloop.latch: 119cbacab26SFlorian Hahn call void @use(ptr %ptr.iv) 120cbacab26SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 121cbacab26SFlorian Hahn br label %loop.header 122cbacab26SFlorian Hahn 123cbacab26SFlorian Hahnexit: 124cbacab26SFlorian Hahn ret void 125cbacab26SFlorian Hahn} 126cbacab26SFlorian Hahn 127cbacab26SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_gep_step_size_i8_unknown_end_ptr_with_early_exit(ptr %start, ptr %end) { 128cbacab26SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_gep_step_size_i8_unknown_end_ptr_with_early_exit( 129cbacab26SFlorian Hahn; CHECK-NEXT: entry: 130cbacab26SFlorian Hahn; CHECK-NEXT: [[START_ULT_END:%.*]] = icmp uge ptr [[START:%.*]], [[END:%.*]] 131cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[START_ULT_END]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 132cbacab26SFlorian Hahn; CHECK: loop.ph: 133cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 134cbacab26SFlorian Hahn; CHECK: loop.header: 135cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 136cbacab26SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[END]] 137cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 138cbacab26SFlorian Hahn; CHECK: for.body: 139cbacab26SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 140cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 141cbacab26SFlorian Hahn; CHECK: loop.next: 142*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 143cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 144cbacab26SFlorian Hahn; CHECK: loop.latch: 145cbacab26SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 146cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1 147cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 148cbacab26SFlorian Hahn; CHECK: exit: 149cbacab26SFlorian Hahn; CHECK-NEXT: ret void 150cbacab26SFlorian Hahn; 151cbacab26SFlorian Hahnentry: 152cbacab26SFlorian Hahn %start.ult.end = icmp uge ptr %start, %end 153cbacab26SFlorian Hahn br i1 %start.ult.end, label %exit, label %loop.ph 154cbacab26SFlorian Hahn 155cbacab26SFlorian Hahnloop.ph: 156cbacab26SFlorian Hahn br label %loop.header 157cbacab26SFlorian Hahn 158cbacab26SFlorian Hahnloop.header: 159cbacab26SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 160cbacab26SFlorian Hahn %c = icmp eq ptr %ptr.iv, %end 161cbacab26SFlorian Hahn br i1 %c, label %exit, label %for.body 162cbacab26SFlorian Hahn 163cbacab26SFlorian Hahnfor.body: 164cbacab26SFlorian Hahn %c.1 = call i1 @cond() 165cbacab26SFlorian Hahn br i1 %c.1, label %loop.next, label %exit 166cbacab26SFlorian Hahn 167cbacab26SFlorian Hahnloop.next: 168cbacab26SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 169cbacab26SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %end 170cbacab26SFlorian Hahn %and = and i1 %t.1, %t.2 171cbacab26SFlorian Hahn br i1 %and, label %loop.latch, label %exit 172cbacab26SFlorian Hahn 173cbacab26SFlorian Hahnloop.latch: 174cbacab26SFlorian Hahn call void @use(ptr %ptr.iv) 175cbacab26SFlorian Hahn %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1 176cbacab26SFlorian Hahn br label %loop.header 177cbacab26SFlorian Hahn 178cbacab26SFlorian Hahnexit: 179cbacab26SFlorian Hahn ret void 180cbacab26SFlorian Hahn} 181cbacab26SFlorian Hahn 182cbacab26SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_gep_step_size_i32_unknown_end_ptr_with_early_exit(ptr %start, ptr %end) { 183cbacab26SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_gep_step_size_i32_unknown_end_ptr_with_early_exit( 184cbacab26SFlorian Hahn; CHECK-NEXT: entry: 185cbacab26SFlorian Hahn; CHECK-NEXT: [[START_ULT_END:%.*]] = icmp uge ptr [[START:%.*]], [[END:%.*]] 186cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[START_ULT_END]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 187cbacab26SFlorian Hahn; CHECK: loop.ph: 188cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 189cbacab26SFlorian Hahn; CHECK: loop.header: 190cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 191cbacab26SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[END]] 192cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 193cbacab26SFlorian Hahn; CHECK: for.body: 194cbacab26SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 195cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 196cbacab26SFlorian Hahn; CHECK: loop.next: 197cbacab26SFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[END]] 198*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 199cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 200cbacab26SFlorian Hahn; CHECK: loop.latch: 201cbacab26SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 202cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 203cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 204cbacab26SFlorian Hahn; CHECK: exit: 205cbacab26SFlorian Hahn; CHECK-NEXT: ret void 206cbacab26SFlorian Hahn; 207cbacab26SFlorian Hahnentry: 208cbacab26SFlorian Hahn %start.ult.end = icmp uge ptr %start, %end 209cbacab26SFlorian Hahn br i1 %start.ult.end, label %exit, label %loop.ph 210cbacab26SFlorian Hahn 211cbacab26SFlorian Hahnloop.ph: 212cbacab26SFlorian Hahn br label %loop.header 213cbacab26SFlorian Hahn 214cbacab26SFlorian Hahnloop.header: 215cbacab26SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 216cbacab26SFlorian Hahn %c = icmp eq ptr %ptr.iv, %end 217cbacab26SFlorian Hahn br i1 %c, label %exit, label %for.body 218cbacab26SFlorian Hahn 219cbacab26SFlorian Hahnfor.body: 220cbacab26SFlorian Hahn %c.1 = call i1 @cond() 221cbacab26SFlorian Hahn br i1 %c.1, label %loop.next, label %exit 222cbacab26SFlorian Hahn 223cbacab26SFlorian Hahnloop.next: 224cbacab26SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 225cbacab26SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %end 226cbacab26SFlorian Hahn %and = and i1 %t.1, %t.2 227cbacab26SFlorian Hahn br i1 %and, label %loop.latch, label %exit 228cbacab26SFlorian Hahn 229cbacab26SFlorian Hahnloop.latch: 230cbacab26SFlorian Hahn call void @use(ptr %ptr.iv) 231cbacab26SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 232cbacab26SFlorian Hahn br label %loop.header 233cbacab26SFlorian Hahn 234cbacab26SFlorian Hahnexit: 235cbacab26SFlorian Hahn ret void 236cbacab26SFlorian Hahn} 237cbacab26SFlorian Hahn 238cbacab26SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_different_element_types_1_with_early_exit_and_different_upper(ptr %start, ptr %end, i16 %len) { 239cbacab26SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types_1_with_early_exit_and_different_upper( 240cbacab26SFlorian Hahn; CHECK-NEXT: entry: 241cbacab26SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[END:%.*]], i16 [[LEN:%.*]] 242cbacab26SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 243cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 244cbacab26SFlorian Hahn; CHECK: loop.ph: 245cbacab26SFlorian Hahn; CHECK-NEXT: [[START_ULT_END:%.*]] = icmp ult ptr [[START:%.*]], [[UPPER]] 246cbacab26SFlorian Hahn; CHECK-NEXT: call void @llvm.assume(i1 [[START_ULT_END]]) 247cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 248cbacab26SFlorian Hahn; CHECK: loop.header: 249cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 250cbacab26SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 251cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 252cbacab26SFlorian Hahn; CHECK: for.body: 253cbacab26SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 254cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 255cbacab26SFlorian Hahn; CHECK: loop.next: 256cbacab26SFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 257*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 258cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 259cbacab26SFlorian Hahn; CHECK: loop.latch: 260cbacab26SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 261cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 262cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 263cbacab26SFlorian Hahn; CHECK: exit: 264cbacab26SFlorian Hahn; CHECK-NEXT: ret void 265cbacab26SFlorian Hahn; 266cbacab26SFlorian Hahnentry: 267cbacab26SFlorian Hahn %upper = getelementptr inbounds i32, ptr %end, i16 %len 268cbacab26SFlorian Hahn %len.neg = icmp slt i16 %len, 0 269cbacab26SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 270cbacab26SFlorian Hahn 271cbacab26SFlorian Hahnloop.ph: 272cbacab26SFlorian Hahn %start.ult.end = icmp ult ptr %start, %upper 273cbacab26SFlorian Hahn call void @llvm.assume(i1 %start.ult.end) 274cbacab26SFlorian Hahn br label %loop.header 275cbacab26SFlorian Hahn 276cbacab26SFlorian Hahnloop.header: 277cbacab26SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 278cbacab26SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 279cbacab26SFlorian Hahn br i1 %c, label %exit, label %for.body 280cbacab26SFlorian Hahn 281cbacab26SFlorian Hahnfor.body: 282cbacab26SFlorian Hahn %c.1 = call i1 @cond() 283cbacab26SFlorian Hahn br i1 %c.1, label %loop.next, label %exit 284cbacab26SFlorian Hahn 285cbacab26SFlorian Hahnloop.next: 286cbacab26SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 287cbacab26SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 288cbacab26SFlorian Hahn %and = and i1 %t.1, %t.2 289cbacab26SFlorian Hahn br i1 %and, label %loop.latch, label %exit 290cbacab26SFlorian Hahn 291cbacab26SFlorian Hahnloop.latch: 292cbacab26SFlorian Hahn call void @use(ptr %ptr.iv) 293cbacab26SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 294cbacab26SFlorian Hahn br label %loop.header 295cbacab26SFlorian Hahn 296cbacab26SFlorian Hahnexit: 297cbacab26SFlorian Hahn ret void 298cbacab26SFlorian Hahn} 299cbacab26SFlorian Hahn 300cbacab26SFlorian Hahndefine void @test_monotonic_ptr_iv_step_sign_positive_through_assume_multi_exit(ptr %start, i16 %len, i16 %step) { 301cbacab26SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_step_sign_positive_through_assume_multi_exit( 302cbacab26SFlorian Hahn; CHECK-NEXT: entry: 303cbacab26SFlorian Hahn; CHECK-NEXT: [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0 304cbacab26SFlorian Hahn; CHECK-NEXT: call void @llvm.assume(i1 [[STEP_POS]]) 305cbacab26SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 306cbacab26SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 307cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 308cbacab26SFlorian Hahn; CHECK: loop.ph: 309cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 310cbacab26SFlorian Hahn; CHECK: loop.header: 311cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 312cbacab26SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 313cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 314cbacab26SFlorian Hahn; CHECK: for.body: 315cbacab26SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 316cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[EXIT]] 317cbacab26SFlorian Hahn; CHECK: then: 318cbacab26SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 319cbacab26SFlorian Hahn; CHECK-NEXT: [[C_3:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 320cbacab26SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_3]] 321cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 322cbacab26SFlorian Hahn; CHECK: loop.latch: 323cbacab26SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 324cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 [[STEP]] 325cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 326cbacab26SFlorian Hahn; CHECK: exit: 327cbacab26SFlorian Hahn; CHECK-NEXT: ret void 328cbacab26SFlorian Hahn; 329cbacab26SFlorian Hahnentry: 330cbacab26SFlorian Hahn %step.pos = icmp sge i16 %step, 0 331cbacab26SFlorian Hahn call void @llvm.assume(i1 %step.pos) 332cbacab26SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 333cbacab26SFlorian Hahn %len.neg = icmp slt i16 %len, 0 334cbacab26SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 335cbacab26SFlorian Hahn 336cbacab26SFlorian Hahnloop.ph: 337cbacab26SFlorian Hahn br label %loop.header 338cbacab26SFlorian Hahn 339cbacab26SFlorian Hahnloop.header: 340cbacab26SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 341cbacab26SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 342cbacab26SFlorian Hahn br i1 %c, label %exit, label %for.body 343cbacab26SFlorian Hahn 344cbacab26SFlorian Hahnfor.body: 345cbacab26SFlorian Hahn %c.1 = call i1 @cond() 346cbacab26SFlorian Hahn br i1 %c.1, label %then, label %exit 347cbacab26SFlorian Hahn 348cbacab26SFlorian Hahnthen: 349cbacab26SFlorian Hahn %c.2 = icmp uge ptr %ptr.iv, %start 350cbacab26SFlorian Hahn %c.3 = icmp ult ptr %ptr.iv, %upper 351cbacab26SFlorian Hahn %and = and i1 %c.2, %c.3 352cbacab26SFlorian Hahn br i1 %and, label %loop.latch, label %exit 353cbacab26SFlorian Hahn 354cbacab26SFlorian Hahnloop.latch: 355cbacab26SFlorian Hahn call void @use(ptr %ptr.iv) 356cbacab26SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 %step 357cbacab26SFlorian Hahn br label %loop.header 358cbacab26SFlorian Hahn 359cbacab26SFlorian Hahnexit: 360cbacab26SFlorian Hahn ret void 361cbacab26SFlorian Hahn} 362cbacab26SFlorian Hahn 363cbacab26SFlorian Hahndefine void @test_monotonic_ptr_iv_cond_doesnt_control_exit(ptr %start, i16 %len) { 364cbacab26SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_cond_doesnt_control_exit( 365cbacab26SFlorian Hahn; CHECK-NEXT: entry: 366cbacab26SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 367cbacab26SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 368cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 369cbacab26SFlorian Hahn; CHECK: loop.ph: 370cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 371cbacab26SFlorian Hahn; CHECK: loop.header: 372cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 373cbacab26SFlorian Hahn; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond() 374cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_0]], label [[EXIT]], label [[FOR_BODY:%.*]] 375cbacab26SFlorian Hahn; CHECK: for.body: 376cbacab26SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]] 377cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[LOOP_LATCH]] 378cbacab26SFlorian Hahn; CHECK: then: 379cbacab26SFlorian Hahn; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 380cbacab26SFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 381cbacab26SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]] 382cbacab26SFlorian Hahn; CHECK-NEXT: call void @use.i1(i1 [[AND]]) 383cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_LATCH]] 384cbacab26SFlorian Hahn; CHECK: loop.latch: 385cbacab26SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 386cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 387cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 388cbacab26SFlorian Hahn; CHECK: exit: 389cbacab26SFlorian Hahn; CHECK-NEXT: ret void 390cbacab26SFlorian Hahn; 391cbacab26SFlorian Hahnentry: 392cbacab26SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 393cbacab26SFlorian Hahn %len.neg = icmp slt i16 %len, 0 394cbacab26SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 395cbacab26SFlorian Hahn 396cbacab26SFlorian Hahnloop.ph: 397cbacab26SFlorian Hahn br label %loop.header 398cbacab26SFlorian Hahn 399cbacab26SFlorian Hahnloop.header: 400cbacab26SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 401cbacab26SFlorian Hahn %c.0 = call i1 @cond() 402cbacab26SFlorian Hahn br i1 %c.0, label %exit, label %for.body 403cbacab26SFlorian Hahn 404cbacab26SFlorian Hahnfor.body: 405cbacab26SFlorian Hahn %c.1 = icmp ne ptr %ptr.iv, %upper 406cbacab26SFlorian Hahn br i1 %c.1, label %then, label %loop.latch 407cbacab26SFlorian Hahn 408cbacab26SFlorian Hahnthen: 409cbacab26SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 410cbacab26SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 411cbacab26SFlorian Hahn %and = and i1 %t.1, %t.2 412cbacab26SFlorian Hahn call void @use.i1(i1 %and) 413cbacab26SFlorian Hahn br label %loop.latch 414cbacab26SFlorian Hahn 415cbacab26SFlorian Hahnloop.latch: 416cbacab26SFlorian Hahn call void @use(ptr %ptr.iv) 417cbacab26SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 418cbacab26SFlorian Hahn br label %loop.header 419cbacab26SFlorian Hahn 420cbacab26SFlorian Hahnexit: 421cbacab26SFlorian Hahn ret void 422cbacab26SFlorian Hahn} 423cbacab26SFlorian Hahn 424cbacab26SFlorian Hahndefine void @test_monotonic_ptr_iv_cond_doesnt_control_exit2(ptr %start, i16 %len) { 425cbacab26SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_cond_doesnt_control_exit2( 426cbacab26SFlorian Hahn; CHECK-NEXT: entry: 427cbacab26SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 428cbacab26SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 429cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 430cbacab26SFlorian Hahn; CHECK: loop.ph: 431cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 432cbacab26SFlorian Hahn; CHECK: loop.header: 433cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 434cbacab26SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]] 435cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[FOR_BODY:%.*]] 436cbacab26SFlorian Hahn; CHECK: for.body: 437cbacab26SFlorian Hahn; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond() 438cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_0]], label [[EXIT]], label [[LOOP_LATCH]] 439cbacab26SFlorian Hahn; CHECK: then: 440cbacab26SFlorian Hahn; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 441cbacab26SFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 442cbacab26SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]] 443cbacab26SFlorian Hahn; CHECK-NEXT: call void @use.i1(i1 [[AND]]) 444cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_LATCH]] 445cbacab26SFlorian Hahn; CHECK: loop.latch: 446cbacab26SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 447cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 448cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 449cbacab26SFlorian Hahn; CHECK: exit: 450cbacab26SFlorian Hahn; CHECK-NEXT: ret void 451cbacab26SFlorian Hahn; 452cbacab26SFlorian Hahnentry: 453cbacab26SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 454cbacab26SFlorian Hahn %len.neg = icmp slt i16 %len, 0 455cbacab26SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 456cbacab26SFlorian Hahn 457cbacab26SFlorian Hahnloop.ph: 458cbacab26SFlorian Hahn br label %loop.header 459cbacab26SFlorian Hahn 460cbacab26SFlorian Hahnloop.header: 461cbacab26SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 462cbacab26SFlorian Hahn %c.1 = icmp ne ptr %ptr.iv, %upper 463cbacab26SFlorian Hahn br i1 %c.1, label %then, label %for.body 464cbacab26SFlorian Hahn 465cbacab26SFlorian Hahnfor.body: 466cbacab26SFlorian Hahn %c.0 = call i1 @cond() 467cbacab26SFlorian Hahn br i1 %c.0, label %exit, label %loop.latch 468cbacab26SFlorian Hahn 469cbacab26SFlorian Hahnthen: 470cbacab26SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 471cbacab26SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 472cbacab26SFlorian Hahn %and = and i1 %t.1, %t.2 473cbacab26SFlorian Hahn call void @use.i1(i1 %and) 474cbacab26SFlorian Hahn br label %loop.latch 475cbacab26SFlorian Hahn 476cbacab26SFlorian Hahnloop.latch: 477cbacab26SFlorian Hahn call void @use(ptr %ptr.iv) 478cbacab26SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 479cbacab26SFlorian Hahn br label %loop.header 480cbacab26SFlorian Hahn 481cbacab26SFlorian Hahnexit: 482cbacab26SFlorian Hahn ret void 483cbacab26SFlorian Hahn} 484cbacab26SFlorian Hahn 485cbacab26SFlorian Hahndefine void @test_monotonic_ptr_iv_cond_doesnt_dominate_checks(ptr %start, i16 %len) { 486cbacab26SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_cond_doesnt_dominate_checks( 487cbacab26SFlorian Hahn; CHECK-NEXT: entry: 488cbacab26SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 489cbacab26SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 490cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 491cbacab26SFlorian Hahn; CHECK: loop.ph: 492cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 493cbacab26SFlorian Hahn; CHECK: loop.header: 494cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 495cbacab26SFlorian Hahn; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond() 496cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_0]], label [[EXIT]], label [[FOR_BODY:%.*]] 497cbacab26SFlorian Hahn; CHECK: for.body: 498cbacab26SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]] 499cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[LOOP_LATCH]] 500cbacab26SFlorian Hahn; CHECK: then: 501cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_LATCH]] 502cbacab26SFlorian Hahn; CHECK: loop.latch: 503cbacab26SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 504cbacab26SFlorian Hahn; CHECK-NEXT: [[C_3:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 505cbacab26SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_3]] 506cbacab26SFlorian Hahn; CHECK-NEXT: call void @use.i1(i1 [[AND]]) 507cbacab26SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 508cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 509cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 510cbacab26SFlorian Hahn; CHECK: exit: 511cbacab26SFlorian Hahn; CHECK-NEXT: ret void 512cbacab26SFlorian Hahn; 513cbacab26SFlorian Hahnentry: 514cbacab26SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 515cbacab26SFlorian Hahn %len.neg = icmp slt i16 %len, 0 516cbacab26SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 517cbacab26SFlorian Hahn 518cbacab26SFlorian Hahnloop.ph: 519cbacab26SFlorian Hahn br label %loop.header 520cbacab26SFlorian Hahn 521cbacab26SFlorian Hahnloop.header: 522cbacab26SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 523cbacab26SFlorian Hahn %c.0 = call i1 @cond() 524cbacab26SFlorian Hahn br i1 %c.0, label %exit, label %for.body 525cbacab26SFlorian Hahn 526cbacab26SFlorian Hahnfor.body: 527cbacab26SFlorian Hahn %c.1 = icmp ne ptr %ptr.iv, %upper 528cbacab26SFlorian Hahn br i1 %c.1, label %then, label %loop.latch 529cbacab26SFlorian Hahn 530cbacab26SFlorian Hahnthen: 531cbacab26SFlorian Hahn br label %loop.latch 532cbacab26SFlorian Hahn 533cbacab26SFlorian Hahnloop.latch: 534cbacab26SFlorian Hahn %c.2 = icmp uge ptr %ptr.iv, %start 535cbacab26SFlorian Hahn %c.3 = icmp ult ptr %ptr.iv, %upper 536cbacab26SFlorian Hahn %and = and i1 %c.2, %c.3 537cbacab26SFlorian Hahn call void @use.i1(i1 %and) 538cbacab26SFlorian Hahn call void @use(ptr %ptr.iv) 539cbacab26SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 540cbacab26SFlorian Hahn br label %loop.header 541cbacab26SFlorian Hahn 542cbacab26SFlorian Hahnexit: 543cbacab26SFlorian Hahn ret void 544cbacab26SFlorian Hahn} 545cbacab26SFlorian Hahn 546cbacab26SFlorian Hahndefine void @test_monotonic_ptr_iv_step_2_multi_exit(ptr %start, i16 %len) { 547cbacab26SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_step_2_multi_exit( 548cbacab26SFlorian Hahn; CHECK-NEXT: entry: 549cbacab26SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 550cbacab26SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 551cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 552cbacab26SFlorian Hahn; CHECK: loop.ph: 553cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 554cbacab26SFlorian Hahn; CHECK: loop.header: 555cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 556cbacab26SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 557cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[EXIT]], label [[FOR_BODY:%.*]] 558cbacab26SFlorian Hahn; CHECK: for.body: 559cbacab26SFlorian Hahn; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond() 560cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_0]], label [[EXIT]], label [[THEN:%.*]] 561cbacab26SFlorian Hahn; CHECK: then: 562cbacab26SFlorian Hahn; CHECK-NEXT: [[C_3:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 563*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[C_3]] 564cbacab26SFlorian Hahn; CHECK-NEXT: call void @use.i1(i1 [[AND]]) 565cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_LATCH]] 566cbacab26SFlorian Hahn; CHECK: loop.latch: 567cbacab26SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 568cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 2 569cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 570cbacab26SFlorian Hahn; CHECK: exit: 571cbacab26SFlorian Hahn; CHECK-NEXT: ret void 572cbacab26SFlorian Hahn; 573cbacab26SFlorian Hahnentry: 574cbacab26SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 575cbacab26SFlorian Hahn %len.neg = icmp slt i16 %len, 0 576cbacab26SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 577cbacab26SFlorian Hahn 578cbacab26SFlorian Hahnloop.ph: 579cbacab26SFlorian Hahn br label %loop.header 580cbacab26SFlorian Hahn 581cbacab26SFlorian Hahnloop.header: 582cbacab26SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 583cbacab26SFlorian Hahn %c.1 = icmp eq ptr %ptr.iv, %upper 584cbacab26SFlorian Hahn br i1 %c.1, label %exit, label %for.body 585cbacab26SFlorian Hahn 586cbacab26SFlorian Hahnfor.body: 587cbacab26SFlorian Hahn %c.0 = call i1 @cond() 588cbacab26SFlorian Hahn br i1 %c.0, label %exit, label %then 589cbacab26SFlorian Hahn 590cbacab26SFlorian Hahnthen: 591cbacab26SFlorian Hahn %c.2 = icmp uge ptr %ptr.iv, %start 592cbacab26SFlorian Hahn %c.3 = icmp ult ptr %ptr.iv, %upper 593cbacab26SFlorian Hahn %and = and i1 %c.2, %c.3 594cbacab26SFlorian Hahn call void @use.i1(i1 %and) 595cbacab26SFlorian Hahn br label %loop.latch 596cbacab26SFlorian Hahn 597cbacab26SFlorian Hahnloop.latch: 598cbacab26SFlorian Hahn call void @use(ptr %ptr.iv) 599cbacab26SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 2 600cbacab26SFlorian Hahn br label %loop.header 601cbacab26SFlorian Hahn 602cbacab26SFlorian Hahnexit: 603cbacab26SFlorian Hahn ret void 604cbacab26SFlorian Hahn} 605cbacab26SFlorian Hahn 606cbacab26SFlorian Hahndefine void @test_monotonic_ptr_iv_step_2_cond_doesnt_control_exit(ptr %start, i16 %len) { 607cbacab26SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_step_2_cond_doesnt_control_exit( 608cbacab26SFlorian Hahn; CHECK-NEXT: entry: 609cbacab26SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 610cbacab26SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 611cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 612cbacab26SFlorian Hahn; CHECK: loop.ph: 613cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 614cbacab26SFlorian Hahn; CHECK: loop.header: 615cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 616cbacab26SFlorian Hahn; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond() 617cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_0]], label [[EXIT]], label [[FOR_BODY:%.*]] 618cbacab26SFlorian Hahn; CHECK: for.body: 619cbacab26SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]] 620cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[LOOP_LATCH]] 621cbacab26SFlorian Hahn; CHECK: then: 622cbacab26SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 623cbacab26SFlorian Hahn; CHECK-NEXT: [[C_3:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 624cbacab26SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_3]] 625cbacab26SFlorian Hahn; CHECK-NEXT: call void @use.i1(i1 [[AND]]) 626cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_LATCH]] 627cbacab26SFlorian Hahn; CHECK: loop.latch: 628cbacab26SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 629cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 2 630cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 631cbacab26SFlorian Hahn; CHECK: exit: 632cbacab26SFlorian Hahn; CHECK-NEXT: ret void 633cbacab26SFlorian Hahn; 634cbacab26SFlorian Hahnentry: 635cbacab26SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 636cbacab26SFlorian Hahn %len.neg = icmp slt i16 %len, 0 637cbacab26SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 638cbacab26SFlorian Hahn 639cbacab26SFlorian Hahnloop.ph: 640cbacab26SFlorian Hahn br label %loop.header 641cbacab26SFlorian Hahn 642cbacab26SFlorian Hahnloop.header: 643cbacab26SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 644cbacab26SFlorian Hahn %c.0 = call i1 @cond() 645cbacab26SFlorian Hahn br i1 %c.0, label %exit, label %for.body 646cbacab26SFlorian Hahn 647cbacab26SFlorian Hahnfor.body: 648cbacab26SFlorian Hahn %c.1 = icmp ne ptr %ptr.iv, %upper 649cbacab26SFlorian Hahn br i1 %c.1, label %then, label %loop.latch 650cbacab26SFlorian Hahn 651cbacab26SFlorian Hahnthen: 652cbacab26SFlorian Hahn %c.2 = icmp uge ptr %ptr.iv, %start 653cbacab26SFlorian Hahn %c.3 = icmp ult ptr %ptr.iv, %upper 654cbacab26SFlorian Hahn %and = and i1 %c.2, %c.3 655cbacab26SFlorian Hahn call void @use.i1(i1 %and) 656cbacab26SFlorian Hahn br label %loop.latch 657cbacab26SFlorian Hahn 658cbacab26SFlorian Hahnloop.latch: 659cbacab26SFlorian Hahn call void @use(ptr %ptr.iv) 660cbacab26SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 2 661cbacab26SFlorian Hahn br label %loop.header 662cbacab26SFlorian Hahn 663cbacab26SFlorian Hahnexit: 664cbacab26SFlorian Hahn ret void 665cbacab26SFlorian Hahn} 666cbacab26SFlorian Hahn 667e1e7b019SFlorian Hahndefine void @test_monotonic_ptr_iv_step_64_cond_doesnt_control_exit(ptr %start, i16 %len) { 668e1e7b019SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_step_64_cond_doesnt_control_exit( 669e1e7b019SFlorian Hahn; CHECK-NEXT: entry: 670e1e7b019SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i64, ptr [[START:%.*]], i16 [[LEN:%.*]] 671e1e7b019SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 672e1e7b019SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 673e1e7b019SFlorian Hahn; CHECK: loop.ph: 674e1e7b019SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 675e1e7b019SFlorian Hahn; CHECK: loop.header: 676e1e7b019SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 677e1e7b019SFlorian Hahn; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond() 678e1e7b019SFlorian Hahn; CHECK-NEXT: br i1 [[C_0]], label [[EXIT]], label [[FOR_BODY:%.*]] 679e1e7b019SFlorian Hahn; CHECK: for.body: 680e1e7b019SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]] 681e1e7b019SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[LOOP_LATCH]] 682e1e7b019SFlorian Hahn; CHECK: then: 683e1e7b019SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 684e1e7b019SFlorian Hahn; CHECK-NEXT: [[C_3:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 685e1e7b019SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_3]] 686e1e7b019SFlorian Hahn; CHECK-NEXT: call void @use.i1(i1 [[AND]]) 687e1e7b019SFlorian Hahn; CHECK-NEXT: br label [[LOOP_LATCH]] 688e1e7b019SFlorian Hahn; CHECK: loop.latch: 689e1e7b019SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 690e1e7b019SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i16 4 691e1e7b019SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 692e1e7b019SFlorian Hahn; CHECK: exit: 693e1e7b019SFlorian Hahn; CHECK-NEXT: ret void 694e1e7b019SFlorian Hahn; 695e1e7b019SFlorian Hahnentry: 696e1e7b019SFlorian Hahn %upper = getelementptr inbounds i64, ptr %start, i16 %len 697e1e7b019SFlorian Hahn %len.neg = icmp slt i16 %len, 0 698e1e7b019SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 699e1e7b019SFlorian Hahn 700e1e7b019SFlorian Hahnloop.ph: 701e1e7b019SFlorian Hahn br label %loop.header 702e1e7b019SFlorian Hahn 703e1e7b019SFlorian Hahnloop.header: 704e1e7b019SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 705e1e7b019SFlorian Hahn %c.0 = call i1 @cond() 706e1e7b019SFlorian Hahn br i1 %c.0, label %exit, label %for.body 707e1e7b019SFlorian Hahn 708e1e7b019SFlorian Hahnfor.body: 709e1e7b019SFlorian Hahn %c.1 = icmp ne ptr %ptr.iv, %upper 710e1e7b019SFlorian Hahn br i1 %c.1, label %then, label %loop.latch 711e1e7b019SFlorian Hahn 712e1e7b019SFlorian Hahnthen: 713e1e7b019SFlorian Hahn %c.2 = icmp uge ptr %ptr.iv, %start 714e1e7b019SFlorian Hahn %c.3 = icmp ult ptr %ptr.iv, %upper 715e1e7b019SFlorian Hahn %and = and i1 %c.2, %c.3 716e1e7b019SFlorian Hahn call void @use.i1(i1 %and) 717e1e7b019SFlorian Hahn br label %loop.latch 718e1e7b019SFlorian Hahn 719e1e7b019SFlorian Hahnloop.latch: 720e1e7b019SFlorian Hahn call void @use(ptr %ptr.iv) 721e1e7b019SFlorian Hahn %ptr.iv.next = getelementptr inbounds i16, ptr %ptr.iv, i16 4 722e1e7b019SFlorian Hahn br label %loop.header 723e1e7b019SFlorian Hahn 724e1e7b019SFlorian Hahnexit: 725e1e7b019SFlorian Hahn ret void 726e1e7b019SFlorian Hahn} 727e1e7b019SFlorian Hahn 728e1e7b019SFlorian Hahndefine void @test_monotonic_ptr_iv_step_80_cond_doesnt_control_exit(ptr %start, i16 %len) { 729e1e7b019SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_step_80_cond_doesnt_control_exit( 730e1e7b019SFlorian Hahn; CHECK-NEXT: entry: 731e1e7b019SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i64, ptr [[START:%.*]], i16 [[LEN:%.*]] 732e1e7b019SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 733e1e7b019SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 734e1e7b019SFlorian Hahn; CHECK: loop.ph: 735e1e7b019SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 736e1e7b019SFlorian Hahn; CHECK: loop.header: 737e1e7b019SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 738e1e7b019SFlorian Hahn; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond() 739e1e7b019SFlorian Hahn; CHECK-NEXT: br i1 [[C_0]], label [[EXIT]], label [[FOR_BODY:%.*]] 740e1e7b019SFlorian Hahn; CHECK: for.body: 741e1e7b019SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]] 742e1e7b019SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[LOOP_LATCH]] 743e1e7b019SFlorian Hahn; CHECK: then: 744e1e7b019SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 745e1e7b019SFlorian Hahn; CHECK-NEXT: [[C_3:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 746e1e7b019SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_3]] 747e1e7b019SFlorian Hahn; CHECK-NEXT: call void @use.i1(i1 [[AND]]) 748e1e7b019SFlorian Hahn; CHECK-NEXT: br label [[LOOP_LATCH]] 749e1e7b019SFlorian Hahn; CHECK: loop.latch: 750e1e7b019SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 751e1e7b019SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i16, ptr [[PTR_IV]], i16 5 752e1e7b019SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 753e1e7b019SFlorian Hahn; CHECK: exit: 754e1e7b019SFlorian Hahn; CHECK-NEXT: ret void 755e1e7b019SFlorian Hahn; 756e1e7b019SFlorian Hahnentry: 757e1e7b019SFlorian Hahn %upper = getelementptr inbounds i64, ptr %start, i16 %len 758e1e7b019SFlorian Hahn %len.neg = icmp slt i16 %len, 0 759e1e7b019SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 760e1e7b019SFlorian Hahn 761e1e7b019SFlorian Hahnloop.ph: 762e1e7b019SFlorian Hahn br label %loop.header 763e1e7b019SFlorian Hahn 764e1e7b019SFlorian Hahnloop.header: 765e1e7b019SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 766e1e7b019SFlorian Hahn %c.0 = call i1 @cond() 767e1e7b019SFlorian Hahn br i1 %c.0, label %exit, label %for.body 768e1e7b019SFlorian Hahn 769e1e7b019SFlorian Hahnfor.body: 770e1e7b019SFlorian Hahn %c.1 = icmp ne ptr %ptr.iv, %upper 771e1e7b019SFlorian Hahn br i1 %c.1, label %then, label %loop.latch 772e1e7b019SFlorian Hahn 773e1e7b019SFlorian Hahnthen: 774e1e7b019SFlorian Hahn %c.2 = icmp uge ptr %ptr.iv, %start 775e1e7b019SFlorian Hahn %c.3 = icmp ult ptr %ptr.iv, %upper 776e1e7b019SFlorian Hahn %and = and i1 %c.2, %c.3 777e1e7b019SFlorian Hahn call void @use.i1(i1 %and) 778e1e7b019SFlorian Hahn br label %loop.latch 779e1e7b019SFlorian Hahn 780e1e7b019SFlorian Hahnloop.latch: 781e1e7b019SFlorian Hahn call void @use(ptr %ptr.iv) 782e1e7b019SFlorian Hahn %ptr.iv.next = getelementptr inbounds i16, ptr %ptr.iv, i16 5 783e1e7b019SFlorian Hahn br label %loop.header 784e1e7b019SFlorian Hahn 785e1e7b019SFlorian Hahnexit: 786e1e7b019SFlorian Hahn ret void 787e1e7b019SFlorian Hahn} 788cbacab26SFlorian Hahn 789cbacab26SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_check_outside_loop(ptr %start, i16 %len) { 790cbacab26SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_check_outside_loop( 791cbacab26SFlorian Hahn; CHECK-NEXT: entry: 792cbacab26SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 793cbacab26SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp sge i16 [[LEN]], 0 794cbacab26SFlorian Hahn; CHECK-NEXT: call void @llvm.assume(i1 [[LEN_NEG]]) 795cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_PH:%.*]] 796cbacab26SFlorian Hahn; CHECK: loop.ph: 797cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 798cbacab26SFlorian Hahn; CHECK: loop.header: 799cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 800cbacab26SFlorian Hahn; CHECK-NEXT: [[C_0:%.*]] = call i1 @cond() 801cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_0]], label [[EXIT:%.*]], label [[LOOP_LATCH]] 802cbacab26SFlorian Hahn; CHECK: loop.latch: 803cbacab26SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 804cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1 805cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 806cbacab26SFlorian Hahn; CHECK: exit: 807cbacab26SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp ne ptr [[PTR_IV]], [[UPPER]] 808cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[THEN:%.*]], label [[EXIT_2:%.*]] 809cbacab26SFlorian Hahn; CHECK: then: 810cbacab26SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 811cbacab26SFlorian Hahn; CHECK-NEXT: [[C_3:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 812cbacab26SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_3]] 813cbacab26SFlorian Hahn; CHECK-NEXT: call void @use.i1(i1 [[AND]]) 814cbacab26SFlorian Hahn; CHECK-NEXT: br label [[EXIT_2]] 815cbacab26SFlorian Hahn; CHECK: exit.2: 816cbacab26SFlorian Hahn; CHECK-NEXT: ret void 817cbacab26SFlorian Hahn; 818cbacab26SFlorian Hahnentry: 819cbacab26SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 820cbacab26SFlorian Hahn %len.neg = icmp sge i16 %len, 0 821cbacab26SFlorian Hahn call void @llvm.assume(i1 %len.neg) 822cbacab26SFlorian Hahn br label %loop.ph 823cbacab26SFlorian Hahn 824cbacab26SFlorian Hahnloop.ph: 825cbacab26SFlorian Hahn br label %loop.header 826cbacab26SFlorian Hahn 827cbacab26SFlorian Hahnloop.header: 828cbacab26SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 829cbacab26SFlorian Hahn %c.0 = call i1 @cond() 830cbacab26SFlorian Hahn br i1 %c.0, label %exit, label %loop.latch 831cbacab26SFlorian Hahn 832cbacab26SFlorian Hahnloop.latch: 833cbacab26SFlorian Hahn call void @use(ptr %ptr.iv) 834cbacab26SFlorian Hahn %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1 835cbacab26SFlorian Hahn br label %loop.header 836cbacab26SFlorian Hahn 837cbacab26SFlorian Hahnexit: 838cbacab26SFlorian Hahn %c.1 = icmp ne ptr %ptr.iv, %upper 839cbacab26SFlorian Hahn br i1 %c.1, label %then, label %exit.2 840cbacab26SFlorian Hahn 841cbacab26SFlorian Hahnthen: 842cbacab26SFlorian Hahn %c.2 = icmp uge ptr %ptr.iv, %start 843cbacab26SFlorian Hahn %c.3 = icmp ult ptr %ptr.iv, %upper 844cbacab26SFlorian Hahn %and = and i1 %c.2, %c.3 845cbacab26SFlorian Hahn call void @use.i1(i1 %and) 846cbacab26SFlorian Hahn br label %exit.2 847cbacab26SFlorian Hahn 848cbacab26SFlorian Hahnexit.2: 849cbacab26SFlorian Hahn ret void 850cbacab26SFlorian Hahn} 851cbacab26SFlorian Hahn 852cbacab26SFlorian Hahndefine void @test_step_gep_doesnt_use_ptr_iv_phi(ptr %start, ptr %other, i16 %len) { 853cbacab26SFlorian Hahn; CHECK-LABEL: @test_step_gep_doesnt_use_ptr_iv_phi( 854cbacab26SFlorian Hahn; CHECK-NEXT: entry: 855cbacab26SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds float, ptr [[START:%.*]], i16 [[LEN:%.*]] 856cbacab26SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 857cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 858cbacab26SFlorian Hahn; CHECK: loop.ph: 859cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 860cbacab26SFlorian Hahn; CHECK: loop.header: 861cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 862cbacab26SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 863cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 864cbacab26SFlorian Hahn; CHECK: for.body: 865cbacab26SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 866cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 867cbacab26SFlorian Hahn; CHECK: loop.next: 868cbacab26SFlorian Hahn; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 869cbacab26SFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 870cbacab26SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]] 871cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 872cbacab26SFlorian Hahn; CHECK: loop.latch: 873cbacab26SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 874cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds float, ptr [[OTHER:%.*]], i16 1 875cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 876cbacab26SFlorian Hahn; CHECK: exit: 877cbacab26SFlorian Hahn; CHECK-NEXT: ret void 878cbacab26SFlorian Hahn; 879cbacab26SFlorian Hahnentry: 880cbacab26SFlorian Hahn %upper = getelementptr inbounds float, ptr %start, i16 %len 881cbacab26SFlorian Hahn %len.neg = icmp slt i16 %len, 0 882cbacab26SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 883cbacab26SFlorian Hahn 884cbacab26SFlorian Hahnloop.ph: 885cbacab26SFlorian Hahn br label %loop.header 886cbacab26SFlorian Hahn 887cbacab26SFlorian Hahnloop.header: 888cbacab26SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 889cbacab26SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 890cbacab26SFlorian Hahn br i1 %c, label %exit, label %for.body 891cbacab26SFlorian Hahn 892cbacab26SFlorian Hahnfor.body: 893cbacab26SFlorian Hahn %c.1 = call i1 @cond() 894cbacab26SFlorian Hahn br i1 %c.1, label %loop.next, label %exit 895cbacab26SFlorian Hahn 896cbacab26SFlorian Hahnloop.next: 897cbacab26SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 898cbacab26SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 899cbacab26SFlorian Hahn %and = and i1 %t.1, %t.2 900cbacab26SFlorian Hahn br i1 %and, label %loop.latch, label %exit 901cbacab26SFlorian Hahn 902cbacab26SFlorian Hahnloop.latch: 903cbacab26SFlorian Hahn call void @use(ptr %ptr.iv) 904cbacab26SFlorian Hahn %ptr.iv.next = getelementptr inbounds float, ptr %other, i16 1 905cbacab26SFlorian Hahn br label %loop.header 906cbacab26SFlorian Hahn 907cbacab26SFlorian Hahnexit: 908cbacab26SFlorian Hahn ret void 909cbacab26SFlorian Hahn} 910cbacab26SFlorian Hahn 911cbacab26SFlorian Hahndefine void @test_step_gep_not_inbounds(ptr %start, ptr %end, i16 %len) { 912cbacab26SFlorian Hahn; CHECK-LABEL: @test_step_gep_not_inbounds( 913cbacab26SFlorian Hahn; CHECK-NEXT: entry: 914cbacab26SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds float, ptr [[START:%.*]], i16 [[LEN:%.*]] 915cbacab26SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 916cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 917cbacab26SFlorian Hahn; CHECK: loop.ph: 918cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 919cbacab26SFlorian Hahn; CHECK: loop.header: 920cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 921cbacab26SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 922cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 923cbacab26SFlorian Hahn; CHECK: for.body: 924cbacab26SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 925cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 926cbacab26SFlorian Hahn; CHECK: loop.next: 927*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, true 928cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 929cbacab26SFlorian Hahn; CHECK: loop.latch: 930cbacab26SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 931cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr float, ptr [[PTR_IV]], i16 1 932cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 933cbacab26SFlorian Hahn; CHECK: exit: 934cbacab26SFlorian Hahn; CHECK-NEXT: ret void 935cbacab26SFlorian Hahn; 936cbacab26SFlorian Hahnentry: 937cbacab26SFlorian Hahn %upper = getelementptr inbounds float, ptr %start, i16 %len 938cbacab26SFlorian Hahn %len.neg = icmp slt i16 %len, 0 939cbacab26SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 940cbacab26SFlorian Hahn 941cbacab26SFlorian Hahnloop.ph: 942cbacab26SFlorian Hahn br label %loop.header 943cbacab26SFlorian Hahn 944cbacab26SFlorian Hahnloop.header: 945cbacab26SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 946cbacab26SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 947cbacab26SFlorian Hahn br i1 %c, label %exit, label %for.body 948cbacab26SFlorian Hahn 949cbacab26SFlorian Hahnfor.body: 950cbacab26SFlorian Hahn %c.1 = call i1 @cond() 951cbacab26SFlorian Hahn br i1 %c.1, label %loop.next, label %exit 952cbacab26SFlorian Hahn 953cbacab26SFlorian Hahnloop.next: 954cbacab26SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 955cbacab26SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 956cbacab26SFlorian Hahn %and = and i1 %t.1, %t.2 957cbacab26SFlorian Hahn br i1 %and, label %loop.latch, label %exit 958cbacab26SFlorian Hahn 959cbacab26SFlorian Hahnloop.latch: 960cbacab26SFlorian Hahn call void @use(ptr %ptr.iv) 961cbacab26SFlorian Hahn %ptr.iv.next = getelementptr float, ptr %ptr.iv, i16 1 962cbacab26SFlorian Hahn br label %loop.header 963cbacab26SFlorian Hahn 964cbacab26SFlorian Hahnexit: 965cbacab26SFlorian Hahn ret void 966cbacab26SFlorian Hahn} 967cbacab26SFlorian Hahn 968cbacab26SFlorian Hahndefine void @test_upper_gep_not_inbounds(ptr %start, ptr %end, i16 %len) { 969cbacab26SFlorian Hahn; CHECK-LABEL: @test_upper_gep_not_inbounds( 970cbacab26SFlorian Hahn; CHECK-NEXT: entry: 971cbacab26SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr float, ptr [[START:%.*]], i16 [[LEN:%.*]] 972cbacab26SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 973cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 974cbacab26SFlorian Hahn; CHECK: loop.ph: 975cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 976cbacab26SFlorian Hahn; CHECK: loop.header: 977cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 978cbacab26SFlorian Hahn; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 979cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]] 980cbacab26SFlorian Hahn; CHECK: for.body: 981cbacab26SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = call i1 @cond() 982cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 983cbacab26SFlorian Hahn; CHECK: loop.next: 984cbacab26SFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 985*e6a1657fSFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[T_2]] 986cbacab26SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 987cbacab26SFlorian Hahn; CHECK: loop.latch: 988cbacab26SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 989cbacab26SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds float, ptr [[PTR_IV]], i16 1 990cbacab26SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 991cbacab26SFlorian Hahn; CHECK: exit: 992cbacab26SFlorian Hahn; CHECK-NEXT: ret void 993cbacab26SFlorian Hahn; 994cbacab26SFlorian Hahnentry: 995cbacab26SFlorian Hahn %upper = getelementptr float, ptr %start, i16 %len 996cbacab26SFlorian Hahn %len.neg = icmp slt i16 %len, 0 997cbacab26SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 998cbacab26SFlorian Hahn 999cbacab26SFlorian Hahnloop.ph: 1000cbacab26SFlorian Hahn br label %loop.header 1001cbacab26SFlorian Hahn 1002cbacab26SFlorian Hahnloop.header: 1003cbacab26SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 1004cbacab26SFlorian Hahn %c = icmp eq ptr %ptr.iv, %upper 1005cbacab26SFlorian Hahn br i1 %c, label %exit, label %for.body 1006cbacab26SFlorian Hahn 1007cbacab26SFlorian Hahnfor.body: 1008cbacab26SFlorian Hahn %c.1 = call i1 @cond() 1009cbacab26SFlorian Hahn br i1 %c.1, label %loop.next, label %exit 1010cbacab26SFlorian Hahn 1011cbacab26SFlorian Hahnloop.next: 1012cbacab26SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 1013cbacab26SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 1014cbacab26SFlorian Hahn %and = and i1 %t.1, %t.2 1015cbacab26SFlorian Hahn br i1 %and, label %loop.latch, label %exit 1016cbacab26SFlorian Hahn 1017cbacab26SFlorian Hahnloop.latch: 1018cbacab26SFlorian Hahn call void @use(ptr %ptr.iv) 1019cbacab26SFlorian Hahn %ptr.iv.next = getelementptr inbounds float, ptr %ptr.iv, i16 1 1020cbacab26SFlorian Hahn br label %loop.header 1021cbacab26SFlorian Hahn 1022cbacab26SFlorian Hahnexit: 1023cbacab26SFlorian Hahn ret void 1024cbacab26SFlorian Hahn} 1025