1e25eb143SFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2e25eb143SFlorian Hahn; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 3e25eb143SFlorian Hahn 4e25eb143SFlorian Hahntarget datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 5e25eb143SFlorian Hahn 6e25eb143SFlorian Hahndeclare void @use(ptr) 7e25eb143SFlorian Hahndeclare i1 @cond() 8e25eb143SFlorian Hahn 9e25eb143SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_different_element_types_1_chain_of_2_exit_condition_unrelated_condition_in_header(ptr %start, i16 %len, i16 %x) { 10e25eb143SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types_1_chain_of_2_exit_condition_unrelated_condition_in_header( 11e25eb143SFlorian Hahn; CHECK-NEXT: entry: 12e25eb143SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 13e25eb143SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 14e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 15e25eb143SFlorian Hahn; CHECK: loop.ph: 16e25eb143SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 17e25eb143SFlorian Hahn; CHECK: loop.header: 18e25eb143SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 19e25eb143SFlorian Hahn; CHECK-NEXT: [[C_0:%.*]] = icmp eq i16 [[X:%.*]], 1 20e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[C_0]], label [[EXIT]], label [[THEN:%.*]] 21e25eb143SFlorian Hahn; CHECK: then: 22e25eb143SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 23e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[EXIT]], label [[FOR_BODY:%.*]] 24e25eb143SFlorian Hahn; CHECK: for.body: 25e25eb143SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond() 26e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 27e25eb143SFlorian Hahn; CHECK: loop.next: 28e25eb143SFlorian Hahn; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 29e25eb143SFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 30e25eb143SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]] 31e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 32e25eb143SFlorian Hahn; CHECK: loop.latch: 33e25eb143SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 34e25eb143SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1 35e25eb143SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 36e25eb143SFlorian Hahn; CHECK: exit: 37e25eb143SFlorian Hahn; CHECK-NEXT: ret void 38e25eb143SFlorian Hahn; 39e25eb143SFlorian Hahnentry: 40e25eb143SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 41e25eb143SFlorian Hahn %len.neg = icmp slt i16 %len, 0 42e25eb143SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 43e25eb143SFlorian Hahn 44e25eb143SFlorian Hahnloop.ph: 45e25eb143SFlorian Hahn br label %loop.header 46e25eb143SFlorian Hahn 47e25eb143SFlorian Hahnloop.header: 48e25eb143SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 49e25eb143SFlorian Hahn %c.0 = icmp eq i16 %x, 1 50e25eb143SFlorian Hahn br i1 %c.0, label %exit, label %then 51e25eb143SFlorian Hahn 52e25eb143SFlorian Hahnthen: 53e25eb143SFlorian Hahn %c.1 = icmp eq ptr %ptr.iv, %upper 54e25eb143SFlorian Hahn br i1 %c.1, label %exit, label %for.body 55e25eb143SFlorian Hahn 56e25eb143SFlorian Hahnfor.body: 57e25eb143SFlorian Hahn %c.2 = call i1 @cond() 58e25eb143SFlorian Hahn br i1 %c.2, label %loop.next, label %exit 59e25eb143SFlorian Hahn 60e25eb143SFlorian Hahnloop.next: 61e25eb143SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 62e25eb143SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 63e25eb143SFlorian Hahn %and = and i1 %t.1, %t.2 64e25eb143SFlorian Hahn br i1 %and, label %loop.latch, label %exit 65e25eb143SFlorian Hahn 66e25eb143SFlorian Hahnloop.latch: 67e25eb143SFlorian Hahn call void @use(ptr %ptr.iv) 68e25eb143SFlorian Hahn %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1 69e25eb143SFlorian Hahn br label %loop.header 70e25eb143SFlorian Hahn 71e25eb143SFlorian Hahnexit: 72e25eb143SFlorian Hahn ret void 73e25eb143SFlorian Hahn} 74e25eb143SFlorian Hahn 75e25eb143SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_different_element_types_1_chain_of_3_exit_condition_unrelated_condition_in_header(ptr %start, i16 %len, i16 %x) { 76e25eb143SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types_1_chain_of_3_exit_condition_unrelated_condition_in_header( 77e25eb143SFlorian Hahn; CHECK-NEXT: entry: 78e25eb143SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 79e25eb143SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 80e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]] 81e25eb143SFlorian Hahn; CHECK: loop.ph: 82e25eb143SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 83e25eb143SFlorian Hahn; CHECK: loop.header: 84e25eb143SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 85e25eb143SFlorian Hahn; CHECK-NEXT: [[C_0:%.*]] = icmp eq i16 [[X:%.*]], 1 86e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[C_0]], label [[EXIT]], label [[THEN_1:%.*]] 87e25eb143SFlorian Hahn; CHECK: then.1: 88e25eb143SFlorian Hahn; CHECK-NEXT: [[C_00:%.*]] = icmp ult i16 [[X]], 100 89e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[C_0]], label [[EXIT]], label [[THEN_2:%.*]] 90e25eb143SFlorian Hahn; CHECK: then.2: 91e25eb143SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 92e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[EXIT]], label [[FOR_BODY:%.*]] 93e25eb143SFlorian Hahn; CHECK: for.body: 94e25eb143SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond() 95e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 96e25eb143SFlorian Hahn; CHECK: loop.next: 97e25eb143SFlorian Hahn; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 98e25eb143SFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 99e25eb143SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]] 100e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 101e25eb143SFlorian Hahn; CHECK: loop.latch: 102e25eb143SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 103e25eb143SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1 104e25eb143SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 105e25eb143SFlorian Hahn; CHECK: exit: 106e25eb143SFlorian Hahn; CHECK-NEXT: ret void 107e25eb143SFlorian Hahn; 108e25eb143SFlorian Hahnentry: 109e25eb143SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 110e25eb143SFlorian Hahn %len.neg = icmp slt i16 %len, 0 111e25eb143SFlorian Hahn br i1 %len.neg, label %exit, label %loop.ph 112e25eb143SFlorian Hahn 113e25eb143SFlorian Hahnloop.ph: 114e25eb143SFlorian Hahn br label %loop.header 115e25eb143SFlorian Hahn 116e25eb143SFlorian Hahnloop.header: 117e25eb143SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 118e25eb143SFlorian Hahn %c.0 = icmp eq i16 %x, 1 119e25eb143SFlorian Hahn br i1 %c.0, label %exit, label %then.1 120e25eb143SFlorian Hahn 121e25eb143SFlorian Hahnthen.1: 122e25eb143SFlorian Hahn %c.00 = icmp ult i16 %x, 100 123e25eb143SFlorian Hahn br i1 %c.0, label %exit, label %then.2 124e25eb143SFlorian Hahn 125e25eb143SFlorian Hahnthen.2: 126e25eb143SFlorian Hahn %c.1 = icmp eq ptr %ptr.iv, %upper 127e25eb143SFlorian Hahn br i1 %c.1, label %exit, label %for.body 128e25eb143SFlorian Hahn 129e25eb143SFlorian Hahnfor.body: 130e25eb143SFlorian Hahn %c.2 = call i1 @cond() 131e25eb143SFlorian Hahn br i1 %c.2, label %loop.next, label %exit 132e25eb143SFlorian Hahn 133e25eb143SFlorian Hahnloop.next: 134e25eb143SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 135e25eb143SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 136e25eb143SFlorian Hahn %and = and i1 %t.1, %t.2 137e25eb143SFlorian Hahn br i1 %and, label %loop.latch, label %exit 138e25eb143SFlorian Hahn 139e25eb143SFlorian Hahnloop.latch: 140e25eb143SFlorian Hahn call void @use(ptr %ptr.iv) 141e25eb143SFlorian Hahn %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1 142e25eb143SFlorian Hahn br label %loop.header 143e25eb143SFlorian Hahn 144e25eb143SFlorian Hahnexit: 145e25eb143SFlorian Hahn ret void 146e25eb143SFlorian Hahn} 147e25eb143SFlorian Hahn 148e25eb143SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_different_element_types_1_chain_of_2_exit_conditions_with_slt_in_header(ptr %start, i16 %len, i16 %x) { 149e25eb143SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types_1_chain_of_2_exit_conditions_with_slt_in_header( 150e25eb143SFlorian Hahn; CHECK-NEXT: entry: 151e25eb143SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 152e25eb143SFlorian Hahn; CHECK-NEXT: br label [[LOOP_PH:%.*]] 153e25eb143SFlorian Hahn; CHECK: loop.ph: 154e25eb143SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 155e25eb143SFlorian Hahn; CHECK: loop.header: 156e25eb143SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 157e25eb143SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 158e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[THEN:%.*]] 159e25eb143SFlorian Hahn; CHECK: then: 160e25eb143SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 161e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[EXIT]], label [[FOR_BODY:%.*]] 162e25eb143SFlorian Hahn; CHECK: for.body: 163e25eb143SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond() 164e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 165e25eb143SFlorian Hahn; CHECK: loop.next: 166e25eb143SFlorian Hahn; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 167e25eb143SFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 168e25eb143SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]] 169e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 170e25eb143SFlorian Hahn; CHECK: loop.latch: 171e25eb143SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 172e25eb143SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1 173e25eb143SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 174e25eb143SFlorian Hahn; CHECK: exit: 175e25eb143SFlorian Hahn; CHECK-NEXT: ret void 176e25eb143SFlorian Hahn; 177e25eb143SFlorian Hahnentry: 178e25eb143SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 179e25eb143SFlorian Hahn br label %loop.ph 180e25eb143SFlorian Hahn 181e25eb143SFlorian Hahnloop.ph: 182e25eb143SFlorian Hahn br label %loop.header 183e25eb143SFlorian Hahn 184e25eb143SFlorian Hahnloop.header: 185e25eb143SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 186e25eb143SFlorian Hahn %len.neg = icmp slt i16 %len, 0 187e25eb143SFlorian Hahn br i1 %len.neg, label %exit, label %then 188e25eb143SFlorian Hahn 189e25eb143SFlorian Hahnthen: 190e25eb143SFlorian Hahn %c.1 = icmp eq ptr %ptr.iv, %upper 191e25eb143SFlorian Hahn br i1 %c.1, label %exit, label %for.body 192e25eb143SFlorian Hahn 193e25eb143SFlorian Hahnfor.body: 194e25eb143SFlorian Hahn %c.2 = call i1 @cond() 195e25eb143SFlorian Hahn br i1 %c.2, label %loop.next, label %exit 196e25eb143SFlorian Hahn 197e25eb143SFlorian Hahnloop.next: 198e25eb143SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 199e25eb143SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 200e25eb143SFlorian Hahn %and = and i1 %t.1, %t.2 201e25eb143SFlorian Hahn br i1 %and, label %loop.latch, label %exit 202e25eb143SFlorian Hahn 203e25eb143SFlorian Hahnloop.latch: 204e25eb143SFlorian Hahn call void @use(ptr %ptr.iv) 205e25eb143SFlorian Hahn %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1 206e25eb143SFlorian Hahn br label %loop.header 207e25eb143SFlorian Hahn 208e25eb143SFlorian Hahnexit: 209e25eb143SFlorian Hahn ret void 210e25eb143SFlorian Hahn} 211e25eb143SFlorian Hahn 212e25eb143SFlorian Hahndefine void @test_header_not_exiting(ptr %start, i16 %len, i16 %x) { 213e25eb143SFlorian Hahn; CHECK-LABEL: @test_header_not_exiting( 214e25eb143SFlorian Hahn; CHECK-NEXT: entry: 215e25eb143SFlorian Hahn; CHECK-NEXT: [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]] 216e25eb143SFlorian Hahn; CHECK-NEXT: br label [[LOOP_PH:%.*]] 217e25eb143SFlorian Hahn; CHECK: loop.ph: 218e25eb143SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 219e25eb143SFlorian Hahn; CHECK: loop.header: 220e25eb143SFlorian Hahn; CHECK-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 221e25eb143SFlorian Hahn; CHECK-NEXT: [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0 222e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[LEN_NEG]], label [[THEN:%.*]], label [[FOR_BODY:%.*]] 223e25eb143SFlorian Hahn; CHECK: then: 224e25eb143SFlorian Hahn; CHECK-NEXT: [[C_1:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]] 225e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[C_1]], label [[EXIT:%.*]], label [[FOR_BODY]] 226e25eb143SFlorian Hahn; CHECK: for.body: 227e25eb143SFlorian Hahn; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond() 228e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[C_2]], label [[LOOP_NEXT:%.*]], label [[EXIT]] 229e25eb143SFlorian Hahn; CHECK: loop.next: 230e25eb143SFlorian Hahn; CHECK-NEXT: [[T_1:%.*]] = icmp uge ptr [[PTR_IV]], [[START]] 231e25eb143SFlorian Hahn; CHECK-NEXT: [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]] 232e25eb143SFlorian Hahn; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[T_2]] 233e25eb143SFlorian Hahn; CHECK-NEXT: br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]] 234e25eb143SFlorian Hahn; CHECK: loop.latch: 235e25eb143SFlorian Hahn; CHECK-NEXT: call void @use(ptr [[PTR_IV]]) 236e25eb143SFlorian Hahn; CHECK-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i16 1 237e25eb143SFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER]] 238e25eb143SFlorian Hahn; CHECK: exit: 239e25eb143SFlorian Hahn; CHECK-NEXT: ret void 240e25eb143SFlorian Hahn; 241e25eb143SFlorian Hahnentry: 242e25eb143SFlorian Hahn %upper = getelementptr inbounds i32, ptr %start, i16 %len 243e25eb143SFlorian Hahn br label %loop.ph 244e25eb143SFlorian Hahn 245e25eb143SFlorian Hahnloop.ph: 246e25eb143SFlorian Hahn br label %loop.header 247e25eb143SFlorian Hahn 248e25eb143SFlorian Hahnloop.header: 249e25eb143SFlorian Hahn %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ] 250e25eb143SFlorian Hahn %len.neg = icmp slt i16 %len, 0 251e25eb143SFlorian Hahn br i1 %len.neg, label %then, label %for.body 252e25eb143SFlorian Hahn 253e25eb143SFlorian Hahnthen: 254e25eb143SFlorian Hahn %c.1 = icmp eq ptr %ptr.iv, %upper 255e25eb143SFlorian Hahn br i1 %c.1, label %exit, label %for.body 256e25eb143SFlorian Hahn 257e25eb143SFlorian Hahnfor.body: 258e25eb143SFlorian Hahn %c.2 = call i1 @cond() 259e25eb143SFlorian Hahn br i1 %c.2, label %loop.next, label %exit 260e25eb143SFlorian Hahn 261e25eb143SFlorian Hahnloop.next: 262e25eb143SFlorian Hahn %t.1 = icmp uge ptr %ptr.iv, %start 263e25eb143SFlorian Hahn %t.2 = icmp ult ptr %ptr.iv, %upper 264e25eb143SFlorian Hahn %and = and i1 %t.1, %t.2 265e25eb143SFlorian Hahn br i1 %and, label %loop.latch, label %exit 266e25eb143SFlorian Hahn 267e25eb143SFlorian Hahnloop.latch: 268e25eb143SFlorian Hahn call void @use(ptr %ptr.iv) 269e25eb143SFlorian Hahn %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i16 1 270e25eb143SFlorian Hahn br label %loop.header 271e25eb143SFlorian Hahn 272e25eb143SFlorian Hahnexit: 273e25eb143SFlorian Hahn ret void 274e25eb143SFlorian Hahn} 275*f58312efSFlorian Hahn 276*f58312efSFlorian Hahndeclare void @foo() 277*f58312efSFlorian Hahn 278*f58312efSFlorian Hahndefine i32 @test_latch_exiting1(i32 %N) { 279*f58312efSFlorian Hahn; CHECK-LABEL: @test_latch_exiting1( 280*f58312efSFlorian Hahn; CHECK-NEXT: entry: 281*f58312efSFlorian Hahn; CHECK-NEXT: br label [[LOOP:%.*]] 282*f58312efSFlorian Hahn; CHECK: loop: 283*f58312efSFlorian Hahn; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 284*f58312efSFlorian Hahn; CHECK-NEXT: call void @foo() 285*f58312efSFlorian Hahn; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 286*f58312efSFlorian Hahn; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV]], [[N:%.*]] 287*f58312efSFlorian Hahn; CHECK-NEXT: br i1 [[EC]], label [[EXIT_1:%.*]], label [[LOOP]] 288*f58312efSFlorian Hahn; CHECK: exit.1: 289*f58312efSFlorian Hahn; CHECK-NEXT: ret i32 10 290*f58312efSFlorian Hahn; 291*f58312efSFlorian Hahnentry: 292*f58312efSFlorian Hahn br label %loop 293*f58312efSFlorian Hahn 294*f58312efSFlorian Hahnloop: 295*f58312efSFlorian Hahn %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] 296*f58312efSFlorian Hahn call void @foo() 297*f58312efSFlorian Hahn %iv.next = add i32 %iv, 1 298*f58312efSFlorian Hahn %ec = icmp eq i32 %iv, %N 299*f58312efSFlorian Hahn br i1 %ec, label %exit.1, label %loop 300*f58312efSFlorian Hahn 301*f58312efSFlorian Hahnexit.1: 302*f58312efSFlorian Hahn ret i32 10 303*f58312efSFlorian Hahn} 304*f58312efSFlorian Hahn 305*f58312efSFlorian Hahndefine i32 @test_latch_exiting2(i1 %c, i32 %N) { 306*f58312efSFlorian Hahn; CHECK-LABEL: @test_latch_exiting2( 307*f58312efSFlorian Hahn; CHECK-NEXT: entry: 308*f58312efSFlorian Hahn; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] 309*f58312efSFlorian Hahn; CHECK: loop.header: 310*f58312efSFlorian Hahn; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 311*f58312efSFlorian Hahn; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP_LATCH]], label [[EXIT_1:%.*]] 312*f58312efSFlorian Hahn; CHECK: loop.latch: 313*f58312efSFlorian Hahn; CHECK-NEXT: call void @foo() 314*f58312efSFlorian Hahn; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 315*f58312efSFlorian Hahn; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV]], [[N:%.*]] 316*f58312efSFlorian Hahn; CHECK-NEXT: br i1 [[EC]], label [[EXIT_2:%.*]], label [[LOOP_HEADER]] 317*f58312efSFlorian Hahn; CHECK: exit.1: 318*f58312efSFlorian Hahn; CHECK-NEXT: ret i32 10 319*f58312efSFlorian Hahn; CHECK: exit.2: 320*f58312efSFlorian Hahn; CHECK-NEXT: ret i32 0 321*f58312efSFlorian Hahn; 322*f58312efSFlorian Hahnentry: 323*f58312efSFlorian Hahn br label %loop.header 324*f58312efSFlorian Hahn 325*f58312efSFlorian Hahnloop.header: 326*f58312efSFlorian Hahn %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 327*f58312efSFlorian Hahn br i1 %c, label %loop.latch, label %exit.1 328*f58312efSFlorian Hahn 329*f58312efSFlorian Hahnloop.latch: 330*f58312efSFlorian Hahn call void @foo() 331*f58312efSFlorian Hahn %iv.next = add i32 %iv, 1 332*f58312efSFlorian Hahn %ec = icmp eq i32 %iv, %N 333*f58312efSFlorian Hahn br i1 %ec, label %exit.2, label %loop.header 334*f58312efSFlorian Hahn 335*f58312efSFlorian Hahnexit.1: 336*f58312efSFlorian Hahn ret i32 10 337*f58312efSFlorian Hahn 338*f58312efSFlorian Hahnexit.2: 339*f58312efSFlorian Hahn ret i32 0 340*f58312efSFlorian Hahn} 341