On Mon, Oct 20, 2025 at 2:12 PM Matthias Kretz <[email protected]> wrote:

> Tomasz Kaminski [Monday, 20 October 2025, 10:47:12 CEST]:
> > I think this is something worth discussing on the usual list channel, so
> > people not looking
> > at forge will also get notice, so posting in here:
> >
> > In the patch, there is a lot of code that looks like this:
> > if (__builtin_is_constant_evaluated() || (__builtin_constant_p(__arg0) &&
> > __builtin_constant_p(__arg1))
> > {
> >    // some compile-time compatible coded
> > }
> > else
> > {
> >    // optimized version
> > }
>
> To explain the "why": If a function is implemented using a target-specific
> builtin and that builtin's operation is not understood by the optimizer,
> then
> such a call acts as an optimization barrier (very similar to using inline
> asm). If we could resolve that, I'd happily delete all my const-prop
> branches.
>
> I guess you could also say that I should file a lot of missed optimization
> PRs. I didn't, because I'm unsure whether that's the best use of
> everyone's
> time in these cases. I do report missed optimizations when I think it's
> worthwhile. To me there's quite a list of important issues I'm waiting on
> before I feel like I should report more. But please feel free to disagree.
>
> > The __builtin_is_constant_evaluated part is uncontroversial, as we are
> > guaranteed that the code
> > will get folded at compile time, and never be evaluated at runtime.
>
> It's typically also necessary since the code in the else branch cannot be
> called in a constant expression.
>
> > However, we assume that if the
> > arg0 and arg1 are building constant, the compiler will constant fold the
> > code. But it is not required to
> > do so. I believe that you have verified that this is the case on most
> > common optimization level, but
> > I think this may lead to surprises for users, for example on debug
> builds.
>
> On -O0 builds __builtin_constant_p(whatever) is unconditionally false,
> AFAIK.
> And yes, my main workflow is to verify asm output (while having unit test
> compiling in the background).

That touches with my major concern, the user will be debugining (with
optimization disabled) a different code than one that will be used by
optimized
builds, and was having an issue.
That's why I prefer to have this localized in one place.

>


> There is another pattern:
>
> if (__builtin_is_constant_evaluated())
>   // #1
> else
>   {
>      if (__builtin_constant_p(x))
>        {
>           _ReturnType __r = ...; // #2
>           if (__builtin_constant_p(__r)) // #2a
>             return __r;
>        }
>      // #3
>   }
>
> #1 makes it work in constant expressions
> #2 allows the optimizer to understand and optimize / constant-fold
> #3 uses target builtins
>
> However, in this pattern, if #2a fails then constant-folding didn't work
> as
> expected and the branch becomes dead code. Only #3 remains.
>
> This pattern only works if we expect complete constant-folding of the
> operation. In some cases, e.g. 'x / 2', __builtin_constant_p of the result
> cannot be true (unless __builtin_constant_p(x) is also true). But a shift
> by 1
> needs to be preferred over a conversion to double -> 2x divpd ->
> conversion to
> int. (For the division case there's PR90993.)
>
> > This also does not scale well for-used defined types.
>
> You mean, once simd::vec<UDT> gets voted into C++? I don't see a problem
> from
> what that paper is proposing.
>
> > However, I also do not want to simply ask you
> > to drop this functionality, so what I suggest instead is to introduce:
> >
> > template<typename... _Args>
> > [[__gnu__::__always_inline__]]
> > constexpr __should_constprop(const _Args&... __args)
> > {
> >    if conteval { // of if (__builtin_is_constant_evaluated())
> >      return true;
> >   }
> >  return __is_constprop(__args) && ...;
> > }
>
> I can try.
>
> In general, I am afraid of instantiating more templates in the simd
> implementation because I'm constantly fighting with my unit tests blowing
> out
> of any reasonable space and time usage.
>
> > The _M_isconstprop member on simd, should become __is_constprop hidden
> > friend.
>
> Sounds good.
>
> > […]
> > This would allow us to control the constant propagation from arguments in
> > one place, and disable it if it's found problematic.
>
> I believe we'd want to disable on a case by case basis. But I understand
> that
> my liberal use of __builtin_constant_p is novel for libstdc++ code and
> should
> be treated with care. (Except for std::experimental::simd)
>
> --
> ──────────────────────────────────────────────────────────────────────────
>  Dr. Matthias Kretz                           https://mattkretz.github.io
>  GSI Helmholtz Center for Heavy Ion Research               https://gsi.de
>  std::simd
> ──────────────────────────────────────────────────────────────────────────
>
>
>
>

Reply via email to