xref: /llvm-project/llvm/test/Transforms/IndVarSimplify/X86/eliminate-congruent-ivs.ll (revision 3ce360f15b5a790a5fd9dcab716bbed7b4d3a347)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=indvars -scalar-evolution-use-expensive-range-sharpening -S | FileCheck %s
3
4target triple = "x86_64--linux-gnu"
5
6; Provide legal integer types.
7target datalayout = "n8:16:32:64"
8
9declare void @foo(i64 %v)
10declare void @bar(i32 %v)
11
12define void @test1() {
13; CHECK-LABEL: @test1(
14; CHECK-NEXT:  entry:
15; CHECK-NEXT:    br label [[LOOP:%.*]]
16; CHECK:       loop:
17; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
18; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
19; CHECK-NEXT:    [[INDVARS2:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
20; CHECK-NEXT:    call void @bar(i32 [[INDVARS2]])
21; CHECK-NEXT:    call void @foo(i64 [[INDVARS_IV]])
22; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 1000
23; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
24; CHECK:       exit:
25; CHECK-NEXT:    ret void
26;
27entry:
28  br label %loop
29
30loop:                                             ; preds = %loop, %entry
31  %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
32  %val1 = phi i32 [ %val1.inc, %loop ], [ 0, %entry ]
33  %val1.inc = add i32 %val1, 1
34  %iv.next = add i32 %iv, 1
35  call void @bar(i32 %val1.inc)
36  %iv.wide = zext i32 %iv to i64
37  call void @foo(i64 %iv.wide)
38  %loop.cond = icmp eq i32 %iv, 1000
39  br i1 %loop.cond, label %exit, label %loop
40
41exit:                                             ; preds = %loop
42  ret void
43}
44
45define void @test2() {
46; CHECK-LABEL: @test2(
47; CHECK-NEXT:  entry:
48; CHECK-NEXT:    br label [[LOOP:%.*]]
49; CHECK:       loop:
50; CHECK-NEXT:    [[VAL1:%.*]] = phi i64 [ [[VAL1_INC:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
51; CHECK-NEXT:    [[VAL1_INC]] = add nuw nsw i64 [[VAL1]], 1
52; CHECK-NEXT:    call void @foo(i64 [[VAL1_INC]])
53; CHECK-NEXT:    call void @foo(i64 [[VAL1]])
54; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i64 [[VAL1]], 1000
55; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
56; CHECK:       exit:
57; CHECK-NEXT:    ret void
58;
59entry:
60  br label %loop
61
62loop:                                             ; preds = %loop, %entry
63  %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
64  %val1 = phi i64 [ %val1.inc, %loop ], [ 0, %entry ]
65  %val1.inc = add i64 %val1, 1
66  %iv.next = add i32 %iv, 1
67  call void @foo(i64 %val1.inc)
68  %iv.wide = zext i32 %iv to i64
69  call void @foo(i64 %iv.wide)
70  %loop.cond = icmp eq i32 %iv, 1000
71  br i1 %loop.cond, label %exit, label %loop
72
73exit:                                             ; preds = %loop
74  ret void
75}
76
77define void @test3() {
78; CHECK-LABEL: @test3(
79; CHECK-NEXT:  entry:
80; CHECK-NEXT:    br label [[LOOP:%.*]]
81; CHECK:       loop:
82; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
83; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
84; CHECK-NEXT:    call void @foo(i64 [[INDVARS_IV]])
85; CHECK-NEXT:    call void @foo(i64 [[INDVARS_IV]])
86; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 1000
87; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
88; CHECK:       exit:
89; CHECK-NEXT:    ret void
90;
91entry:
92  br label %loop
93
94loop:                                             ; preds = %loop, %entry
95  %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
96  %val1 = phi i32 [ %val1.inc, %loop ], [ 0, %entry ]
97  %val1.inc = add i32 %val1, 1
98  %iv.next = add i32 %iv, 1
99  %val1.wide = zext i32 %val1 to i64
100  call void @foo(i64 %val1.wide)
101  %iv.wide = zext i32 %iv to i64
102  call void @foo(i64 %iv.wide)
103  %loop.cond = icmp eq i32 %iv, 1000
104  br i1 %loop.cond, label %exit, label %loop
105
106exit:                                             ; preds = %loop
107  ret void
108}
109
110define void @test4(ptr %ptr) {
111; CHECK-LABEL: @test4(
112; CHECK-NEXT:  entry:
113; CHECK-NEXT:    store i32 0, ptr [[PTR:%.*]], align 4
114; CHECK-NEXT:    br label [[LOOP:%.*]]
115; CHECK:       loop:
116; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ 0, [[ENTRY:%.*]] ]
117; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
118; CHECK-NEXT:    [[INDVARS:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
119; CHECK-NEXT:    store i32 [[INDVARS]], ptr [[PTR]], align 4
120; CHECK-NEXT:    call void @foo(i64 [[INDVARS_IV]])
121; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 1000
122; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[EXIT:%.*]], label [[LOOP]]
123; CHECK:       exit:
124; CHECK-NEXT:    ret void
125;
126entry:
127  store i32 0, ptr %ptr, align 4
128  br label %loop
129
130loop:                                             ; preds = %loop, %entry
131  %val = phi i32 [ %val.inc, %loop ], [ 0, %entry ]
132  %iv = phi i32 [ %iv.next, %loop ], [ 0, %entry ]
133  %val.inc = add i32 %val, 1
134  store i32 %val.inc, ptr %ptr, align 4
135  %iv.wide = zext i32 %iv to i64
136  call void @foo(i64 %iv.wide)
137  %iv.next = add i32 %iv, 1
138  %loop.cond = icmp eq i32 %iv, 1000
139  br i1 %loop.cond, label %exit, label %loop
140
141exit:                                             ; preds = %loop
142  ret void
143}
144