[PATCH] D54966: Implement P1007R3 `std::assume_aligned`

Hal Finkel via Phabricator reviews at reviews.llvm.org
Tue Dec 4 15:34:08 PST 2018

hfinkel added a comment.

In D54966#1319368 <https://reviews.llvm.org/D54966#1319368>, @rsmith wrote:

> In D54966#1317750 <https://reviews.llvm.org/D54966#1317750>, @hfinkel wrote:
> > In D54966#1317428 <https://reviews.llvm.org/D54966#1317428>, @rsmith wrote:
> >
> > > @chandlerc, @hfinkel: does an attribute-only implementation (with no constant evaluation enforcement) materially hurt the ability for the optimizer to use this annotation? Eg, in:
> > >
> > >   extern char k[16];
> > >   void f() {
> > >     // the initializer of p is a constant expression and might get constant-folded to &k by the frontend
> > >     char *p = std::assume_aligned<16>(&k);
> > >     // ...do stuff...
> > >   }
> > >
> > >
> > > the alignment assumption may well never be emitted as IR. Is that acceptable?
> >
> >
> > `__attribute__((assume_aligned(N)))` and `__builtin_assume_aligned` are, at the IR level, implemented in a very-similar way. For functions with that attribute on the return type, we essentially emit an alignment assumption on the return value at every call site (in CodeGenFunction::EmitCall). Thus, from the optimizer's perspective, I don't think that it makes a big difference.
> The point here is that you may well get //no IR annotation whatsoever// for the above call, because the frontend might constant-evaluate the initializer of `p` down to just `&k`, and then emit IR that just initializes `p` to `&k` with no alignment assumption. Whereas if we treated `assume_aligned<N>(p)` as non-constant in the cases where we cannot prove that `p` is suitably aligned (as `__builtin_assume_aligned` does), then we would emit IR for the alignment assumption, but the downside is that the initializer of `p` would no longer be a constant expression.
> Essentially, what I'm trying to gauge here is, is it OK that you probably don't actually get an alignment assumption in a function like the `f()` above, because it will probably be constant-evaluated away to nothing? Or do we need the constant evaluator to have some kind of side-channel by which it can communicate back to the code generator that an alignment assumption should be applied to `k`?

I thought about this side channel option for k, but I don't think that we can because we'd need to prove that `f()` function was always executed, and that's likely not generally possible. I think that the side channel would apply only to p.

> Or, indeed, should `assume_aligned<N>(p)` not be treated as a constant expression unless we can prove during constant expression evaluation that `p` is in fact suitably aligned -- as GCC and Clang currently do for `__builtin_assume_aligned`?

>From a C++ perspective, this seems suboptimal. I don't want people to duplicate code, some with assume_aligned, some without, if I want the same code with work both in a constexpr and not. A side channel would be better. It is a trade off, however, and I'd need to think more about it.



More information about the libcxx-commits mailing list