[PATCH] D29378: [InstCombine] Allow InstCombine to merge adjacent guards
Max Kazantsev via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 1 08:09:11 PST 2017
mkazantsev added inline comments.
================
Comment at: lib/Transforms/InstCombine/InstCombineCalls.cpp:3269
+
+ // Otherwise we try to widen the next guard and remove the current.
+ Value *A, *B, *NewCond;
----------------
sanjoy wrote:
> There's a subtle problem here -- we can transform
>
> ```
> guard(a) [ "deopt"(X) ]
> guard(b) [ "deopt"(Y) ]
> ```
>
> to
>
> ```
> ;; Widen the first guard
> guard(a & b) [ "deopt"(X) ]
> ```
>
> but not to
>
> ```
> ;; Widen the second guard
> guard(a & b) [ "deopt"(Y) ]
> ```
>
> since the deopt state of the second guard (represented as `"Y"` here
> for simplicity) may have been optimized under the assumption that `a`
> is true.
>
> For instance, say we started with
>
> ```
> guard(a) [ "deopt"(a) ]
> guard(b) [ "deopt"(a) ]
> ```
>
> which first got optimized to
>
> ```
> guard(a) [ "deopt"(a) ]
> guard(b) [ "deopt"(true) ]
> ```
>
> and then due to this change is optimized to
>
> ```
> ;; guard(a) [ "deopt"(a) ]
> guard(a && b) [ "deopt"(true) ]
> ```
>
> Now if `a` is false at runtime then the expected behavior was to
> deoptimize with the deopt state `(a)` == `(false)`, but in the
> optimized program we will deoptimize with the deopt state `(true)`.
>
> The right transform here is to widen the first guard, not the second
> one.
>
Thanks for pointing that out: wasn't obvious indeed.
================
Comment at: lib/Transforms/InstCombine/InstCombineCalls.cpp:3273
+ match(NextCond, m_Not(m_Value(B))))
+ // Canonicalize guard(!a); guard(!b) -> guard(!(a | b)).
+ NewCond = Builder->CreateNot(Builder->CreateOr(A, B));
----------------
sanjoy wrote:
> I'd not bother with the `!a && !b` => `!(a && b)`. I think it is better to leave it as `!a && !b` (i.e. not special case `m_Not` at all), and have InstCombine re-canonicalize it (in a later iteration) to `!(a || b)` if that's more canonical.
Yeah, it is actually done by DeMorgan's Law transformation. :)
https://reviews.llvm.org/D29378
More information about the llvm-commits
mailing list