xref: /llvm-project/llvm/test/CodeGen/X86/overflowing-iv-codegen.ll (revision e6bf48d11047e970cb24554a01b65b566d6b5d22)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-linux | 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:       # %bb.0: # %entry
8; CHECK-NEXT:    addq $-4, %rdi
9; CHECK-NEXT:    .p2align 4
10; CHECK-NEXT:  .LBB0_1: # %loop
11; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
12; CHECK-NEXT:    subq $1, %rsi
13; CHECK-NEXT:    jb .LBB0_4
14; CHECK-NEXT:  # %bb.2: # %backedge
15; CHECK-NEXT:    # in Loop: Header=BB0_1 Depth=1
16; CHECK-NEXT:    cmpl %edx, (%rdi)
17; CHECK-NEXT:    leaq 4(%rdi), %rdi
18; CHECK-NEXT:    jne .LBB0_1
19; CHECK-NEXT:  # %bb.3: # %failure
20; CHECK-NEXT:  .LBB0_4: # %exit
21; CHECK-NEXT:    movl $-1, %eax
22; CHECK-NEXT:    retq
23entry:
24  %scevgep = getelementptr i32, ptr %p, i64 -1
25  br label %loop
26
27loop:                                             ; preds = %backedge, %entry
28  %iv = phi i64 [ %iv.next, %backedge ], [ 0, %entry ]
29  %iv.next = add i64 %iv, 1
30  %cond_1 = icmp eq i64 %iv, %len
31  br i1 %cond_1, label %exit, label %backedge
32
33backedge:                                         ; preds = %loop
34  %scevgep1 = getelementptr i32, ptr %scevgep, i64 %iv
35  %loaded = load atomic i32, ptr %scevgep1 unordered, align 4
36  %cond_2 = icmp eq i32 %loaded, %x
37  br i1 %cond_2, label %failure, label %loop
38
39exit:                                             ; preds = %loop
40  ret i32 -1
41
42failure:                                          ; preds = %backedge
43  unreachable
44}
45
46; nsw flag, same type width.
47define i32 @test_02(ptr %p, i64 %len, i32 %x) {
48; CHECK-LABEL: test_02:
49; CHECK:       # %bb.0: # %entry
50; CHECK-NEXT:    addq $-4, %rdi
51; CHECK-NEXT:    .p2align 4
52; CHECK-NEXT:  .LBB1_1: # %loop
53; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
54; CHECK-NEXT:    subq $1, %rsi
55; CHECK-NEXT:    jb .LBB1_4
56; CHECK-NEXT:  # %bb.2: # %backedge
57; CHECK-NEXT:    # in Loop: Header=BB1_1 Depth=1
58; CHECK-NEXT:    cmpl %edx, (%rdi)
59; CHECK-NEXT:    leaq 4(%rdi), %rdi
60; CHECK-NEXT:    jne .LBB1_1
61; CHECK-NEXT:  # %bb.3: # %failure
62; CHECK-NEXT:  .LBB1_4: # %exit
63; CHECK-NEXT:    movl $-1, %eax
64; CHECK-NEXT:    retq
65entry:
66  %scevgep = getelementptr i32, ptr %p, i64 -1
67  br label %loop
68
69loop:                                             ; preds = %backedge, %entry
70  %iv = phi i64 [ %iv.next, %backedge ], [ 0, %entry ]
71  %iv.next = add nsw i64 %iv, 1
72  %cond_1 = icmp eq i64 %iv, %len
73  br i1 %cond_1, label %exit, label %backedge
74
75backedge:                                         ; preds = %loop
76  %scevgep1 = getelementptr i32, ptr %scevgep, i64 %iv
77  %loaded = load atomic i32, ptr %scevgep1 unordered, align 4
78  %cond_2 = icmp eq i32 %loaded, %x
79  br i1 %cond_2, label %failure, label %loop
80
81exit:                                             ; preds = %loop
82  ret i32 -1
83
84failure:                                          ; preds = %backedge
85  unreachable
86}
87
88; nsw flag, optimization is possible because memory instruction is dominated by loop-exiting check against iv.next.
89define i32 @test_02_nopoison(ptr %p, i64 %len, i32 %x) {
90; CHECK-LABEL: test_02_nopoison:
91; CHECK:       # %bb.0: # %entry
92; CHECK-NEXT:    addq $-4, %rdi
93; CHECK-NEXT:    .p2align 4
94; CHECK-NEXT:  .LBB2_1: # %loop
95; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
96; CHECK-NEXT:    subq $1, %rsi
97; CHECK-NEXT:    jb .LBB2_4
98; CHECK-NEXT:  # %bb.2: # %backedge
99; CHECK-NEXT:    # in Loop: Header=BB2_1 Depth=1
100; CHECK-NEXT:    cmpl %edx, (%rdi)
101; CHECK-NEXT:    leaq 4(%rdi), %rdi
102; CHECK-NEXT:    jne .LBB2_1
103; CHECK-NEXT:  # %bb.3: # %failure
104; CHECK-NEXT:  .LBB2_4: # %exit
105; CHECK-NEXT:    movl $-1, %eax
106; CHECK-NEXT:    retq
107entry:
108  %len.plus.1 = add i64 %len, 1
109  %scevgep = getelementptr i32, ptr %p, i64 -1
110  br label %loop
111
112loop:                                             ; preds = %backedge, %entry
113  %iv = phi i64 [ %iv.next, %backedge ], [ 0, %entry ]
114  %iv.next = add nsw i64 %iv, 1
115  %cond_1 = icmp eq i64 %iv.next, %len.plus.1
116  br i1 %cond_1, label %exit, label %backedge
117
118backedge:                                         ; preds = %loop
119  %scevgep1 = getelementptr i32, ptr %scevgep, i64 %iv
120  %loaded = load atomic i32, ptr %scevgep1 unordered, align 4
121  %cond_2 = icmp eq i32 %loaded, %x
122  br i1 %cond_2, label %failure, label %loop
123
124exit:                                             ; preds = %loop
125  ret i32 -1
126
127failure:                                          ; preds = %backedge
128  unreachable
129}
130
131
132; nuw flag, same type width.
133define i32 @test_03(ptr %p, i64 %len, i32 %x) {
134; CHECK-LABEL: test_03:
135; CHECK:       # %bb.0: # %entry
136; CHECK-NEXT:    addq $-4, %rdi
137; CHECK-NEXT:    .p2align 4
138; CHECK-NEXT:  .LBB3_1: # %loop
139; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
140; CHECK-NEXT:    subq $1, %rsi
141; CHECK-NEXT:    jb .LBB3_4
142; CHECK-NEXT:  # %bb.2: # %backedge
143; CHECK-NEXT:    # in Loop: Header=BB3_1 Depth=1
144; CHECK-NEXT:    cmpl %edx, (%rdi)
145; CHECK-NEXT:    leaq 4(%rdi), %rdi
146; CHECK-NEXT:    jne .LBB3_1
147; CHECK-NEXT:  # %bb.3: # %failure
148; CHECK-NEXT:  .LBB3_4: # %exit
149; CHECK-NEXT:    movl $-1, %eax
150; CHECK-NEXT:    retq
151entry:
152  %scevgep = getelementptr i32, ptr %p, i64 -1
153  br label %loop
154
155loop:                                             ; preds = %backedge, %entry
156  %iv = phi i64 [ %iv.next, %backedge ], [ 0, %entry ]
157  %iv.next = add nuw i64 %iv, 1
158  %cond_1 = icmp eq i64 %iv, %len
159  br i1 %cond_1, label %exit, label %backedge
160
161backedge:                                         ; preds = %loop
162  %scevgep1 = getelementptr i32, ptr %scevgep, i64 %iv
163  %loaded = load atomic i32, ptr %scevgep1 unordered, align 4
164  %cond_2 = icmp eq i32 %loaded, %x
165  br i1 %cond_2, label %failure, label %loop
166
167exit:                                             ; preds = %loop
168  ret i32 -1
169
170failure:                                          ; preds = %backedge
171  unreachable
172}
173
174; nuw flag, optimization is possible because memory instruction is dominated by loop-exiting check against iv.next.
175define i32 @test_03_nopoison(ptr %p, i64 %len, i32 %x) {
176; CHECK-LABEL: test_03_nopoison:
177; CHECK:       # %bb.0: # %entry
178; CHECK-NEXT:    addq $-4, %rdi
179; CHECK-NEXT:    .p2align 4
180; CHECK-NEXT:  .LBB4_1: # %loop
181; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
182; CHECK-NEXT:    subq $1, %rsi
183; CHECK-NEXT:    jb .LBB4_4
184; CHECK-NEXT:  # %bb.2: # %backedge
185; CHECK-NEXT:    # in Loop: Header=BB4_1 Depth=1
186; CHECK-NEXT:    cmpl %edx, (%rdi)
187; CHECK-NEXT:    leaq 4(%rdi), %rdi
188; CHECK-NEXT:    jne .LBB4_1
189; CHECK-NEXT:  # %bb.3: # %failure
190; CHECK-NEXT:  .LBB4_4: # %exit
191; CHECK-NEXT:    movl $-1, %eax
192; CHECK-NEXT:    retq
193entry:
194  %len.plus.1 = add i64 %len, 1
195  %scevgep = getelementptr i32, ptr %p, i64 -1
196  br label %loop
197
198loop:                                             ; preds = %backedge, %entry
199  %iv = phi i64 [ %iv.next, %backedge ], [ 0, %entry ]
200  %iv.next = add nuw i64 %iv, 1
201  %cond_1 = icmp eq i64 %iv.next, %len.plus.1
202  br i1 %cond_1, label %exit, label %backedge
203
204backedge:                                         ; preds = %loop
205  %scevgep1 = getelementptr i32, ptr %scevgep, i64 %iv
206  %loaded = load atomic i32, ptr %scevgep1 unordered, align 4
207  %cond_2 = icmp eq i32 %loaded, %x
208  br i1 %cond_2, label %failure, label %loop
209
210exit:                                             ; preds = %loop
211  ret i32 -1
212
213failure:                                          ; preds = %backedge
214  unreachable
215}
216