Adding Freeze instruction and fix loop unswitch
Nuno Lopes via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 23 04:15:21 PST 2017
Hi,
Following our talk at the LLVM dev meeting regarding poison, we would
like to introduce the freeze instruction in the LLVM IR so that we can
fix a longstanding bug in loop unswitch.
In the talk I mentioned a bigger proposal with several orthogonal
changes. We are now splitting that proposal in smaller pieces, and
this set of patches is the first piece. These pieces are independent
and can be reviewed independently.
Juneyoung Lee implemented the whole thing; I'm just the messenger.
A few details about the problem:
Loop unswitch does the following transformation:
while (...) {
if (C) { A }
else { B }
}
into:
if (C) {
while (...) { A }
} else {
while (...) { B }
}
This transformation is incorrect if C may be poison/undef, since
branching on poison/undef is UB. If, for example, the loop never
executed, the transformed code would be branching on C while the
original was not, and so we introduced UB (if C is undef/poison).
This has been shown to lead to end-to-end miscompilations when loop
unswitch is combined with other passes, like GVN:
- https://llvm.org/bugs/show_bug.cgi?id=27506
- https://llvm.org/bugs/show_bug.cgi?id=31652
We propose a simple change, which is to transform the code above into:
C' = freeze(c)
if (C') {
while (...) { A }
} else {
while (...) { B }
}
Freeze always returns a non-poison/undef value. When given a
poison/undef value, it returns a non-deterministic value that is fixed
for all uses.
We've split the changes in 5 patches:
- Add Freeze instruction to IR: https://reviews.llvm.org/D29011
- InstCombine/InstSimplify support for freeze:
https://reviews.llvm.org/D29013
- SelectionDAG support for freeze: https://reviews.llvm.org/D29014
- Fix wrong code emission by loop unswitch: https://reviews.llvm.org/D29015
- Optimize placement of freeze in loop unswitch:
https://reviews.llvm.org/D29016
Thanks,
Nuno
More information about the llvm-commits
mailing list