@@ -56,6 +56,125 @@ loop:
5656 %ec = icmp eq i64 %i.inc , 100
5757 br i1 %ec , label %exit , label %loop
5858
59+ exit:
60+ ret void
61+ }
62+
63+ ; max_i = INT64_MAX/6 // 1537228672809129301
64+ ; for (long long i = 0; i <= max_i; i++) {
65+ ; A[-6*i + INT64_MAX] = 0;
66+ ; if (i)
67+ ; A[3*i - 2] = 1;
68+ ; }
69+ ;
70+ ; FIXME: DependenceAnalysis currently detects no dependency between the two
71+ ; stores, but it does exist. For example,
72+ ;
73+ ; memory access | i == 1 | i == (max_i + 1) / 2 | i == max_i
74+ ; ---------------------|--------|----------------------|-------------------
75+ ; A[-6*i + INT64_MAX] | | A[3*max_i - 2] | A[1]
76+ ; A[3*i - 2] | A[1] | | A[3*max_i - 2]
77+ ;
78+ ;
79+ define void @gcdmiv_delta_ovfl (ptr %A ) {
80+ ; CHECK-ALL-LABEL: 'gcdmiv_delta_ovfl'
81+ ; CHECK-ALL-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 0, ptr %idx.0, align 1
82+ ; CHECK-ALL-NEXT: da analyze - none!
83+ ; CHECK-ALL-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
84+ ; CHECK-ALL-NEXT: da analyze - none!
85+ ; CHECK-ALL-NEXT: Src: store i8 1, ptr %idx.1, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
86+ ; CHECK-ALL-NEXT: da analyze - none!
87+ ;
88+ ; CHECK-GCD-MIV-LABEL: 'gcdmiv_delta_ovfl'
89+ ; CHECK-GCD-MIV-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 0, ptr %idx.0, align 1
90+ ; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*]!
91+ ; CHECK-GCD-MIV-NEXT: Src: store i8 0, ptr %idx.0, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
92+ ; CHECK-GCD-MIV-NEXT: da analyze - none!
93+ ; CHECK-GCD-MIV-NEXT: Src: store i8 1, ptr %idx.1, align 1 --> Dst: store i8 1, ptr %idx.1, align 1
94+ ; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*]!
95+ ;
96+ entry:
97+ br label %loop.header
98+
99+ loop.header:
100+ %i = phi i64 [ 0 , %entry ], [ %i.inc , %loop.latch ]
101+ %subscript.0 = phi i64 [ 9223372036854775807 , %entry ], [ %subscript.0.next , %loop.latch ]
102+ %subscript.1 = phi i64 [ -2 , %entry ], [ %subscript.1.next , %loop.latch ]
103+ %idx.0 = getelementptr inbounds i8 , ptr %A , i64 %subscript.0
104+ store i8 0 , ptr %idx.0
105+ %cond.store = icmp ne i64 %i , 0
106+ br i1 %cond.store , label %if.store , label %loop.latch
107+
108+ if.store:
109+ %idx.1 = getelementptr i8 , ptr %A , i64 %subscript.1
110+ store i8 1 , ptr %idx.1
111+ br label %loop.latch
112+
113+ loop.latch:
114+ %i.inc = add nuw nsw i64 %i , 1
115+ %subscript.0.next = add nsw i64 %subscript.0 , -6
116+ %subscript.1.next = add nsw i64 %subscript.1 , 3
117+ %exitcond = icmp sgt i64 %i.inc , 1537228672809129301
118+ br i1 %exitcond , label %exit , label %loop.header
119+
120+ exit:
121+ ret void
122+ }
123+
124+ ; max_i = INT64_MAX/3 // 3074457345618258602
125+ ; for (i = 0; i < max_i; i++) {
126+ ; A[3*i] = 0;
127+ ; A[-3*i - 3*m - INT64_MAX] = 1;
128+ ; }
129+ ;
130+ ; FIXME: DependenceAnalysis currently detects no dependency between the two
131+ ; stores, but it may exist. For example, consider `m = 1`. Then,
132+ ; `-3*m - INT64_MAX` is `INT64_MAX - 1`. So `-3*i - 3*m - INT64_MAX` is
133+ ; effectively `-3*i + (INT64_MAX - 1)`. Thus, accesses will be as follows:
134+ ;
135+ ; memory access | i == 1 | i == max_i - 1
136+ ; ---------------------------|------------------|------------------
137+ ; A[3*i] | A[3] | A[INT64_MAX - 4]
138+ ; A[-3*i - 3*m - INT64_MAX] | A[INT64_MAX - 4] | A[3]
139+ ;
140+
141+ define void @gcdmiv_const_ovfl (ptr %A , i64 %m ) {
142+ ; CHECK-ALL-LABEL: 'gcdmiv_const_ovfl'
143+ ; CHECK-ALL-NEXT: Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 0, ptr %gep.0, align 1
144+ ; CHECK-ALL-NEXT: da analyze - none!
145+ ; CHECK-ALL-NEXT: Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
146+ ; CHECK-ALL-NEXT: da analyze - none!
147+ ; CHECK-ALL-NEXT: Src: store i8 1, ptr %gep.1, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
148+ ; CHECK-ALL-NEXT: da analyze - none!
149+ ;
150+ ; CHECK-GCD-MIV-LABEL: 'gcdmiv_const_ovfl'
151+ ; CHECK-GCD-MIV-NEXT: Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 0, ptr %gep.0, align 1
152+ ; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*]!
153+ ; CHECK-GCD-MIV-NEXT: Src: store i8 0, ptr %gep.0, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
154+ ; CHECK-GCD-MIV-NEXT: da analyze - none!
155+ ; CHECK-GCD-MIV-NEXT: Src: store i8 1, ptr %gep.1, align 1 --> Dst: store i8 1, ptr %gep.1, align 1
156+ ; CHECK-GCD-MIV-NEXT: da analyze - consistent output [*]!
157+ ;
158+ entry:
159+ %m.3 = mul nsw i64 -3 , %m
160+ %const = sub i64 %m.3 , 9223372036854775807
161+ %guard = icmp ne i64 %const , 0
162+ br i1 %guard , label %loop , label %exit
163+
164+ loop:
165+ %i = phi i64 [ 0 , %entry ], [ %i.inc , %loop ]
166+ %offset.0 = phi i64 [ 0 , %entry ], [ %offset.0.next , %loop ]
167+ %offset.1 = phi i64 [ %const , %entry ], [ %offset.1.next , %loop ]
168+ %gep.0 = getelementptr inbounds i8 , ptr %A , i64 %offset.0
169+ %gep.1 = getelementptr inbounds i8 , ptr %A , i64 %offset.1
170+ store i8 0 , ptr %gep.0
171+ store i8 1 , ptr %gep.1
172+ %i.inc = add nuw nsw i64 %i , 1
173+ %offset.0.next = add nsw i64 %offset.0 , 3
174+ %offset.1.next = add nsw i64 %offset.1 , -3
175+ %ec = icmp eq i64 %i.inc , 3074457345618258602
176+ br i1 %ec , label %exit , label %loop
177+
59178exit:
60179 ret void
61180}
0 commit comments