[PATCH] D33257: [JumpThreading] Dont RAUW condition if guards in block
Anna Thomas via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed May 17 15:53:29 PDT 2017
anna added inline comments.
================
Comment at: lib/Transforms/Scalar/JumpThreading.cpp:266
+ Intrinsic::getName(Intrinsic::experimental_guard));
+ if (GuardDecl && !GuardDecl->use_empty()) {
+ // Traversing the uses requires checking for `Cond` being used directly in
----------------
sanjoy wrote:
> I don't think this is specific to guards. For instance, if you have:
>
> ```
> bb:
> cond = icmp ...;
> print(cond);
> exit();
> assume(cond);
> br cond;
> ```
>
> You can't simplify the `cond` in `print(cond)` to `print(true)`. I think there are similar issues with `isObjectDereferencedInBlock`.
>
> I'd instead phrase this problem as:
>
> We know that at the end of a basic block, a certain condition, `cond`, is true. The question from what point onwards did that condition become true. To do that, I suggest walking backwards from the branch, and stopping when you find an instruction for which `isGuaranteedToTransferExecutionToSuccessor` returns false. All the instructions you enumerate this way can be `replaceUsesOfWith(cond, true)` 'ed. This approach will miss some cases though, like in:
>
> ```
> bb:
> cond = icmp ...;
> print(cond);
> cond' = or cond, something_else
> exit();
> use(cond')
> assume(cond);
> br cond;
> ```
>
> we won't simplify `cond'`. If needed, we can come up with a more aggressive substitution scheme to get those cases.
>
Sanjoy's phrasing is a bit different from this phrasing: do not fold guards and assumes and uses before the guards and assumes.
Specifically these 2 examples showcase the differences:
1. Using `isGuaranteedToTransferExecutionToSuccessor`, we will be folding assumes. Folding to true is okay, based on lang ref semantics of `assume`. Also, I think there cannot be a case of folding to `assume(false)`, based on how LVI calculates values.
```
bb:
cond = icmp ...;
print(cond); <-- can fold this, and we do so.
assume(cond); <-- can fold this, and we do so.
br cond;
```
If there was an exit() between print and assume, we cannot fold the `print`.
2. In this test case below, we unfortunately do not fold either uses because exit is a throwing call, and `isGuaranteedToTransferExecutionToSuccessor` won't allow to fold.
```
bb:
cond = icmp ...
assume(cond) <-- can fold this, but not able to.
print(cond) <-- can fold this, but not able to.
exit() <-- throws
br cond
```
I think either phrasing has it's pros and cons, but both are conservatively correct. Thoughts?
https://reviews.llvm.org/D33257
More information about the llvm-commits
mailing list