xref: /llvm-project/llvm/test/CodeGen/X86/overflowing-iv.ll (revision 2f448bf509432c1a19ec46ab8cbc7353c03c6280)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -mtriple=x86_64-linux -codegenprepare -S | FileCheck %s
3
4; No overflow flags, same type width.
5define i32 @test_01(ptr %p, i64 %len, i32 %x) {
6; CHECK-LABEL: @test_01(
7; CHECK-NEXT:  entry:
8; CHECK-NEXT:    br label [[LOOP:%.*]]
9; CHECK:       loop:
10; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[ENTRY:%.*]] ]
11; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
12; CHECK-NEXT:    [[COND_1:%.*]] = icmp eq i64 [[IV]], [[LEN:%.*]]
13; CHECK-NEXT:    br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]]
14; CHECK:       backedge:
15; CHECK-NEXT:    [[SUNKADDR:%.*]] = mul i64 [[IV_NEXT]], 4
16; CHECK-NEXT:    [[SUNKADDR1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[SUNKADDR]]
17; CHECK-NEXT:    [[SUNKADDR2:%.*]] = getelementptr i8, ptr [[SUNKADDR1]], i64 -8
18; CHECK-NEXT:    [[LOADED:%.*]] = load atomic i32, ptr [[SUNKADDR2]] unordered, align 4
19; CHECK-NEXT:    [[COND_2:%.*]] = icmp eq i32 [[LOADED]], [[X:%.*]]
20; CHECK-NEXT:    br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]]
21; CHECK:       exit:
22; CHECK-NEXT:    ret i32 -1
23; CHECK:       failure:
24; CHECK-NEXT:    unreachable
25;
26entry:
27  %scevgep = getelementptr i32, ptr %p, i64 -1
28  br label %loop
29
30loop:                                             ; preds = %backedge, %entry
31  %iv = phi i64 [ %iv.next, %backedge ], [ 0, %entry ]
32  %iv.next = add i64 %iv, 1
33  %cond_1 = icmp eq i64 %iv, %len
34  br i1 %cond_1, label %exit, label %backedge
35
36backedge:                                         ; preds = %loop
37  %scevgep1 = getelementptr i32, ptr %scevgep, i64 %iv
38  %loaded = load atomic i32, ptr %scevgep1 unordered, align 4
39  %cond_2 = icmp eq i32 %loaded, %x
40  br i1 %cond_2, label %failure, label %loop
41
42exit:                                             ; preds = %loop
43  ret i32 -1
44
45failure:                                          ; preds = %backedge
46  unreachable
47}
48
49; nsw flag, same type width.
50define i32 @test_02(ptr %p, i64 %len, i32 %x) {
51; CHECK-LABEL: @test_02(
52; CHECK-NEXT:  entry:
53; CHECK-NEXT:    br label [[LOOP:%.*]]
54; CHECK:       loop:
55; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[ENTRY:%.*]] ]
56; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 1
57; CHECK-NEXT:    [[COND_1:%.*]] = icmp eq i64 [[IV]], [[LEN:%.*]]
58; CHECK-NEXT:    br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]]
59; CHECK:       backedge:
60; CHECK-NEXT:    [[SUNKADDR:%.*]] = mul i64 [[IV]], 4
61; CHECK-NEXT:    [[SUNKADDR1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[SUNKADDR]]
62; CHECK-NEXT:    [[SUNKADDR2:%.*]] = getelementptr i8, ptr [[SUNKADDR1]], i64 -4
63; CHECK-NEXT:    [[LOADED:%.*]] = load atomic i32, ptr [[SUNKADDR2]] unordered, align 4
64; CHECK-NEXT:    [[COND_2:%.*]] = icmp eq i32 [[LOADED]], [[X:%.*]]
65; CHECK-NEXT:    br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]]
66; CHECK:       exit:
67; CHECK-NEXT:    ret i32 -1
68; CHECK:       failure:
69; CHECK-NEXT:    unreachable
70;
71entry:
72  %scevgep = getelementptr i32, ptr %p, i64 -1
73  br label %loop
74
75loop:                                             ; preds = %backedge, %entry
76  %iv = phi i64 [ %iv.next, %backedge ], [ 0, %entry ]
77  %iv.next = add nsw i64 %iv, 1
78  %cond_1 = icmp eq i64 %iv, %len
79  br i1 %cond_1, label %exit, label %backedge
80
81backedge:                                         ; preds = %loop
82  %scevgep1 = getelementptr i32, ptr %scevgep, i64 %iv
83  %loaded = load atomic i32, ptr %scevgep1 unordered, align 4
84  %cond_2 = icmp eq i32 %loaded, %x
85  br i1 %cond_2, label %failure, label %loop
86
87exit:                                             ; preds = %loop
88  ret i32 -1
89
90failure:                                          ; preds = %backedge
91  unreachable
92}
93
94; nsw flag, optimization is possible because memory instruction is dominated by loop-exiting check against iv.next.
95define i32 @test_02_nopoison(ptr %p, i64 %len, i32 %x) {
96; CHECK-LABEL: @test_02_nopoison(
97; CHECK-NEXT:  entry:
98; CHECK-NEXT:    [[LEN_PLUS_1:%.*]] = add i64 [[LEN:%.*]], 1
99; CHECK-NEXT:    br label [[LOOP:%.*]]
100; CHECK:       loop:
101; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[ENTRY:%.*]] ]
102; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 1
103; CHECK-NEXT:    [[COND_1:%.*]] = icmp eq i64 [[IV_NEXT]], [[LEN_PLUS_1]]
104; CHECK-NEXT:    br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]]
105; CHECK:       backedge:
106; CHECK-NEXT:    [[SUNKADDR:%.*]] = mul i64 [[IV]], 4
107; CHECK-NEXT:    [[SUNKADDR1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[SUNKADDR]]
108; CHECK-NEXT:    [[SUNKADDR2:%.*]] = getelementptr i8, ptr [[SUNKADDR1]], i64 -4
109; CHECK-NEXT:    [[LOADED:%.*]] = load atomic i32, ptr [[SUNKADDR2]] unordered, align 4
110; CHECK-NEXT:    [[COND_2:%.*]] = icmp eq i32 [[LOADED]], [[X:%.*]]
111; CHECK-NEXT:    br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]]
112; CHECK:       exit:
113; CHECK-NEXT:    ret i32 -1
114; CHECK:       failure:
115; CHECK-NEXT:    unreachable
116;
117entry:
118  %len.plus.1 = add i64 %len, 1
119  %scevgep = getelementptr i32, ptr %p, i64 -1
120  br label %loop
121
122loop:                                             ; preds = %backedge, %entry
123  %iv = phi i64 [ %iv.next, %backedge ], [ 0, %entry ]
124  %iv.next = add nsw i64 %iv, 1
125  %cond_1 = icmp eq i64 %iv.next, %len.plus.1
126  br i1 %cond_1, label %exit, label %backedge
127
128backedge:                                         ; preds = %loop
129  %scevgep1 = getelementptr i32, ptr %scevgep, i64 %iv
130  %loaded = load atomic i32, ptr %scevgep1 unordered, align 4
131  %cond_2 = icmp eq i32 %loaded, %x
132  br i1 %cond_2, label %failure, label %loop
133
134exit:                                             ; preds = %loop
135  ret i32 -1
136
137failure:                                          ; preds = %backedge
138  unreachable
139}
140
141
142; nuw flag, same type width.
143define i32 @test_03(ptr %p, i64 %len, i32 %x) {
144; CHECK-LABEL: @test_03(
145; CHECK-NEXT:  entry:
146; CHECK-NEXT:    br label [[LOOP:%.*]]
147; CHECK:       loop:
148; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[ENTRY:%.*]] ]
149; CHECK-NEXT:    [[IV_NEXT]] = add nuw i64 [[IV]], 1
150; CHECK-NEXT:    [[COND_1:%.*]] = icmp eq i64 [[IV]], [[LEN:%.*]]
151; CHECK-NEXT:    br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]]
152; CHECK:       backedge:
153; CHECK-NEXT:    [[SUNKADDR:%.*]] = mul i64 [[IV]], 4
154; CHECK-NEXT:    [[SUNKADDR1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[SUNKADDR]]
155; CHECK-NEXT:    [[SUNKADDR2:%.*]] = getelementptr i8, ptr [[SUNKADDR1]], i64 -4
156; CHECK-NEXT:    [[LOADED:%.*]] = load atomic i32, ptr [[SUNKADDR2]] unordered, align 4
157; CHECK-NEXT:    [[COND_2:%.*]] = icmp eq i32 [[LOADED]], [[X:%.*]]
158; CHECK-NEXT:    br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]]
159; CHECK:       exit:
160; CHECK-NEXT:    ret i32 -1
161; CHECK:       failure:
162; CHECK-NEXT:    unreachable
163;
164entry:
165  %scevgep = getelementptr i32, ptr %p, i64 -1
166  br label %loop
167
168loop:                                             ; preds = %backedge, %entry
169  %iv = phi i64 [ %iv.next, %backedge ], [ 0, %entry ]
170  %iv.next = add nuw i64 %iv, 1
171  %cond_1 = icmp eq i64 %iv, %len
172  br i1 %cond_1, label %exit, label %backedge
173
174backedge:                                         ; preds = %loop
175  %scevgep1 = getelementptr i32, ptr %scevgep, i64 %iv
176  %loaded = load atomic i32, ptr %scevgep1 unordered, align 4
177  %cond_2 = icmp eq i32 %loaded, %x
178  br i1 %cond_2, label %failure, label %loop
179
180exit:                                             ; preds = %loop
181  ret i32 -1
182
183failure:                                          ; preds = %backedge
184  unreachable
185}
186
187; nuw flag, optimization is possible because memory instruction is dominated by loop-exiting check against iv.next.
188define i32 @test_03_nopoison(ptr %p, i64 %len, i32 %x) {
189; CHECK-LABEL: @test_03_nopoison(
190; CHECK-NEXT:  entry:
191; CHECK-NEXT:    [[LEN_PLUS_1:%.*]] = add i64 [[LEN:%.*]], 1
192; CHECK-NEXT:    br label [[LOOP:%.*]]
193; CHECK:       loop:
194; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[ENTRY:%.*]] ]
195; CHECK-NEXT:    [[IV_NEXT]] = add nuw i64 [[IV]], 1
196; CHECK-NEXT:    [[COND_1:%.*]] = icmp eq i64 [[IV_NEXT]], [[LEN_PLUS_1]]
197; CHECK-NEXT:    br i1 [[COND_1]], label [[EXIT:%.*]], label [[BACKEDGE]]
198; CHECK:       backedge:
199; CHECK-NEXT:    [[SUNKADDR:%.*]] = mul i64 [[IV]], 4
200; CHECK-NEXT:    [[SUNKADDR1:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[SUNKADDR]]
201; CHECK-NEXT:    [[SUNKADDR2:%.*]] = getelementptr i8, ptr [[SUNKADDR1]], i64 -4
202; CHECK-NEXT:    [[LOADED:%.*]] = load atomic i32, ptr [[SUNKADDR2]] unordered, align 4
203; CHECK-NEXT:    [[COND_2:%.*]] = icmp eq i32 [[LOADED]], [[X:%.*]]
204; CHECK-NEXT:    br i1 [[COND_2]], label [[FAILURE:%.*]], label [[LOOP]]
205; CHECK:       exit:
206; CHECK-NEXT:    ret i32 -1
207; CHECK:       failure:
208; CHECK-NEXT:    unreachable
209;
210entry:
211  %len.plus.1 = add i64 %len, 1
212  %scevgep = getelementptr i32, ptr %p, i64 -1
213  br label %loop
214
215loop:                                             ; preds = %backedge, %entry
216  %iv = phi i64 [ %iv.next, %backedge ], [ 0, %entry ]
217  %iv.next = add nuw i64 %iv, 1
218  %cond_1 = icmp eq i64 %iv.next, %len.plus.1
219  br i1 %cond_1, label %exit, label %backedge
220
221backedge:                                         ; preds = %loop
222  %scevgep1 = getelementptr i32, ptr %scevgep, i64 %iv
223  %loaded = load atomic i32, ptr %scevgep1 unordered, align 4
224  %cond_2 = icmp eq i32 %loaded, %x
225  br i1 %cond_2, label %failure, label %loop
226
227exit:                                             ; preds = %loop
228  ret i32 -1
229
230failure:                                          ; preds = %backedge
231  unreachable
232}
233