[PATCH] D51207: Introduce llvm.experimental.widenable_condition intrinsic

Sanjoy Das via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 10 14:37:32 PDT 2018


sanjoy added inline comments.


================
Comment at: docs/LangRef.rst:15097-15099
+defined as follows: as long as the block `deopt` only contains the
+call to ``@llvm.experimental.deoptimize`` and instructions without
+side effects, it is valid to replace
----------------
apilipenko wrote:
> mkazantsev wrote:
> > apilipenko wrote:
> > > Why do you need this limitation?
> > As stated above, we want these two constructions do exactly the same thing:
> > 
> >    ; Unguarded instructions
> >     call void @llvm.experimental.guard(i1 %cond, <args...>) ["deopt"(<deopt_args...>)]
> >     ; Guarded instructions
> > 
> > and
> > 
> >   block:
> >     ; Unguarded instructions
> >     %widenable_condition = call i1 @llvm.experimental.widenable.condition()
> >     %new_condition = and i1 %cond, %widenable_condition
> >     br i1 %new_condition, label %guarded, label %deopt
> > 
> >   guarded:
> >     ; Guarded instructions
> > 
> >   deopt:
> >     call type @llvm.experimental.deoptimize(<args...>) [ "deopt"(<deopt_args...>) ]
> > 
> > If there is something side-effecting before deoptimization in `deopt` block, these two constructions are obviously not equivalent.
> > 
> Sorry, I don't quite follow you. *These two* constructions are exactly the same. widenable condition representation just enables more flexibility and you can have some extra code before deoptimization. So with widenable condition representation you can express more than what you could do with old guards.
> 
> I don't think that there are correctness or profitability reasons to impose this limitation.
I agree with Artur here; `@llvm.experimental.widenable.condition` is technically an independent concept from `@llvm.experimental.deoptimize` though of course it is heavily inspired by it.

For instance with `@llvm.experimental.widenable.condition` you could do things like:

```
int f(int x) {
  if (@llvm.experimental.widenable.condition()) {
    return faster_to_execute(x);
  } else {
    return easier_to_constant_fold(x);
  }
}
```

and later fold `@llvm.experimental.widenable.condition()` to `false` or `true` depending on whether `f` was inlined into a call site where `x` is a compile time constant or not.


We should also not spec  `@llvm.experimental.widenable.condition()` as returning `undef` since `undef` is problematic.  Instead we should say each call of `@llvm.experimental.widenable.condition()` non-deterministically returns `true` or `false` but the returned value is a normal `i1` and does not have magic properties like `undef`.


https://reviews.llvm.org/D51207





More information about the llvm-commits mailing list