New issue
Advanced search Search tips

Issue 829143 link

Starred by 1 user

Issue metadata

Status: Untriaged
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Chrome
Pri: 3
Type: Bug
Build-Toolchain



Sign in to add a comment

clang: __builtin_constant_p() not effective for inline function parameters

Project Member Reported by mka@chromium.org, Apr 4 2018

Issue description

When used on a parameter of an inline function __builtin_constant_p() always returns 0, even when the parameters is a constant literal. This differs from gcc and leads to sub-optimal code.

This has been brought up as a problem on the kernel mailing list: https://lkml.org/lkml/2018/4/4/777

Example:

#include <stdio.h>

static int is_const(int val) {
        return __builtin_constant_p(val);
}

int main(int argc, char *argv[])
{
        const int var = 456;

        printf("literal: %d\n", __builtin_constant_p(123));
        printf("const var: %d\n", __builtin_constant_p(var));
        printf("literal+inline: %d\n", is_const(123));
        printf("const var+inline: %d\n", is_const(var));

        return 0;
}


gcc (with -O2):

literal: 1
const var: 1
literal+inline: 1
const var+inline: 1


clang (with -O2):

literal: 1
const var: 1
literal+inline: 0
const var+inline: 0

 
tl;dr WAI since Clang's implementation differs from GCC.
Also note that GCC cannot do it either at -O0.

We faced this problem before (https://bugs.chromium.org/p/chromium/issues/detail?id=770889#c7 )

For reference, I had asked Richard Smith about it and here is his answer:

On 3 Oct 2017 11:02, "Manoj Gupta" <manojgupta@google.com> wrote:
Hi Richard,

This is Manoj from ChromeOS toolchain team. I have been asked for a Linux kernel build issue that arises due to use of __builtin_constant_p. (https://bugs.chromium.org/p/chromium/issues/detail?id=770889 has the details)

The root cause is gcc can analyze the builtin when used in an lined function while clang does not.
gcc spec for this builtin do add legitimacy to use this builtin in inlined function calls with -O.
https://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Other-Builtins.html

"You may use this built-in function in either a macro or an inline function. However, if you use it in an inlined function and pass an argument of the function as the argument to the built-in, GCC never returns 1 when you call the inline function with a string constant or compound literal (see Compound Literals) and does not return 1 when you pass a constant numeric value to the inline function unless you specify the -O option."

Do you think it is worth to improve clang's handling of this builtin?

Not especially. GCC's behaviour exposes an implementation detail that clang does not share, and provides a fundamentally fragile coding model that depends on the whims of the optimiser for correctness. Clang provides an alternative mechanism that does not suffer from these problems (the enable_if attribute) for this purpose; we generally encourage its use instead.

Comment 2 by mka@chromium.org, Apr 5 2018

Labels: -Pri-2 Pri-3
Lowering to P3 since Linus Torvalds sees it as an optimization good to have in the long-term, but not a must in the near future (https://lkml.org/lkml/2018/4/4/895)

Sign in to add a comment