constexpr with builtin

classic Classic list List threaded Threaded
9 messages Options
fil
Reply | Threaded
Open this post in threaded view
|

constexpr with builtin

fil
CLANG 3.2, just wondering if anyone can explain:

inline constexpr uint8_t test(uint64_t value)
{
        return value == 0 ? 0: __builtin_clzll(value);
}

Result: Constexpr function never produces a constant expression

While this compiles fine:

inline constexpr uint8_t test(uint64_t value)
{
        return value == value ? __builtin_clzll(value) : 0;
}

Any ideas?
fil
Reply | Threaded
Open this post in threaded view
|

Re: constexpr with builtin

fil
Apologies, this is the code block that does not compile:

inline constexpr uint8_t test(uint64_t value)
{
        return __builtin_clzll(value);
}
Reply | Threaded
Open this post in threaded view
|

Re: constexpr with builtin

Sebastian Redl

On 09.09.2013, at 15:13, fil wrote:

> Apologies, this is the code block that does not compile:
>
> inline constexpr uint8_t test(uint64_t value)
> {
> return __builtin_clzll(value);
> }

I believe the simple test that makes the code above not compile does not evaluate potential results of conditional expressions: only one branch needs to be a constant expression, and the test does not reason about "value == value" always taking one branch. So the version with the tautological test will compile by itself, but you'll never be able to use it in a constexpr context, versus the simple function above is recognized as not being constexpr.

Making built-in functions with simple arithmetic meanings constexpr is a different issue.

Sebastian
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
fil
Reply | Threaded
Open this post in threaded view
|

Re: constexpr with builtin

fil
Sebastian Redl wrote
I believe the simple test that makes the code above not compile does not evaluate potential results of conditional expressions: only one branch needs to be a constant expression, and the test does not reason about "value == value" always taking one branch. So the version with the tautological test will compile by itself, but you'll never be able to use it in a constexpr context, versus the simple function above is recognized as not being constexpr.

Making built-in functions with simple arithmetic meanings constexpr is a different issue.
Thanks for the reply. Two questions:

1. know of a way to use builtin functions (like clz) in a constexpr context? I am figuring I need to re-implement it, no way to use the CPU instruction at compile time (?)
2. why does a branch allow it to be compiled? I would have thought that the compiler would inspect both branches and insist they both be a const friendly.

So, I should expect the branched version compile to fail if I actually use it in a constexpr context? Should have tried that..

Regards, Fil.
Reply | Threaded
Open this post in threaded view
|

Re: constexpr with builtin

Richard Smith
On Mon, Sep 9, 2013 at 7:20 PM, fil <[hidden email]> wrote:
Sebastian Redl wrote
> I believe the simple test that makes the code above not compile does not
> evaluate potential results of conditional expressions: only one branch
> needs to be a constant expression, and the test does not reason about
> "value == value" always taking one branch. So the version with the
> tautological test will compile by itself, but you'll never be able to use
> it in a constexpr context, versus the simple function above is recognized
> as not being constexpr.
>
> Making built-in functions with simple arithmetic meanings constexpr is a
> different issue.

Thanks for the reply. Two questions:

1. know of a way to use builtin functions (like clz) in a constexpr context?
I am figuring I need to re-implement it, no way to use the CPU instruction
at compile time (?)

__builtin_clz works in constant expressions in recent Clang revisions. You only need to upgrade =)

2. why does a branch allow it to be compiled? I would have thought that the
compiler would inspect both branches and insist they both be a const
friendly.

The compiler does inspect both branches, but it only insists that *one* of them is constexpr-friendly. It's valid for a ?: to select between a potentially-constant expression and a never-constant expression within a constexpr function.

So, I should expect the branched version compile to fail if I actually use
it in a constexpr context?

Yes.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
fil
Reply | Threaded
Open this post in threaded view
|

Re: constexpr with builtin

fil
Richard Smith wrote
> 1. know of a way to use builtin functions (like clz) in a constexpr
> context?
> I am figuring I need to re-implement it, no way to use the CPU instruction
> at compile time (?)
>

__builtin_clz works in constant expressions in recent Clang revisions. You
only need to upgrade =)
Right.. good to know. Did this change come in 3.3 or very latest SVN?

Richard Smith wrote
2. why does a branch allow it to be compiled? I would have thought that the
> compiler would inspect both branches and insist they both be a const
> friendly.

The compiler does inspect both branches, but it only insists that *one* of
them is constexpr-friendly. It's valid for a ?: to select between a
potentially-constant expression and a never-constant expression within a
constexpr function.
Gotcha. I expected it to be a bit more draconian on guaranteeing constexpr in all branches. Thx for the follow up.

Regards, Fil.
Reply | Threaded
Open this post in threaded view
|

Re: constexpr with builtin

Richard Smith


On 9 Sep 2013 20:40, "fil" <[hidden email]> wrote:
>
> Richard Smith wrote
> >> 1. know of a way to use builtin functions (like clz) in a constexpr
> >> context?
> >> I am figuring I need to re-implement it, no way to use the CPU
> >> instruction
> >> at compile time (?)
> >>
> >
> > __builtin_clz works in constant expressions in recent Clang revisions. You
> > only need to upgrade =)
>
> Right.. good to know. Did this change come in 3.3 or very latest SVN?

Sorry, I don't remember. Maybe someone with 3.3 can test this for you. I think it was more recently than that, though.

> Richard Smith wrote
> > 2. why does a branch allow it to be compiled? I would have thought that
> > the
> >> compiler would inspect both branches and insist they both be a const
> >> friendly.
> >
> > The compiler does inspect both branches, but it only insists that *one* of
> > them is constexpr-friendly. It's valid for a ?: to select between a
> > potentially-constant expression and a never-constant expression within a
> > constexpr function.
>
> Gotcha. I expected it to be a bit more draconian on guaranteeing constexpr
> in all branches. Thx for the follow up.
>
> Regards, Fil.
>
>
>
>
> --
> View this message in context: http://clang-developers.42468.n3.nabble.com/constexpr-with-builtin-tp4034336p4034358.html
> Sent from the Clang Developers mailing list archive at Nabble.com.
> _______________________________________________
> cfe-dev mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: constexpr with builtin

Justin Bogner
In reply to this post by fil
fil <[hidden email]> writes:
>> __builtin_clz works in constant expressions in recent Clang
>> revisions. You only need to upgrade =)
>
> Right.. good to know. Did this change come in 3.3 or very latest SVN?
>

This needs SVN. The change was made shortly after the 3.3 release.
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
fil
Reply | Threaded
Open this post in threaded view
|

Re: constexpr with builtin

fil
Hi Justin,

Justin Bogner wrote
This needs SVN. The change was made shortly after the 3.3 release.
Thanks for the clarification. I found it worked exactly as described - now running on the SVN latest. Looking forward to the 3.4 release.. :)