- Add llvm::SimplifyFreezeInst
- Add InstCombiner::visitFreeze
- Add llvm tests
Details
Diff Detail
Event Timeline
LGTM
include/llvm/Analysis/InstructionSimplify.h | ||
---|---|---|
286 | No need for the name in the comment. |
test/Transforms/InstCombine/freeze.ll | ||
---|---|---|
2 | Please consider using utils/update_test_checks.py |
LGTM.
p.s. Do you have a list of items for this work somewhere? We clearly need support in a number of passes, is there a master list so that we can split work once the IR def pass lands?
This needs both an instsimplify test and an instcombine test.
Other than that this seems conservatively correct.
Hi, sorry for the delay. I don't have master list, but possible places where freeze can be considered is as follows:
- The loopunswitch bug can be fixed with freeze. https://reviews.llvm.org/D29015 , https://reviews.llvm.org/D29016 , I'll update the patch today or tomorrow.
- select(c, bop(x,y), bop(x,z)) -> bop(x,(select(c,y,z)) is buggy if c is poison and bop is division because it generates division by poison. This can be resolved by freezing c. It is at InstCombiner::foldSelectOpOp of InstCombineSelect.cpp
- Check whether freeze was regarded as a zero-cost instruction when inlining
- Division hoisting
divisor = y | 1 // divisor is either non-zero or poison while (cond) { x = 100 / divisor // Hoisting this x may introduce UB, so y should be freezed in advance. use(x) }
Similar case is having if (divisor != 0) check surrounding the while loop. When divisor is undef (and if branching on undef is nondeterministic jump), hoisting the division is not explained. You can freeze the divisor.
- SelectionDAGBuilder::visitBr() tries to lower br i1 (and (icmp ...), (icmp ...)) into two separated branches, but it is blocked if one of the icmps is freezed. Adding transformations like freeze (icmp a, const) -> icmp (freeze a), const is helpful for this.
No need for the name in the comment.