xref: /llvm-project/llvm/test/Analysis/LoopAccessAnalysis/underlying-object-loop-varying-phi.ll (revision a3ad5faa321848376b277db369313c80d3df2152)
1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 4
2; RUN: opt -passes='print<access-info>' -disable-output %s 2>&1 | FileCheck %s
3
4target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
5
6; Test case for https://github.com/llvm/llvm-project/issues/82665.
7define void @indirect_ptr_recurrences_read_write(ptr %A, ptr %B) {
8; CHECK-LABEL: 'indirect_ptr_recurrences_read_write'
9; CHECK-NEXT:    loop:
10; CHECK-NEXT:      Report: unsafe dependent memory operations in loop. Use #pragma clang loop distribute(enable) to allow loop distribution to attempt to isolate the offending operations into a separate loop
11; CHECK-NEXT:  Unsafe indirect dependence.
12; CHECK-NEXT:      Dependences:
13; CHECK-NEXT:        IndirectUnsafe:
14; CHECK-NEXT:            %l = load i32, ptr %ptr.recur, align 4, !tbaa !4 ->
15; CHECK-NEXT:            store i32 %xor, ptr %ptr.recur, align 4, !tbaa !4
16; CHECK-EMPTY:
17; CHECK-NEXT:      Run-time memory checks:
18; CHECK-NEXT:      Grouped accesses:
19; CHECK-EMPTY:
20; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
21; CHECK-NEXT:      SCEV assumptions:
22; CHECK-EMPTY:
23; CHECK-NEXT:      Expressions re-written:
24;
25entry:
26  br label %loop
27
28loop:
29  %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
30  %ptr.recur = phi ptr [ %A, %entry ], [ %ptr.next, %loop ]
31  %gep.B = getelementptr inbounds ptr, ptr %B, i64 %iv
32  %ptr.next = load ptr, ptr %gep.B, align 8, !tbaa !6
33  %l = load i32, ptr %ptr.recur, align 4, !tbaa !10
34  %xor = xor i32 %l, 1
35  store i32 %xor, ptr %ptr.recur, align 4, !tbaa !10
36  %iv.next = add nuw nsw i64 %iv, 1
37  %ec = icmp eq i64 %iv.next, 5
38  br i1 %ec, label %exit, label %loop
39
40exit:
41  ret void
42}
43
44define i32 @indirect_ptr_recurrences_read_only_loop(ptr %A, ptr %B) {
45; CHECK-LABEL: 'indirect_ptr_recurrences_read_only_loop'
46; CHECK-NEXT:    loop:
47; CHECK-NEXT:      Memory dependences are safe
48; CHECK-NEXT:      Dependences:
49; CHECK-NEXT:      Run-time memory checks:
50; CHECK-NEXT:      Grouped accesses:
51; CHECK-EMPTY:
52; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
53; CHECK-NEXT:      SCEV assumptions:
54; CHECK-EMPTY:
55; CHECK-NEXT:      Expressions re-written:
56;
57entry:
58  br label %loop
59
60loop:
61  %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
62  %ptr.recur = phi ptr [ %A, %entry ], [ %ptr.next, %loop ]
63  %red = phi i32 [ 0, %entry ], [ %xor, %loop ]
64  %gep.B = getelementptr inbounds ptr, ptr %B, i64 %iv
65  %ptr.next = load ptr, ptr %gep.B, align 8, !tbaa !6
66  %l = load i32, ptr %ptr.recur, align 4, !tbaa !10
67  %xor = xor i32 %l, 1
68  %iv.next = add nuw nsw i64 %iv, 1
69  %ec = icmp eq i64 %iv.next, 5
70  br i1 %ec, label %exit, label %loop
71
72exit:
73  ret i32 %xor
74}
75
76define void @indirect_ptr_recurrences_read_write_may_alias_no_tbaa(ptr %A, ptr %B) {
77; CHECK-LABEL: 'indirect_ptr_recurrences_read_write_may_alias_no_tbaa'
78; CHECK-NEXT:    loop:
79; CHECK-NEXT:      Report: cannot identify array bounds
80; CHECK-NEXT:      Dependences:
81; CHECK-NEXT:      Run-time memory checks:
82; CHECK-NEXT:      Grouped accesses:
83; CHECK-EMPTY:
84; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
85; CHECK-NEXT:      SCEV assumptions:
86; CHECK-EMPTY:
87; CHECK-NEXT:      Expressions re-written:
88;
89entry:
90  br label %loop
91
92loop:
93  %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
94  %ptr.recur = phi ptr [ %A, %entry ], [ %ptr.next, %loop ]
95  %gep.B = getelementptr inbounds ptr, ptr %B, i64 %iv
96  %ptr.next = load ptr, ptr %gep.B, align 8, !tbaa !6
97  %l = load i32, ptr %ptr.recur, align 4
98  %xor = xor i32 %l, 1
99  store i32 %xor, ptr %ptr.recur, align 4
100  %iv.next = add nuw nsw i64 %iv, 1
101  %ec = icmp eq i64 %iv.next, 5
102  br i1 %ec, label %exit, label %loop
103
104exit:
105  ret void
106}
107
108define void @indirect_ptr_recurrences_read_write_may_alias_different_obj(ptr %A, ptr %B, ptr %C) {
109; CHECK-LABEL: 'indirect_ptr_recurrences_read_write_may_alias_different_obj'
110; CHECK-NEXT:    loop:
111; CHECK-NEXT:      Report: cannot identify array bounds
112; CHECK-NEXT:      Dependences:
113; CHECK-NEXT:      Run-time memory checks:
114; CHECK-NEXT:      Grouped accesses:
115; CHECK-EMPTY:
116; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
117; CHECK-NEXT:      SCEV assumptions:
118; CHECK-EMPTY:
119; CHECK-NEXT:      Expressions re-written:
120;
121entry:
122  br label %loop
123
124loop:
125  %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
126  %ptr.recur = phi ptr [ %A, %entry ], [ %ptr.next, %loop ]
127  %gep.B = getelementptr inbounds ptr, ptr %B, i64 %iv
128  %ptr.next = load ptr, ptr %gep.B, align 8, !tbaa !6
129  %l = load i32, ptr %ptr.recur, align 4
130  %xor = xor i32 %l, 1
131  %gep.C = getelementptr inbounds ptr, ptr %C, i64 %iv
132  store i32 %xor, ptr %gep.C, align 4
133  %iv.next = add nuw nsw i64 %iv, 1
134  %ec = icmp eq i64 %iv.next, 5
135  br i1 %ec, label %exit, label %loop
136
137exit:
138  ret void
139}
140
141define void @indirect_ptr_recurrences_read_write_may_noalias_different_obj(ptr %A, ptr %B, ptr noalias %C) {
142; CHECK-LABEL: 'indirect_ptr_recurrences_read_write_may_noalias_different_obj'
143; CHECK-NEXT:    loop:
144; CHECK-NEXT:      Memory dependences are safe
145; CHECK-NEXT:      Dependences:
146; CHECK-NEXT:      Run-time memory checks:
147; CHECK-NEXT:      Grouped accesses:
148; CHECK-EMPTY:
149; CHECK-NEXT:      Non vectorizable stores to invariant address were not found in loop.
150; CHECK-NEXT:      SCEV assumptions:
151; CHECK-EMPTY:
152; CHECK-NEXT:      Expressions re-written:
153;
154entry:
155  br label %loop
156
157loop:
158  %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop ]
159  %ptr.recur = phi ptr [ %A, %entry ], [ %ptr.next, %loop ]
160  %gep.B = getelementptr inbounds ptr, ptr %B, i64 %iv
161  %ptr.next = load ptr, ptr %gep.B, align 8, !tbaa !6
162  %l = load i32, ptr %ptr.recur, align 4
163  %xor = xor i32 %l, 1
164  %gep.C = getelementptr inbounds ptr, ptr %C, i64 %iv
165  store i32 %xor, ptr %gep.C, align 4
166  %iv.next = add nuw nsw i64 %iv, 1
167  %ec = icmp eq i64 %iv.next, 5
168  br i1 %ec, label %exit, label %loop
169
170exit:
171  ret void
172}
173
174
175!6 = !{!7, !7, i64 0}
176!7 = !{!"any pointer", !8, i64 0}
177!8 = !{!"omnipotent char", !9, i64 0}
178!9 = !{!"Simple C/C++ TBAA"}
179!10 = !{!11, !11, i64 0}
180!11 = !{!"int", !8, i64 0}
181