llvm.org GIT mirror llvm / ec761ad
[JumpThreading] Dont RAUW condition incorrectly Summary: We have a bug when RAUWing the condition if experimental.guard or assumes is a use of that condition. This is because LazyValueInfo may have used the guards/assumes to identify the value of the condition at the end of the block. RAUW replaces the uses at the guard/assume as well as uses before the guard/assume. Both of these are incorrect. For now, disable RAUW for conditions and fix the logic as a next step: https://reviews.llvm.org/D33257 Reviewers: sanjoy, reames, trentxintong Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D33279 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303349 91177308-0d34-0410-b5e6-96231b3b80d8 Anna Thomas 2 years ago
4 changed file(s) with 154 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
832832 CondBr->eraseFromParent();
833833 if (CondCmp->use_empty())
834834 CondCmp->eraseFromParent();
835 else if (CondCmp->getParent() == BB) {
836 // If the fact we just learned is true for all uses of the
837 // condition, replace it with a constant value
838 auto *CI = Ret == LazyValueInfo::True ?
839 ConstantInt::getTrue(CondCmp->getType()) :
840 ConstantInt::getFalse(CondCmp->getType());
841 CondCmp->replaceAllUsesWith(CI);
842 CondCmp->eraseFromParent();
843 }
835 // TODO: We can safely replace *some* uses of the CondInst if it has
836 // exactly one value as returned by LVI. RAUW is incorrect in the
837 // presence of guards and assumes, that have the `Cond` as the use. This
838 // is because we use the guards/assume to reason about the `Cond` value
839 // at the end of block, but RAUW unconditionally replaces all uses
840 // including the guards/assumes themselves and the uses before the
841 // guard/assume.
844842 return true;
845843 }
846844
13261324 if (auto *CondInst = dyn_cast(Cond)) {
13271325 if (CondInst->use_empty() && !CondInst->mayHaveSideEffects())
13281326 CondInst->eraseFromParent();
1329 else if (OnlyVal && OnlyVal != MultipleVal &&
1330 CondInst->getParent() == BB) {
1331 // If we just learned Cond is the same value for all uses of the
1332 // condition, replace it with a constant value
1333 CondInst->replaceAllUsesWith(OnlyVal);
1334 if (!CondInst->mayHaveSideEffects())
1335 CondInst->eraseFromParent();
1336 }
1327 // TODO: We can safely replace *some* uses of the CondInst if it has
1328 // exactly one value as returned by LVI. RAUW is incorrect in the
1329 // presence of guards and assumes, that have the `Cond` as the use. This
1330 // is because we use the guards/assume to reason about the `Cond` value
1331 // at the end of block, but RAUW unconditionally replaces all uses
1332 // including the guards/assumes themselves and the uses before the
1333 // guard/assume.
13371334 }
13381335 return true;
13391336 }
5555 ret i32 %retval.0
5656 }
5757
58 @g = external global i32
59
60 ; Check that we do prove a fact using an assume within the block.
61 ; FIXME: We can fold the assume based on the semantics of assume.
62 ; CHECK-LABEL: @can_fold_assume
63 ; CHECK: %notnull = icmp ne i32* %array, null
64 ; CHECK-NEXT: call void @llvm.assume(i1 %notnull)
65 ; CHECK-NEXT: ret void
66 define void @can_fold_assume(i32* %array) {
67 %notnull = icmp ne i32* %array, null
68 call void @llvm.assume(i1 %notnull)
69 br i1 %notnull, label %normal, label %error
70
71 normal:
72 ret void
73
74 error:
75 store atomic i32 0, i32* @g unordered, align 4
76 ret void
77 }
78
79 declare void @f(i1)
80 declare void @exit()
81 ; We can fold the assume but not the uses before the assume.
82 define void @dont_fold_incorrectly(i32* %array) {
83 ; CHECK-LABEL:@dont_fold_incorrectly
84 ; CHECK: @f(i1 %notnull)
85 ; CHECK-NEXT: exit()
86 ; CHECK-NEXT: assume(i1 %notnull)
87 ; CHECK-NEXT: ret void
88 %notnull = icmp ne i32* %array, null
89 call void @f(i1 %notnull)
90 call void @exit()
91 call void @llvm.assume(i1 %notnull)
92 br i1 %notnull, label %normal, label %error
93
94 normal:
95 ret void
96
97 error:
98 store atomic i32 0, i32* @g unordered, align 4
99 ret void
100 }
101
58102 ; Function Attrs: nounwind
59103 declare void @llvm.assume(i1) #1
60104
132132 ret void
133133 }
134134
135 ; Make sure we can do the RAUW for %add...
135 ; FIXME: Make sure we can do the RAUW for %add...
136136 ;
137137 ; CHECK-LABEL: @rauw_if_possible(
138 ; CHECK: call void @f4(i32 96)
138 ; CHECK: call void @f4(i32 %add)
139139 define void @rauw_if_possible(i32 %value) nounwind {
140140 entry:
141141 %cmp = icmp eq i32 %value, 32
180180 ; CHECK-NEXT: ret void
181181 ret void
182182 }
183
184 declare void @never_called()
185
186 ; Assume the guard is always taken and we deoptimize, so we never reach the
187 ; branch below that guard. We should *never* change the behaviour of a guard from
188 ; `must deoptimize` to `may deoptimize`, since this affects the program
189 ; semantics.
190 define void @dont_fold_guard(i8* %addr, i32 %i, i32 %length) {
191 ; CHECK-LABEL: dont_fold_guard
192 ; CHECK: experimental.guard(i1 %wide.chk)
193
194 entry:
195 br label %BBPred
196
197 BBPred:
198 %cond = icmp eq i8* %addr, null
199 br i1 %cond, label %zero, label %not_zero
200
201 zero:
202 unreachable
203
204 not_zero:
205 %c1 = icmp ult i32 %i, %length
206 %c2 = icmp eq i32 %i, 0
207 %wide.chk = and i1 %c1, %c2
208 call void(i1, ...) @llvm.experimental.guard(i1 %wide.chk) [ "deopt"() ]
209 br i1 %c2, label %unreachedBB2, label %unreachedBB1
210
211 unreachedBB2:
212 call void @never_called()
213 ret void
214
215 unreachedBB1:
216 ret void
217 }
218
219
220 ; same as dont_fold_guard1 but condition %cmp is not an instruction.
221 ; We cannot fold the guard under any circumstance.
222 ; FIXME: We can merge unreachableBB2 into not_zero.
223 define void @dont_fold_guard2(i8* %addr, i1 %cmp, i32 %i, i32 %length) {
224 ; CHECK-LABEL: dont_fold_guard2
225 ; CHECK: guard(i1 %cmp)
226
227 entry:
228 br label %BBPred
229
230 BBPred:
231 %cond = icmp eq i8* %addr, null
232 br i1 %cond, label %zero, label %not_zero
233
234 zero:
235 unreachable
236
237 not_zero:
238 call void(i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
239 br i1 %cmp, label %unreachedBB2, label %unreachedBB1
240
241 unreachedBB2:
242 call void @never_called()
243 ret void
244
245 unreachedBB1:
246 ret void
247 }
248
249 ; Same as dont_fold_guard1 but use switch instead of branch.
250 ; triggers source code `ProcessThreadableEdges`.
251 declare void @f(i1)
252 define void @dont_fold_guard3(i1 %cmp1, i32 %i) nounwind {
253 ; CHECK-LABEL: dont_fold_guard3
254 ; CHECK-LABEL: L2:
255 ; CHECK-NEXT: %cmp = icmp eq i32 %i, 0
256 ; CHECK-NEXT: guard(i1 %cmp)
257 ; CHECK-NEXT: @f(i1 %cmp)
258 ; CHECK-NEXT: ret void
259 entry:
260 br i1 %cmp1, label %L0, label %L3
261 L0:
262 %cmp = icmp eq i32 %i, 0
263 call void(i1, ...) @llvm.experimental.guard(i1 %cmp) [ "deopt"() ]
264 switch i1 %cmp, label %L3 [
265 i1 false, label %L1
266 i1 true, label %L2
267 ]
268
269 L1:
270 ret void
271 L2:
272 call void @f(i1 %cmp)
273 ret void
274 L3:
275 ret void
276 }