136999318SFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
236999318SFlorian Hahn; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
336999318SFlorian Hahn
436999318SFlorian Hahn; NOTE: The custom datalayout defines i32 to be 64 bit aligned.
536999318SFlorian Hahn
636999318SFlorian Hahntarget datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i32:64:64-f80:128-n8:16:32:64-S128"
736999318SFlorian Hahn
836999318SFlorian Hahndeclare void @use(ptr)
936999318SFlorian Hahndeclare i1 @cond()
1036999318SFlorian Hahn
1136999318SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_element_types_with_different_alloc_type_sizes(ptr %start, i16 %len) {
1236999318SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_element_types_with_different_alloc_type_sizes(
1336999318SFlorian Hahn; CHECK-NEXT:  entry:
1436999318SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds float, ptr [[START:%.*]], i16 [[LEN:%.*]]
1536999318SFlorian Hahn; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
1636999318SFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
1736999318SFlorian Hahn; CHECK:       loop.ph:
1836999318SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
1936999318SFlorian Hahn; CHECK:       loop.header:
2036999318SFlorian Hahn; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
2136999318SFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
2236999318SFlorian Hahn; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
2336999318SFlorian Hahn; CHECK:       for.body:
2436999318SFlorian Hahn; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
25*e6a1657fSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[T_2]]
2636999318SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
2736999318SFlorian Hahn; CHECK:       loop.latch:
2836999318SFlorian Hahn; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
2936999318SFlorian Hahn; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1
3036999318SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER]]
3136999318SFlorian Hahn; CHECK:       exit:
3236999318SFlorian Hahn; CHECK-NEXT:    ret void
3336999318SFlorian Hahn;
3436999318SFlorian Hahnentry:
3536999318SFlorian Hahn  %upper = getelementptr inbounds float, ptr %start, i16 %len
3636999318SFlorian Hahn  %len.neg = icmp slt i16 %len, 0
3736999318SFlorian Hahn  br i1 %len.neg, label %exit, label %loop.ph
3836999318SFlorian Hahn
3936999318SFlorian Hahnloop.ph:
4036999318SFlorian Hahn  br label %loop.header
4136999318SFlorian Hahn
4236999318SFlorian Hahnloop.header:
4336999318SFlorian Hahn  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
4436999318SFlorian Hahn  %c = icmp eq ptr %ptr.iv, %upper
4536999318SFlorian Hahn  br i1 %c, label %exit, label %for.body
4636999318SFlorian Hahn
4736999318SFlorian Hahnfor.body:
4836999318SFlorian Hahn  %t.1 = icmp uge ptr %ptr.iv, %start
4936999318SFlorian Hahn  %t.2 = icmp ult ptr %ptr.iv, %upper
5036999318SFlorian Hahn  %and = and i1 %t.1, %t.2
5136999318SFlorian Hahn  br i1 %and, label %loop.latch, label %exit
5236999318SFlorian Hahn
5336999318SFlorian Hahnloop.latch:
5436999318SFlorian Hahn  call void @use(ptr %ptr.iv)
5536999318SFlorian Hahn  %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
5636999318SFlorian Hahn  br label %loop.header
5736999318SFlorian Hahn
5836999318SFlorian Hahnexit:
5936999318SFlorian Hahn  ret void
6036999318SFlorian Hahn}
6136999318SFlorian Hahn
6236999318SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_2_element_types_with_different_alloc_type_sizes(ptr %start, i16 %len) {
6336999318SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_2_element_types_with_different_alloc_type_sizes(
6436999318SFlorian Hahn; CHECK-NEXT:  entry:
6536999318SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]
6636999318SFlorian Hahn; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
6736999318SFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
6836999318SFlorian Hahn; CHECK:       loop.ph:
6936999318SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
7036999318SFlorian Hahn; CHECK:       loop.header:
7136999318SFlorian Hahn; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
7236999318SFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
7336999318SFlorian Hahn; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
7436999318SFlorian Hahn; CHECK:       for.body:
75*e6a1657fSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
7636999318SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
7736999318SFlorian Hahn; CHECK:       loop.latch:
7836999318SFlorian Hahn; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
7936999318SFlorian Hahn; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds float, ptr [[PTR_IV]], i16 1
8036999318SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER]]
8136999318SFlorian Hahn; CHECK:       exit:
8236999318SFlorian Hahn; CHECK-NEXT:    ret void
8336999318SFlorian Hahn;
8436999318SFlorian Hahnentry:
8536999318SFlorian Hahn  %upper = getelementptr inbounds i32, ptr %start, i16 %len
8636999318SFlorian Hahn  %len.neg = icmp slt i16 %len, 0
8736999318SFlorian Hahn  br i1 %len.neg, label %exit, label %loop.ph
8836999318SFlorian Hahn
8936999318SFlorian Hahnloop.ph:
9036999318SFlorian Hahn  br label %loop.header
9136999318SFlorian Hahn
9236999318SFlorian Hahnloop.header:
9336999318SFlorian Hahn  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
9436999318SFlorian Hahn  %c = icmp eq ptr %ptr.iv, %upper
9536999318SFlorian Hahn  br i1 %c, label %exit, label %for.body
9636999318SFlorian Hahn
9736999318SFlorian Hahnfor.body:
9836999318SFlorian Hahn  %t.1 = icmp uge ptr %ptr.iv, %start
9936999318SFlorian Hahn  %t.2 = icmp ult ptr %ptr.iv, %upper
10036999318SFlorian Hahn  %and = and i1 %t.1, %t.2
10136999318SFlorian Hahn  br i1 %and, label %loop.latch, label %exit
10236999318SFlorian Hahn
10336999318SFlorian Hahnloop.latch:
10436999318SFlorian Hahn  call void @use(ptr %ptr.iv)
10536999318SFlorian Hahn  %ptr.iv.next = getelementptr inbounds float, ptr %ptr.iv, i16 1
10636999318SFlorian Hahn  br label %loop.header
10736999318SFlorian Hahn
10836999318SFlorian Hahnexit:
10936999318SFlorian Hahn  ret void
11036999318SFlorian Hahn}
11136999318SFlorian Hahn
11236999318SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_different_element_types_with_same_alloc_type_sizes(ptr %start, i16 %len) {
11336999318SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types_with_same_alloc_type_sizes(
11436999318SFlorian Hahn; CHECK-NEXT:  entry:
11536999318SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i5, ptr [[START:%.*]], i16 [[LEN:%.*]]
11636999318SFlorian Hahn; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
11736999318SFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
11836999318SFlorian Hahn; CHECK:       loop.ph:
11936999318SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
12036999318SFlorian Hahn; CHECK:       loop.header:
12136999318SFlorian Hahn; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
12236999318SFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
12336999318SFlorian Hahn; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
12436999318SFlorian Hahn; CHECK:       for.body:
125*e6a1657fSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
12636999318SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
12736999318SFlorian Hahn; CHECK:       loop.latch:
12836999318SFlorian Hahn; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
12936999318SFlorian Hahn; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i7, ptr [[PTR_IV]], i16 1
13036999318SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER]]
13136999318SFlorian Hahn; CHECK:       exit:
13236999318SFlorian Hahn; CHECK-NEXT:    ret void
13336999318SFlorian Hahn;
13436999318SFlorian Hahnentry:
13536999318SFlorian Hahn  %upper = getelementptr inbounds i5, ptr %start, i16 %len
13636999318SFlorian Hahn  %len.neg = icmp slt i16 %len, 0
13736999318SFlorian Hahn  br i1 %len.neg, label %exit, label %loop.ph
13836999318SFlorian Hahn
13936999318SFlorian Hahnloop.ph:
14036999318SFlorian Hahn  br label %loop.header
14136999318SFlorian Hahn
14236999318SFlorian Hahnloop.header:
14336999318SFlorian Hahn  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
14436999318SFlorian Hahn  %c = icmp eq ptr %ptr.iv, %upper
14536999318SFlorian Hahn  br i1 %c, label %exit, label %for.body
14636999318SFlorian Hahn
14736999318SFlorian Hahnfor.body:
14836999318SFlorian Hahn  %t.1 = icmp uge ptr %ptr.iv, %start
14936999318SFlorian Hahn  %t.2 = icmp ult ptr %ptr.iv, %upper
15036999318SFlorian Hahn  %and = and i1 %t.1, %t.2
15136999318SFlorian Hahn  br i1 %and, label %loop.latch, label %exit
15236999318SFlorian Hahn
15336999318SFlorian Hahnloop.latch:
15436999318SFlorian Hahn  call void @use(ptr %ptr.iv)
15536999318SFlorian Hahn  %ptr.iv.next = getelementptr inbounds i7, ptr %ptr.iv, i16 1
15636999318SFlorian Hahn  br label %loop.header
15736999318SFlorian Hahn
15836999318SFlorian Hahnexit:
15936999318SFlorian Hahn  ret void
16036999318SFlorian Hahn}
16136999318SFlorian Hahn
16236999318SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_2_different_element_types_with_same_alloc_type_sizes(ptr %start, i16 %len) {
16336999318SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_2_different_element_types_with_same_alloc_type_sizes(
16436999318SFlorian Hahn; CHECK-NEXT:  entry:
16536999318SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i31, ptr [[START:%.*]], i16 [[LEN:%.*]]
16636999318SFlorian Hahn; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
16736999318SFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
16836999318SFlorian Hahn; CHECK:       loop.ph:
16936999318SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
17036999318SFlorian Hahn; CHECK:       loop.header:
17136999318SFlorian Hahn; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
17236999318SFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
17336999318SFlorian Hahn; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
17436999318SFlorian Hahn; CHECK:       for.body:
175*e6a1657fSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
17636999318SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
17736999318SFlorian Hahn; CHECK:       loop.latch:
17836999318SFlorian Hahn; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
17936999318SFlorian Hahn; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i30, ptr [[PTR_IV]], i16 1
18036999318SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER]]
18136999318SFlorian Hahn; CHECK:       exit:
18236999318SFlorian Hahn; CHECK-NEXT:    ret void
18336999318SFlorian Hahn;
18436999318SFlorian Hahnentry:
18536999318SFlorian Hahn  %upper = getelementptr inbounds i31, ptr %start, i16 %len
18636999318SFlorian Hahn  %len.neg = icmp slt i16 %len, 0
18736999318SFlorian Hahn  br i1 %len.neg, label %exit, label %loop.ph
18836999318SFlorian Hahn
18936999318SFlorian Hahnloop.ph:
19036999318SFlorian Hahn  br label %loop.header
19136999318SFlorian Hahn
19236999318SFlorian Hahnloop.header:
19336999318SFlorian Hahn  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
19436999318SFlorian Hahn  %c = icmp eq ptr %ptr.iv, %upper
19536999318SFlorian Hahn  br i1 %c, label %exit, label %for.body
19636999318SFlorian Hahn
19736999318SFlorian Hahnfor.body:
19836999318SFlorian Hahn  %t.1 = icmp uge ptr %ptr.iv, %start
19936999318SFlorian Hahn  %t.2 = icmp ult ptr %ptr.iv, %upper
20036999318SFlorian Hahn  %and = and i1 %t.1, %t.2
20136999318SFlorian Hahn  br i1 %and, label %loop.latch, label %exit
20236999318SFlorian Hahn
20336999318SFlorian Hahnloop.latch:
20436999318SFlorian Hahn  call void @use(ptr %ptr.iv)
20536999318SFlorian Hahn  %ptr.iv.next = getelementptr inbounds i30, ptr %ptr.iv, i16 1
20636999318SFlorian Hahn  br label %loop.header
20736999318SFlorian Hahn
20836999318SFlorian Hahnexit:
20936999318SFlorian Hahn  ret void
21036999318SFlorian Hahn}
21136999318SFlorian Hahn
21236999318SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_element_types_with_different_alloc_type_sizes_with_early_exit(ptr %start, i16 %len) {
21336999318SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_element_types_with_different_alloc_type_sizes_with_early_exit(
21436999318SFlorian Hahn; CHECK-NEXT:  entry:
21536999318SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds float, ptr [[START:%.*]], i16 [[LEN:%.*]]
21636999318SFlorian Hahn; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
21736999318SFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
21836999318SFlorian Hahn; CHECK:       loop.ph:
21936999318SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
22036999318SFlorian Hahn; CHECK:       loop.header:
22136999318SFlorian Hahn; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
22236999318SFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
22336999318SFlorian Hahn; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
22436999318SFlorian Hahn; CHECK:       for.body:
22536999318SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
22636999318SFlorian Hahn; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
22736999318SFlorian Hahn; CHECK:       loop.next:
22836999318SFlorian Hahn; CHECK-NEXT:    [[T_2:%.*]] = icmp ult ptr [[PTR_IV]], [[UPPER]]
229*e6a1657fSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 true, [[T_2]]
23036999318SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
23136999318SFlorian Hahn; CHECK:       loop.latch:
23236999318SFlorian Hahn; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
23336999318SFlorian Hahn; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i32, ptr [[PTR_IV]], i16 1
23436999318SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER]]
23536999318SFlorian Hahn; CHECK:       exit:
23636999318SFlorian Hahn; CHECK-NEXT:    ret void
23736999318SFlorian Hahn;
23836999318SFlorian Hahnentry:
23936999318SFlorian Hahn  %upper = getelementptr inbounds float, ptr %start, i16 %len
24036999318SFlorian Hahn  %len.neg = icmp slt i16 %len, 0
24136999318SFlorian Hahn  br i1 %len.neg, label %exit, label %loop.ph
24236999318SFlorian Hahn
24336999318SFlorian Hahnloop.ph:
24436999318SFlorian Hahn  br label %loop.header
24536999318SFlorian Hahn
24636999318SFlorian Hahnloop.header:
24736999318SFlorian Hahn  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
24836999318SFlorian Hahn  %c = icmp eq ptr %ptr.iv, %upper
24936999318SFlorian Hahn  br i1 %c, label %exit, label %for.body
25036999318SFlorian Hahn
25136999318SFlorian Hahnfor.body:
25236999318SFlorian Hahn  %c.1 = call i1 @cond()
25336999318SFlorian Hahn  br i1 %c.1, label %loop.next, label %exit
25436999318SFlorian Hahn
25536999318SFlorian Hahnloop.next:
25636999318SFlorian Hahn  %t.1 = icmp uge ptr %ptr.iv, %start
25736999318SFlorian Hahn  %t.2 = icmp ult ptr %ptr.iv, %upper
25836999318SFlorian Hahn  %and = and i1 %t.1, %t.2
25936999318SFlorian Hahn  br i1 %and, label %loop.latch, label %exit
26036999318SFlorian Hahn
26136999318SFlorian Hahnloop.latch:
26236999318SFlorian Hahn  call void @use(ptr %ptr.iv)
26336999318SFlorian Hahn  %ptr.iv.next = getelementptr inbounds i32, ptr %ptr.iv, i16 1
26436999318SFlorian Hahn  br label %loop.header
26536999318SFlorian Hahn
26636999318SFlorian Hahnexit:
26736999318SFlorian Hahn  ret void
26836999318SFlorian Hahn}
26936999318SFlorian Hahn
27036999318SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_2_element_types_with_different_alloc_type_sizes_with_early_exit(ptr %start, i16 %len) {
27136999318SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_2_element_types_with_different_alloc_type_sizes_with_early_exit(
27236999318SFlorian Hahn; CHECK-NEXT:  entry:
27336999318SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[START:%.*]], i16 [[LEN:%.*]]
27436999318SFlorian Hahn; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
27536999318SFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
27636999318SFlorian Hahn; CHECK:       loop.ph:
27736999318SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
27836999318SFlorian Hahn; CHECK:       loop.header:
27936999318SFlorian Hahn; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
28036999318SFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
28136999318SFlorian Hahn; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
28236999318SFlorian Hahn; CHECK:       for.body:
28336999318SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
28436999318SFlorian Hahn; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
28536999318SFlorian Hahn; CHECK:       loop.next:
286*e6a1657fSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
28736999318SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
28836999318SFlorian Hahn; CHECK:       loop.latch:
28936999318SFlorian Hahn; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
29036999318SFlorian Hahn; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds float, ptr [[PTR_IV]], i16 1
29136999318SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER]]
29236999318SFlorian Hahn; CHECK:       exit:
29336999318SFlorian Hahn; CHECK-NEXT:    ret void
29436999318SFlorian Hahn;
29536999318SFlorian Hahnentry:
29636999318SFlorian Hahn  %upper = getelementptr inbounds i32, ptr %start, i16 %len
29736999318SFlorian Hahn  %len.neg = icmp slt i16 %len, 0
29836999318SFlorian Hahn  br i1 %len.neg, label %exit, label %loop.ph
29936999318SFlorian Hahn
30036999318SFlorian Hahnloop.ph:
30136999318SFlorian Hahn  br label %loop.header
30236999318SFlorian Hahn
30336999318SFlorian Hahnloop.header:
30436999318SFlorian Hahn  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
30536999318SFlorian Hahn  %c = icmp eq ptr %ptr.iv, %upper
30636999318SFlorian Hahn  br i1 %c, label %exit, label %for.body
30736999318SFlorian Hahn
30836999318SFlorian Hahnfor.body:
30936999318SFlorian Hahn  %c.1 = call i1 @cond()
31036999318SFlorian Hahn  br i1 %c.1, label %loop.next, label %exit
31136999318SFlorian Hahn
31236999318SFlorian Hahnloop.next:
31336999318SFlorian Hahn  %t.1 = icmp uge ptr %ptr.iv, %start
31436999318SFlorian Hahn  %t.2 = icmp ult ptr %ptr.iv, %upper
31536999318SFlorian Hahn  %and = and i1 %t.1, %t.2
31636999318SFlorian Hahn  br i1 %and, label %loop.latch, label %exit
31736999318SFlorian Hahn
31836999318SFlorian Hahnloop.latch:
31936999318SFlorian Hahn  call void @use(ptr %ptr.iv)
32036999318SFlorian Hahn  %ptr.iv.next = getelementptr inbounds float, ptr %ptr.iv, i16 1
32136999318SFlorian Hahn  br label %loop.header
32236999318SFlorian Hahn
32336999318SFlorian Hahnexit:
32436999318SFlorian Hahn  ret void
32536999318SFlorian Hahn}
32636999318SFlorian Hahn
32736999318SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_1_different_element_types_with_same_alloc_type_sizes_with_early_exit(ptr %start, i16 %len) {
32836999318SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_1_different_element_types_with_same_alloc_type_sizes_with_early_exit(
32936999318SFlorian Hahn; CHECK-NEXT:  entry:
33036999318SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i5, ptr [[START:%.*]], i16 [[LEN:%.*]]
33136999318SFlorian Hahn; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
33236999318SFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
33336999318SFlorian Hahn; CHECK:       loop.ph:
33436999318SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
33536999318SFlorian Hahn; CHECK:       loop.header:
33636999318SFlorian Hahn; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
33736999318SFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
33836999318SFlorian Hahn; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
33936999318SFlorian Hahn; CHECK:       for.body:
34036999318SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
34136999318SFlorian Hahn; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
34236999318SFlorian Hahn; CHECK:       loop.next:
343*e6a1657fSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
34436999318SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
34536999318SFlorian Hahn; CHECK:       loop.latch:
34636999318SFlorian Hahn; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
34736999318SFlorian Hahn; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i7, ptr [[PTR_IV]], i16 1
34836999318SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER]]
34936999318SFlorian Hahn; CHECK:       exit:
35036999318SFlorian Hahn; CHECK-NEXT:    ret void
35136999318SFlorian Hahn;
35236999318SFlorian Hahnentry:
35336999318SFlorian Hahn  %upper = getelementptr inbounds i5, ptr %start, i16 %len
35436999318SFlorian Hahn  %len.neg = icmp slt i16 %len, 0
35536999318SFlorian Hahn  br i1 %len.neg, label %exit, label %loop.ph
35636999318SFlorian Hahn
35736999318SFlorian Hahnloop.ph:
35836999318SFlorian Hahn  br label %loop.header
35936999318SFlorian Hahn
36036999318SFlorian Hahnloop.header:
36136999318SFlorian Hahn  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
36236999318SFlorian Hahn  %c = icmp eq ptr %ptr.iv, %upper
36336999318SFlorian Hahn  br i1 %c, label %exit, label %for.body
36436999318SFlorian Hahn
36536999318SFlorian Hahnfor.body:
36636999318SFlorian Hahn  %c.1 = call i1 @cond()
36736999318SFlorian Hahn  br i1 %c.1, label %loop.next, label %exit
36836999318SFlorian Hahn
36936999318SFlorian Hahnloop.next:
37036999318SFlorian Hahn  %t.1 = icmp uge ptr %ptr.iv, %start
37136999318SFlorian Hahn  %t.2 = icmp ult ptr %ptr.iv, %upper
37236999318SFlorian Hahn  %and = and i1 %t.1, %t.2
37336999318SFlorian Hahn  br i1 %and, label %loop.latch, label %exit
37436999318SFlorian Hahn
37536999318SFlorian Hahnloop.latch:
37636999318SFlorian Hahn  call void @use(ptr %ptr.iv)
37736999318SFlorian Hahn  %ptr.iv.next = getelementptr inbounds i7, ptr %ptr.iv, i16 1
37836999318SFlorian Hahn  br label %loop.header
37936999318SFlorian Hahn
38036999318SFlorian Hahnexit:
38136999318SFlorian Hahn  ret void
38236999318SFlorian Hahn}
38336999318SFlorian Hahn
38436999318SFlorian Hahndefine void @test_monotonic_ptr_iv_inc_2_different_element_types_with_same_alloc_type_sizes_with_early_exit(ptr %start, i16 %len) {
38536999318SFlorian Hahn; CHECK-LABEL: @test_monotonic_ptr_iv_inc_2_different_element_types_with_same_alloc_type_sizes_with_early_exit(
38636999318SFlorian Hahn; CHECK-NEXT:  entry:
38736999318SFlorian Hahn; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i31, ptr [[START:%.*]], i16 [[LEN:%.*]]
38836999318SFlorian Hahn; CHECK-NEXT:    [[LEN_NEG:%.*]] = icmp slt i16 [[LEN]], 0
38936999318SFlorian Hahn; CHECK-NEXT:    br i1 [[LEN_NEG]], label [[EXIT:%.*]], label [[LOOP_PH:%.*]]
39036999318SFlorian Hahn; CHECK:       loop.ph:
39136999318SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
39236999318SFlorian Hahn; CHECK:       loop.header:
39336999318SFlorian Hahn; CHECK-NEXT:    [[PTR_IV:%.*]] = phi ptr [ [[START]], [[LOOP_PH]] ], [ [[PTR_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
39436999318SFlorian Hahn; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[PTR_IV]], [[UPPER]]
39536999318SFlorian Hahn; CHECK-NEXT:    br i1 [[C]], label [[EXIT]], label [[FOR_BODY:%.*]]
39636999318SFlorian Hahn; CHECK:       for.body:
39736999318SFlorian Hahn; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
39836999318SFlorian Hahn; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_NEXT:%.*]], label [[EXIT]]
39936999318SFlorian Hahn; CHECK:       loop.next:
400*e6a1657fSFlorian Hahn; CHECK-NEXT:    [[AND:%.*]] = and i1 true, true
40136999318SFlorian Hahn; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT]]
40236999318SFlorian Hahn; CHECK:       loop.latch:
40336999318SFlorian Hahn; CHECK-NEXT:    call void @use(ptr [[PTR_IV]])
40436999318SFlorian Hahn; CHECK-NEXT:    [[PTR_IV_NEXT]] = getelementptr inbounds i30, ptr [[PTR_IV]], i16 1
40536999318SFlorian Hahn; CHECK-NEXT:    br label [[LOOP_HEADER]]
40636999318SFlorian Hahn; CHECK:       exit:
40736999318SFlorian Hahn; CHECK-NEXT:    ret void
40836999318SFlorian Hahn;
40936999318SFlorian Hahnentry:
41036999318SFlorian Hahn  %upper = getelementptr inbounds i31, ptr %start, i16 %len
41136999318SFlorian Hahn  %len.neg = icmp slt i16 %len, 0
41236999318SFlorian Hahn  br i1 %len.neg, label %exit, label %loop.ph
41336999318SFlorian Hahn
41436999318SFlorian Hahnloop.ph:
41536999318SFlorian Hahn  br label %loop.header
41636999318SFlorian Hahn
41736999318SFlorian Hahnloop.header:
41836999318SFlorian Hahn  %ptr.iv = phi ptr [ %start, %loop.ph ], [ %ptr.iv.next, %loop.latch ]
41936999318SFlorian Hahn  %c = icmp eq ptr %ptr.iv, %upper
42036999318SFlorian Hahn  br i1 %c, label %exit, label %for.body
42136999318SFlorian Hahn
42236999318SFlorian Hahnfor.body:
42336999318SFlorian Hahn  %c.1 = call i1 @cond()
42436999318SFlorian Hahn  br i1 %c.1, label %loop.next, label %exit
42536999318SFlorian Hahn
42636999318SFlorian Hahnloop.next:
42736999318SFlorian Hahn  %t.1 = icmp uge ptr %ptr.iv, %start
42836999318SFlorian Hahn  %t.2 = icmp ult ptr %ptr.iv, %upper
42936999318SFlorian Hahn  %and = and i1 %t.1, %t.2
43036999318SFlorian Hahn  br i1 %and, label %loop.latch, label %exit
43136999318SFlorian Hahn
43236999318SFlorian Hahnloop.latch:
43336999318SFlorian Hahn  call void @use(ptr %ptr.iv)
43436999318SFlorian Hahn  %ptr.iv.next = getelementptr inbounds i30, ptr %ptr.iv, i16 1
43536999318SFlorian Hahn  br label %loop.header
43636999318SFlorian Hahn
43736999318SFlorian Hahnexit:
43836999318SFlorian Hahn  ret void
43936999318SFlorian Hahn}
440