[Bug c/115095] New: [missed optimization] fixed processing on constant string

2024-05-14 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115095

Bug ID: 115095
   Summary: [missed optimization] fixed processing on constant
string
   Product: gcc
   Version: 15.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: yann at droneaud dot fr
  Target Milestone: ---

Created attachment 58208
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58208=edit
source code of https://godbolt.org/z/Meqvbj8GG

I've found clang was able to compute the result of hashing a constant string at
compile time. I would have hope GCC -O3 would be able to optimize such
computation as well:

static inline unsigned int hash(unsigned int h, const char *s)
{
while (*s) {
h += *s;
h *= *s++;
}

return h;
}

#define LOCATION() hash(hash(0, __FILE__), __func__)

unsigned int location(void)
{
return LOCATION();
}

is translated by clang to

location:
movl$1418535820, %eax
retq

but not by GCC, which doesn't compute the value of LOCATION() at compile time
but emit code that compute the value at runtime.

At first, I thought it was an issue with handling __FILE__ or __func__, but
trying with other string constants, GCC is not computing the value at compile
time.

See https://godbolt.org/z/Meqvbj8GG

[Bug c/111025] New: attribute((malloc)) and posix_memalign() (and other functions that return newly allocated object address into an output parameter)

2023-08-15 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111025

Bug ID: 111025
   Summary: attribute((malloc)) and posix_memalign() (and other
functions that return newly allocated object address
into an output parameter)
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: yann at droneaud dot fr
  Target Milestone: ---

Functions such as posix_memalign() don't return the pointer to the newly
allocated memory as their return value, thus attribute((malloc)) cannot be used
with them.

It would be useful to have some form of attribute((malloc)) that could apply to
function such as posix_memalign().

This new attribute((malloc)) form could also be used on asprintf() for example.

With support for the attribute((malloc))'s deallocator specification, it could
improve warnings at compile time and prevents developer mistake.

[Bug middle-end/110292] undefined value due to strict aliasing without warning

2023-06-16 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110292

--- Comment #5 from Yann Droneaud  ---
Hi,

Thanks a lot for the quick analysis of my issue.

(In reply to Andrew Pinski from comment #4)
> Note -Wstrict-aliasing=1 actually does warn:

OK, and -Wall enables -Wstrict-aliasing which defaults to -Wstrict-aliasing=3,
I'm sorry I haven't tried to use lower values ...

https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wstrict-aliasing

(In reply to Andrew Pinski from comment #2)
> aliasing violations are known not to be warned about nor have a runtime
> sanitizer either.

Is there any other tool that would reliably detect such issues ?

Regards

[Bug c/110292] undefined value due to strict aliasing without warning

2023-06-16 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110292

Yann Droneaud  changed:

   What|Removed |Added

 CC||yann at droneaud dot fr

--- Comment #1 from Yann Droneaud  ---
And it should be noted that using -fsanitize=undefined is making the issue
vanish as 0 is written into j location on the stack ...

[Bug c/110292] New: undefined value due to strict aliasing without warning

2023-06-16 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110292

Bug ID: 110292
   Summary: undefined value due to strict aliasing without warning
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: yann at droneaud dot fr
  Target Milestone: ---

The following code (reduced with some help from cvise) doesn't trigger any
warning from GCC 13+

$ cat test.c
#include 

struct a {
  uint8_t b:6;
};

struct c {
  uint64_t d:6;
};

void e(uint64_t *f, uint64_t *g) {
  struct c *h = (struct c *)f;
  struct a i[8] = { [7] = { h -> d } };
  __builtin___memcpy_chk (g, i, sizeof(i),
 __builtin_object_size (g, 0));
}

int main(void) {
  uint64_t j = 0;
  uint64_t k;
  e(, );
  if (k)
__builtin_trap();

  return 0;
}

But compiled under Fedora 39 (Rawhide, gcc 13.1.1-2, x86_64), it aborts,
because j location on the stack is not set to 0 before its address is being
passed to e() ... 

$ gcc -Wall -Wextra -O2 test.c -o test
$ ./test
Aborted (core dumped)

Even if it doesn't abort (because the stack is cleared), there's a problem and
valgrind reports:

$ gcc -Wall -Wextra -O2 -g3 test.c -o test
$ valgrind --track-origins=yes ./test 
==63110== Memcheck, a memory error detector
==63110== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==63110== Using Valgrind-3.21.0 and LibVEX; rerun with -h for copyright
info
==63110== Command: ./test
==63110== 
==63110== Conditional jump or move depends on uninitialised value(s)
==63110==at 0x401047: main (test.c:22)
==63110==  Uninitialised value was created by a stack allocation
==63110==at 0x401030: main (test.c:18)
   ...

And, as one could see, line 18 doesn't match any of the variables that are
allocated.

Below, the assembly compiled by GCC:
$ gcc -Wall -Wextra -O2 -g3 test.c -S
$ cat test.s
e:
movzbl  (%rdi), %eax
andl$63, %eax
salq$56, %rax
movq%rax, (%rsi)
ret
main:
subq$16, %rsp
leaq8(%rsp), %rsi
movq%rsp, %rdi
calle
cmpq$0, 8(%rsp)
jne .L5
xorl%eax, %eax
addq$16, %rsp
ret
.L5:
ud2

Code available at https://godbolt.org/z/b8sn314K9

Is it an aliasing issue in the code and GCC doesn't reports a warning ? Or
worse ?

[Bug c/71713] "initializer element is not constant" with nested casts

2023-05-27 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71713

Yann Droneaud  changed:

   What|Removed |Added

 CC||yann at droneaud dot fr

--- Comment #2 from Yann Droneaud  ---
May be it's possible with GCC 13, with -std=gnu2x, and using C2x constexpr
storage qualifier.

[Bug c/109828] [13/14 Regression] static compound literal with flexible array in initializer leads to invalid size and ICE

2023-05-15 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109828

--- Comment #8 from Yann Droneaud  ---
(In reply to Yann Droneaud from comment #7)
> I've also experimented compound literal initialization at block level
> instead of file level. Except in case it's not supported, it shows the same
> issue at block level as file level.
> 
> https://godbolt.org/z/vn5Pn7hTx
> 
> Unrelated, I've noted it's not possible to initialize the flexible array if
> the initializer is not having a static storage. I would have expected this
> restriction to be lifted by now.

I've opened bug #109863

[Bug c/109863] New: RFE: more consistent flex array initialization: lift static storage requirement in gnu2x

2023-05-15 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109863

Bug ID: 109863
   Summary: RFE: more consistent flex array initialization: lift
static storage requirement in gnu2x
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: yann at droneaud dot fr
  Target Milestone: ---

I've noted some discrepancies in the flex array initialization support:

/* https://godbolt.org/z/9er5G9G15 */

struct s { char i; char c[]; };

extern void t(const struct s*);

void f(void)
{
// ERROR: non-static initialization of a flexible array member
const struct s c0 = { .c = "0", };
t();

// ERROR: non-static initialization of a flexible array member
const struct s *const c1 = &(const struct s) { .c = "1", };
t(c1);

// OK
const struct s *const c2 = &(constexpr struct s) { .c = "2", };
t(c2);

// ERROR: initializer element is not constant
static const struct s *const c3 = &(constexpr struct s) { .c = "3", };
t(c3);

// OK
static const struct s *const c4 = &(static constexpr struct s) { .c =
"4", };
t(c4);
}

AFAICT constexpr is not supposed to also mean static storage at the block
level, so flex array in c2 is initialized in a non-static way ...

Then I would be happy if GCC could be enhanced to not reject c0 and c1
initialization.

But I fear the opposite will happen, and GCC will reject c2 initialization too
:)

[Bug c/109828] [13/14 Regression] static compound literal with flexible array in initializer leads to invalid size and ICE

2023-05-15 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109828

--- Comment #7 from Yann Droneaud  ---
I've also experimented compound literal initialization at block level instead
of file level. Except in case it's not supported, it shows the same issue at
block level as file level.

https://godbolt.org/z/vn5Pn7hTx

Unrelated, I've noted it's not possible to initialize the flexible array if the
initializer is not having a static storage. I would have expected this
restriction to be lifted by now.

[Bug c/109828] [13/14 Regression] C2x:static compound literal (with flexible array) in initializer leads to invalid size and ICE

2023-05-12 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109828

--- Comment #4 from Yann Droneaud  ---
I'm still playing with this, for example https://godbolt.org/z/dfjr8veh5, and
I've noticed the size of the compound_initializer is incorrect too:

struct s { char i; char c[]; };
const struct s *const s = &(static const struct s) { .c = "1", };

Compile too:

.quad   __compound_literal.4
.type   __compound_literal.4, @object
.size   __compound_literal.4, 1
__compound_literal.4:
.zero   1
.string "1"
.zero   18446744073709551613
.zero   1

I would have have expected .size to be 3, not 1.

Maybe it's the result of computing the size as 3 + -3 + 1, but it's far
fetched.

[Bug c/109828] C2x:static compound literal (with flexible array) in initializer leads to invalid size and ICE

2023-05-12 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109828

--- Comment #2 from Yann Droneaud  ---
(In reply to Yann Droneaud from comment #0)
> The following code is badly compiled by GCC 13.1:
> 
> struct s { int i; char c[]; };
> 
> const struct s s = { .c = "0", };
> const struct s *r = &(constexpr struct s) { .c = "1", };
> const struct s *t = &(static struct s) { .c = "2", };
> 
> Targetting x86-64 / amd64, compiling this with gcc -std=gnu2x -S, produces
> surprising large .zero directive:
> 
> s: 
> .zero   4
> .string "0"
> __compound_literal.0:
> .zero   4
> .string "1"
> .zero   18446744073709551613
> .zero   1
> r:
> .quad   __compound_literal.0
> __compound_literal.1:
> .zero   4
> .string "2"
> .zero   18446744073709551613
> .zero   1
> t:
> .quad   __compound_literal.1
> 
>

When asked to assemble that, binutils' as complains:

$ gcc -std=gnu2x nice.c -c
/tmp/ccZEWv73.s: Assembler messages:
/tmp/ccZEWv73.s:17: Warning: .space repeat count is zero, ignored
/tmp/ccZEWv73.s:32: Warning: .space repeat count is zero, ignored

[Bug c/109828] C2x:static compound literal (with flexible array) in initializer leads to invalid size and ICE

2023-05-12 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109828

Yann Droneaud  changed:

   What|Removed |Added

 CC||yann at droneaud dot fr

--- Comment #1 from Yann Droneaud  ---
I should mention GCC trunk (gcc 14.0.0 20230510 on godbolt.org) is experiencing
ICE without the need to call __builtin_object_size().

[Bug c/109828] New: C2x:static compound literal (with flexible array) in initializer leads to invalid size and ICE

2023-05-12 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109828

Bug ID: 109828
   Summary: C2x:static compound literal (with flexible array) in
initializer leads to invalid size and ICE
   Product: gcc
   Version: 13.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: yann at droneaud dot fr
  Target Milestone: ---

The following code is badly compiled by GCC 13.1:

struct s { int i; char c[]; };

const struct s s = { .c = "0", };
const struct s *r = &(constexpr struct s) { .c = "1", };
const struct s *t = &(static struct s) { .c = "2", };

Targetting x86-64 / amd64, compiling this with gcc -std=gnu2x -S, produces
surprising large .zero directive:

s: 
.zero   4
.string "0"
__compound_literal.0:
.zero   4
.string "1"
.zero   18446744073709551613
.zero   1
r:
.quad   __compound_literal.0
__compound_literal.1:
.zero   4
.string "2"
.zero   18446744073709551613
.zero   1
t:
.quad   __compound_literal.1


Adding a call to __builtin_object_size() and compiling with optimization
triggers an ICE

size_t ice(void)
{
return __builtin_object_size(t, 0);
}


$ gcc -std=gnu2x -O2 -S ice.c
ice.c: In function ‘ice’:
ice.c:11:12: internal compiler error: Segmentation fault
   11 | return __builtin_object_size(t, 0);
  |^~~
0xc4dc6f crash_signal
../../gcc/toplev.cc:317
0x7f39935907cf ???
   
/usr/src/debug/glibc-2.37.9000-9.fc39.x86_64/signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0
0xb1023e tree_fits_poly_int64_p(tree_node const*)
../../gcc/tree.cc:6378
0xb1023e tree_to_poly_int64(tree_node const*)
../../gcc/tree.cc:3285
0x83b5bb component_ref_size(tree_node*, special_array_member*)
../../gcc/tree.cc:13199
0x8096ed decl_init_size(tree_node*, bool)
../../gcc/tree-object-size.cc:493
0xc7f08b addr_object_size
../../gcc/tree-object-size.cc:568
0x6d0248 fold_builtin_object_size
../../gcc/builtins.cc:10808
0x6d0248 fold_builtin_2
../../gcc/builtins.cc:9841
0x6d0248 fold_builtin_n(unsigned int, tree_node*, tree_node*, tree_node**,
int, bool) [clone .isra.0]
../../gcc/builtins.cc:9949
0x12084a6 gimplify_call_expr
../../gcc/gimplify.cc:3824
0x12084a6 gimplify_expr(tree_node**, gimple**, gimple**, bool
(*)(tree_node*), int)
../../gcc/gimplify.cc:16348
0x1207508 gimplify_modify_expr
../../gcc/gimplify.cc:6153
0x1207508 gimplify_expr(tree_node**, gimple**, gimple**, bool
(*)(tree_node*), int)
../../gcc/gimplify.cc:16376
0x1206dfc gimplify_stmt(tree_node**, gimple**)
../../gcc/gimplify.cc:7219
0x1699436 gimplify_and_add(tree_node*, gimple**)
../../gcc/gimplify.cc:492
0x1699436 gimplify_return_expr
../../gcc/gimplify.cc:1680
0x1208676 gimplify_expr(tree_node**, gimple**, gimple**, bool
(*)(tree_node*), int)
../../gcc/gimplify.cc:16638
0x1206dfc gimplify_stmt(tree_node**, gimple**)
../../gcc/gimplify.cc:7219
0x1698c04 gimplify_bind_expr
../../gcc/gimplify.cc:1430

See https://godbolt.org/z/fnnW5T8TG

[Bug c/109516] warning: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'const long unsigned int:48' [-Wformat=]

2023-04-14 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109516

--- Comment #7 from Yann Droneaud  ---
(In reply to Andrew Pinski from comment #6)
> > 
> > And I failed to comprehend how unsigned long int:48 can be passed to a
> > variadic function without being promoted to plain unsigned long int ... 
> 
> Oh yes, there is no way for an user to get the value back via va_arg really.
> But this is just how C has an implementation defined behavior here really.

I understand, but can't refrain myself from thinking it's an unfortunate
discrepancy having a warning when formatting the uint64_t:48 case but not for
uint32_t:24 one.

Anyway, thanks for all the explanation. Regards.

[Bug c/109516] warning: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'const long unsigned int:48' [-Wformat=]

2023-04-14 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109516

Yann Droneaud  changed:

   What|Removed |Added

 CC||yann at droneaud dot fr

--- Comment #4 from Yann Droneaud  ---
(In reply to Andrew Pinski from comment #1)
> 
> Basically GCC decided that the type of the bitfield uint48 has a type of
> unsigned:48 and since it is larger size than int, it does not get promoted
> to int and in this cases gets passed to the variadic function as that type.

I wouldn't have expected bitfield type to be "visible" outside of its
structure.  

And I failed to comprehend how unsigned long int:48 can be passed to a variadic
function without being promoted to plain unsigned long int ... 

Anyway, I will have to add a cast to silence the warning.

> While clang decided that the type is still unsigned long long.

AFAICT, there's no unsigned long long involved in my example.

[Bug c/109516] New: warning: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'const long unsigned int:48' [-Wformat=]

2023-04-14 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109516

Bug ID: 109516
   Summary: warning: format '%lx' expects argument of type 'long
unsigned int', but argument 2 has type 'const long
unsigned int:48' [-Wformat=]
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: yann at droneaud dot fr
  Target Milestone: ---

I've discovered today an unexpected format related warning when asking to print
a bitfield over unsigned long:

  $ cat > fmt-bitfield.c <
  #include 
  #include 

  struct struct24 { uint32_t uint24:24; };

  void print24(const struct struct24 *s)
  { printf("%" PRIx32 "\n", s->uint24); }

  struct struct48 { uint64_t uint48:48; };

  void print48(const struct struct48 *s)
  { printf("%" PRIx64 "\n", s->uint48); }
  EOF

  $ gcc -Wformat -c fmt-bitfield.c
  fmt-bitfield.c: In function 'print48':
  fmt-bitfield.c:13:10: warning: format '%lx' expects argument of type 'long
unsigned int', but argument 2 has type 'long unsigned int:48' [-Wformat=]
 13 | { printf("%" PRIx64 "\n", s->uint48); }
|  ^~~  ~
||
|long unsigned int:48
  In file included from fmt-bitfield.c:1:
/usr/include/inttypes.h:121:41: note: format string is defined here
121 | # define PRIx64 __PRI64_PREFIX "x"

See https://godbolt.org/z/r44e5rfnh

I understood that, according to C standard, bitfield over type other that int
or bool is an implementation defined behavior.

But GCC is expected to support bitfield over long as well:

https://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit-fields-implementation.html

  - Allowable bit-field types other than _Bool, signed int, and unsigned int
(C99 and C11 6.7.2.1).

Other integer types, such as long int, and enumerated types are permitted
even in strictly conforming mode.

So I believe the warning is spurious, and formatting a value whose type is a
bitfield over long should not trigger the warning when using %l format
modifier.

(For the record, clang doesn't report such warning).

[Bug preprocessor/109183] [regression?] since GCC 11.1, -MM -MMD generates "a-" prefixed dependency files

2023-03-27 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109183

--- Comment #4 from Yann Droneaud  ---
(In reply to Alexandre Oliva from comment #3)
> dump files now consistently take the base name from the output name, when
> not overridden
> 
> since in this case gcc is called for (compiling and) linking, and the final
> output name is a.* (.out or .exe, depending on the platform),

That the issue at hand, `gcc -MM -MMD test.c` does not compile nor link
anything: it preprocess and extract dependencies, nothing more. Thus using
"a.out" as the output is not expected.

[Bug preprocessor/109183] [regression?] since GCC 11.1, -MM -MMD generates "a-" prefixed dependency files

2023-03-21 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109183

Yann Droneaud  changed:

   What|Removed |Added

 CC||yann at droneaud dot fr

--- Comment #2 from Yann Droneaud  ---
gcc -MM -MMD seems to behave like

  gcc -dumpbase a -MM -MMD test.c

or

  gcc -dumpdir a- -MM -MMD test.c

[Bug preprocessor/109183] New: [regression?] since GCC 11.1, -MM -MMD generates "a-" prefixed dependency files

2023-03-18 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109183

Bug ID: 109183
   Summary: [regression?] since GCC 11.1, -MM -MMD generates "a-"
prefixed dependency files
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: preprocessor
  Assignee: unassigned at gcc dot gnu.org
  Reporter: yann at droneaud dot fr
  Target Milestone: ---

I've found a rather surprising behavior change when using GCC >= 11.1 to build
some project using custom build environment.

How to reproduce:

: > test.c
gcc -MM -MMD test.c
test -e a-test.d && echo "unexpected dependency file name"

I've git-bisect-ed between GCC 11.1 and GCC 10.1 and the behavior change did
happen as the result of this commit:

commit 1dedc12d186a110854537e1279b4e6c29f2df35a
Author: Alexandre Oliva 
Date:   Tue May 26 04:30:15 2020 -0300

revamp dump and aux output names

   
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=1dedc12d186a110854537e1279b4e6c29f2df35a

I didn't find an explanation there for this behavior change.

It's not noted in the documentation either
https://gcc.gnu.org/onlinedocs/gcc-11.3.0/gcc/Preprocessor-Options.html

So this make me believe it's some kind of regression for a corner case.

I understand the correct usage of -MMD is to be associated with some
processing, -E, -S, -c, etc, while -MM imply -E, so perhaps -MM and -MMD are
mutually exclusive and should not be allowed together. I dunno.

But generating "a-" prefixed dependency files is rather unexpected.

[Bug tree-optimization/108398] tree-object-size trips up with pointer arithmetic if an intermediate result is an invalid pointer

2023-01-15 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108398

--- Comment #10 from Yann Droneaud  ---
(In reply to Jakub Jelinek from comment #8)
> -fsanitize=undefined with no diagnostics doesn't mean code is UB free.

This is a pity, it would have help users do diagnose the issue in their code.

[Bug tree-optimization/108398] tree-object-size trips up with pointer arithmetic if an intermediate result is an invalid pointer

2023-01-13 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108398

Yann Droneaud  changed:

   What|Removed |Added

 CC||yann at droneaud dot fr

--- Comment #6 from Yann Droneaud  ---
c-reduce comes up with the following reproducer:

  #include 
  typedef struct {
int a;
  } b;
  typedef struct {
b c[2];
  } d;
  d e;
  int f = 2;
  int main() {
b *g;
for (g = e.c; f; g++)
  switch (g->a) {
  case 0:
memmove(g, g + 1, sizeof(b));
f--;
g--;
  }
   }

gcc -fsanitize=undefined doesn't catch any issue ...

[Bug other/55899] GCC should provide built-ins in data types flavor/version/variation

2022-11-29 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55899

Yann Droneaud  changed:

   What|Removed |Added

 CC||yann at droneaud dot fr

--- Comment #2 from Yann Droneaud  ---
I stumbled upon this issue again when dealing with uint64_t as sometimes it's
defined as unsigned long, sometimes it's defined as unsigned long long
depending on the ABI. Having __builtin_ffs64(), __builtin_clz64(),
__builtin_ctz64(), etc. would ease me making my code portable to unpleasant ABI
such as Microsoft Windows ones without having to use GCC's
__builtin_types_compatible_p() (which is not supported when compiling C++), or
C11 _Generic() ...

[Bug c++/107104] semantics of __builtin_constant_p within static_assert and return value

2022-11-12 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107104

Yann Droneaud  changed:

   What|Removed |Added

 CC||yann at droneaud dot fr

--- Comment #3 from Yann Droneaud  ---
I'm experiencing the same issue:

#include 

void a(int v)
{
static_assert(__builtin_constant_p(v) && v == -1, "failure");
}

GCC 13 and below complains:

: In function 'a':
:16:43: error: expression in static assertion is not constant
   16 | static_assert(__builtin_constant_p(v) && v == -1, "failure");
  |   ^~
Compiler returned: 1


clang current trunk, eg above 15.0, seems to finally get it right:

:16:5: error: static assertion failed due to requirement
'__builtin_constant_p(v) && v == -1': failure
static_assert(__builtin_constant_p(v) && v == -1, "failure");
^ ~~
/usr/include/assert.h:143:24: note: expanded from macro 'static_assert'
# define static_assert _Static_assert
   ^
1 error generated.
Compiler returned: 1

see https://godbolt.org/z/KKn6xTG8a

[Bug ipa/106061] [13 Regression] during GIMPLE pass: einline ICE: verify_cgraph_node failed (edge points to wrong declaration) with -Og since r13-1204-gd68d366425369649

2022-11-11 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106061

Yann Droneaud  changed:

   What|Removed |Added

 CC||yann at droneaud dot fr

--- Comment #6 from Yann Droneaud  ---
I'm reaching this bug too, compiling the following smaller reproducer:

extern void a(void);
inline void b(int c) { if (c) a(); }
void d(void) { b(0); }

[Bug tree-optimization/107618] Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error"

2022-11-11 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107618

--- Comment #6 from Yann Droneaud  ---
(In reply to Richard Biener from comment #5)
> Should be fixed for GCC 13, it doesn't seem to be a regression.

I've tested with a fresh rebuild of GCC's trunk, and the warning is no more
reported at -Og level.

Thanks.

[Bug middle-end/107618] Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error"

2022-11-10 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107618

--- Comment #2 from Yann Droneaud  ---
I was wondering what GCC expects __builtin_object_size(0, 0) to be, and used
the following:

void a_1 (void) __attribute__((__warning__("-1")));
void a0 (void) __attribute__((__warning__("0")));
void a1 (void) __attribute__((__warning__("1")));
void a2 (void) __attribute__((__warning__("2")));
void a3 (void) __attribute__((__warning__("3")));
void a4 (void) __attribute__((__warning__("4")));

int main(void) {
  unsigned long b = __builtin_object_size(0, 0);
  if (__builtin_expect(b == (unsigned long)-1, 0))
a_1();
  if (__builtin_expect(b == 0, 0))
a0();
  if (__builtin_expect(b == 1, 0))
a1();
  if (__builtin_expect(b == 2, 0))
a2();
  if (__builtin_expect(b == 3, 0))
a3();
  if (__builtin_expect(b == 4, 0))
a4();
}

It works as expected for any level above 0, except -Og:

$ gcc -O1 -S warning.c
warning.c: In function ‘main’:
warning.c:11:5: warning: call to ‘a_1’ declared with attribute warning: -1
[-Wattribute-warning]
   11 | a_1();
  | ^

It's quite reassuring that __builtin_object_size(0, 0) returns -1, hence the
emitted call to a_1():

$ cat warning.s
.file"warning.c"
.text
.globlmain
.typemain, @function
main:
endbr64
subq$8, %rsp
calla_1@PLT
movl$0, %eax
addq$8, %rsp
ret

For -Og, there's a firework of warnings (shockingly they're the same than -O0
level):

$ gcc -Og -S warning.c
warning.c: In function ‘main’:
warning.c:11:5: warning: call to ‘a_1’ declared with attribute warning: -1
[-Wattribute-warning]
   11 | a_1();
  | ^
warning.c:13:5: warning: call to ‘a0’ declared with attribute warning: 0
[-Wattribute-warning]
   13 | a0();
  | ^~~~
warning.c:15:5: warning: call to ‘a1’ declared with attribute warning: 1
[-Wattribute-warning]
   15 | a1();
  | ^~~~
warning.c:17:5: warning: call to ‘a2’ declared with attribute warning: 2
[-Wattribute-warning]
   17 | a2();
  | ^~~~
warning.c:19:5: warning: call to ‘a3’ declared with attribute warning: 3
[-Wattribute-warning]
   19 | a3();
  | ^~~~
warning.c:21:5: warning: call to ‘a4’ declared with attribute warning: 4
[-Wattribute-warning]
   21 | a4();
  | ^~~~

Generated assembly for -Og is the same than for levels above 0: a call to a_1()
function is emitted, which mean GCC, at some point, knows
__builtin_object_size(0, 0) is -1 here. Thus most of the warnings are not very
useful.

$ cat warning.s
.file"warning.c"
.text
.globlmain
.typemain, @function
main:
endbr64
subq$8, %rsp
calla_1@PLT
movl$0, %eax
addq$8, %rsp
ret

[Bug middle-end/107618] Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error"

2022-11-10 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107618

Yann Droneaud  changed:

   What|Removed |Added

 CC||yann at droneaud dot fr

--- Comment #1 from Yann Droneaud  ---
A smallest reproducer (generated with some help from C-reduce):

void a(void) __attribute__((__warning__("")));
int main(void) {
  unsigned long b = __builtin_object_size(0, 0);
  if (__builtin_expect(b < 1, 0))
a();
}

Works at all level above -00, except -Og:

$ gcc -Og warning.c
warning.c: In function ‘main’:
warning.c:5:5: warning: call to ‘a’ declared with attribute warning: 
[-Wattribute-warning]
5 | a();
  | ^~~

[Bug other/107618] New: Incorrect diagnostics when using -Og, builtin_expect(), and function attribute "warning" or "error"

2022-11-10 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107618

Bug ID: 107618
   Summary: Incorrect diagnostics when using -Og,
builtin_expect(), and function attribute "warning" or
"error"
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: other
  Assignee: unassigned at gcc dot gnu.org
  Reporter: yann at droneaud dot fr
  Target Milestone: ---

Created attachment 53872
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53872=edit
reproducer for -Og, __builtin_expect(), and function
__attribute__((warning("")))

The code below compiled with -Og triggers a warning message that is not
mandated:

$ gcc -Og  warning.c
warning.c: In function ‘test_expect’:
warning.c:26:17: warning: call to ‘size_mismatch_expect’ declared with
attribute warning: size mismatch (builtin_expect) [-Wattribute-warning]
   26 | size_mismatch_expect();
  | ^~


$ cat warning.c
#include 
#include 
#include 

extern void size_mismatch_nonexpect(void)
__attribute__((__warning__("size mismatch")));

static bool
test_nonexpect(const void *addr, size_t len)
{
size_t sz = __builtin_object_size(addr, 0);
if (sz != (size_t)-1 && sz < len) {
size_mismatch_nonexpect();
return false;
}

return true;
}

extern void size_mismatch_expect(void)
__attribute__((__warning__("size mismatch (builtin_expect)")));

static bool
test_expect(const void *addr, size_t len)
{
size_t sz = __builtin_object_size(addr, 0);
if (__builtin_expect(sz != (size_t)-1 && sz < len, 0)) {
size_mismatch_expect();
return false;
}

return true;
}

int main(void)
{
int i = 0;

if (!test_nonexpect(, sizeof(i)))
return EXIT_FAILURE;

if (!test_expect(, sizeof(i)))
return EXIT_FAILURE;

return EXIT_SUCCESS;
}

The warning at -Og level is not expected because there's no call to the
size_mismatch_expect() in the generated assembler (for x86-64):

$ head warning.s
.file"warning.c"
.text
.typetest_nonexpect, @function
test_nonexpect:
movl$1, %eax
ret
.sizetest_nonexpect, .-test_nonexpect
.typetest_expect, @function
test_expect:
movl$1, %eax
ret
.sizetest_expect, .-test_expect
.globlmain
.typemain, @function
main:
endbr64
subq$24, %rsp
movq%fs:40, %rax
movq%rax, 8(%rsp)
xorl%eax, %eax
movl$0, 4(%rsp)
leaq4(%rsp), %rdi
movl$4, %esi
calltest_nonexpect
testb%al, %al
jne.L11
movl$1, %eax
.L5:
movq8(%rsp), %rdx
subq%fs:40, %rdx
jne.L12
addq$24, %rsp
ret
.L11:
leaq4(%rsp), %rdi
movl$4, %esi
calltest_expect
testb%al, %al
je.L9
movl$0, %eax
jmp.L5
.L9:
movl$1, %eax
jmp.L5


See also https://godbolt.org/z/KEsaavhvG

Compiling at optimization level s, z, 1, 2, or 3 doesn't produce that warning.
(but compiling with -O0 does produces two warnings, as expected, since calls to
the two functions are emitted).

Having the warning at debug optimization level makes using -Og in some complex
code base challenging for no good reason when __attribute__((error(""))) is
used (or -Werror=attribute-warning).

It should also be noted clang doesn't generate the warning for optimization
level above 0.

[Bug middle-end/99578] [11 Regression] gcc-11 -Warray-bounds or -Wstringop-overread warning when accessing a pointer from integer literal

2022-08-20 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578

--- Comment #43 from Yann Droneaud  ---
(In reply to Jakub Jelinek from comment #37)
> Fixed on the trunk so far, temporarily by differentiating between < 4KB
> addresses which are still handled like GCC 11 did for warning purposes, and
> >= 4KB addresses where we won't warn anymore.

As noted by Andrew Pinski in bug #106699, comment #1, one has "to use
--param=min-pagesize=0 if the first 4k is valid memory" to inhibit warnings for
addresses below 4096.

[Bug c/106699] New: Since gcc 12, deferencing constant literal addresses triggers -Warray-bounds warning

2022-08-20 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106699

Bug ID: 106699
   Summary: Since gcc 12, deferencing constant literal addresses
triggers -Warray-bounds warning
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: yann at droneaud dot fr
  Target Milestone: ---

Since GCC 12.1, compiling memtest86+ triggers the following warning:

In function 'find_rsdp',
inlined from 'acpi_init' at ../system/acpi.c:329:29:
../system/acpi.c:185:29: warning: array subscript 0 is outside array bounds of
'uint16_t[0]' {aka 'short unsigned int[]'} [-Warray-bounds]
  185 | uintptr_t address = *(uint16_t *)0x40E << 4;
  | ^~

../system/hwctrl.c: In function 'reboot':
../system/hwctrl.c:76:9: warning: array subscript 0 is outside array bounds of
'uint16_t[0]' {aka 'short unsigned int[]'} [-Warray-bounds]
   76 | *((uint16_t *)0x472) = 0x1234;
  | ^~~~

In function 'find_cpus_in_floating_mp_struct',
inlined from 'smp_init' at ../system/smp.c:543:39:
../system/smp.c:346:29: warning: array subscript 0 is outside array bounds of
'uint16_t[0]' {aka 'short unsigned int[]'} [-Warray-bounds]
  346 | uintptr_t address = *(uint16_t *)0x40E << 4;
  | ^~

Sure using integer literal as a pointer is a recipe for disaster in most cases.
But it's for a freestanding environment, a bootloader, a kernel.

So -Warray-bounds should not infer an address points to a empty array.

A minimal test case:

#include 

void write(void) {
*((uint16_t *)0x472) = 0x1234;
}

uint16_t read(void) {
return *(uint16_t *)0x40E << 4;
}

https://godbolt.org/z/c9993xx41

[Bug rtl-optimization/81501] mulitple calls to __tls_get_addr() with -fPIC

2022-08-17 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81501

--- Comment #7 from Yann Droneaud  ---
(In reply to Roy Jacobson from comment #6)
> We recently upgraded our toolchain from GCC9 to GCC11, and we're seeing
> __tls_get_addr take up to 10% of total runtime under some workloads, where
> it was 1-2% before.
> 
> It seems that some changes to the optimization passes in 10 or 11 have
> significantly increased the impact of this problem.

In bug #82803, comment #12,
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82803#c12), I've shown a
workaround I used, which might be useful until GCC handle __tls_get_addr() as
returning a constant addresses that doesn't need to be looked up multiple times
in a function.

[Bug c/82283] Wrong warning with -Wmissing-field-initializers

2022-03-24 Thread yann at droneaud dot fr via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283

--- Comment #16 from Yann Droneaud  ---
(In reply to Marek Polacek from comment #13)
> I have a patch which fixes all the testcases here.

I've checked my test cases using godbolt gcc trunk, and, yeah, thanks a lot !

[Bug c/82283] Wrong warning with -Wmissing-field-initializers

2020-02-24 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283

--- Comment #8 from Yann Droneaud  ---
See also this stack overflow question

https://stackoverflow.com/questions/49081541/compound-literal-and-designated-initializer-warning-from-gcc-but-not-clang

[Bug c/82283] Wrong warning with -Wmissing-field-initializers

2020-02-24 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283

--- Comment #7 from Yann Droneaud  ---
See also bug #84685 which is a very likely duplicate of this one.

[Bug c/84685] Designated initializers warning

2020-02-24 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84685

Yann Droneaud  changed:

   What|Removed |Added

 CC||yann at droneaud dot fr

--- Comment #3 from Yann Droneaud  ---
Likely a duplicate of bug #82283

[Bug c/82283] Wrong warning with -Wmissing-field-initializers

2020-02-24 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283

--- Comment #6 from Yann Droneaud  ---
Found this one on stack overflow[1], and I find it a bit embarrassing:

struct {
  struct {
int a;
int b;
  } c[1];
} d = {
.c[0].a = 1,
.c[0].b = 1,
};

Results in the following warning:

:7:8: error: missing initializer for field 'b' of 'struct
' [-Werror=missing-field-initializers]
7 |.c[0].b = 1,
  |^
:4:9: note: 'b' declared here
4 | int b;
  | ^
cc1: all warnings being treated as errors
Compiler returned: 1

See https://godbolt.org/z/zGqM7C

GCC emits a warning about a field missing an initializer despite being
obviously explicitly initialized.

If the present but missing initialization is removed:

struct {
  struct {
int a;
int b;
  } c[1];
} d = {
.c[0].a = 1,
};

GCC complains, incorrectly, about a missing initializer, as described in
previous comments:

:8:1: error: missing initializer for field 'b' of 'struct
' [-Werror=missing-field-initializers]
8 | };
  | ^
:4:9: note: 'b' declared here
4 | int b;
  | ^
cc1: all warnings being treated as errors
Compiler returned: 1

See https://godbolt.org/z/8NRwo5

[1]
https://stackoverflow.com/questions/22194935/wmissing-field-initializer-when-using-designated-initializers

[Bug c/82283] Wrong warning with -Wmissing-field-initializers

2020-02-23 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283

--- Comment #5 from Yann Droneaud  ---
For a full combo, here's the almost original code that trigger the two errors
above with GLibc < 2.28, only one with newer Glibc.

#define _GNU_SOURCE 1

#include 
#include 
#include 

int test(int fd)
{
static const char message[] = "Hello world";

struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
.sin_port = htons(12345),
};

struct iovec vec = {
.iov_base = (void *)message,
.iov_len = sizeof(message),
};

struct mmsghdr mmsghdr = {
.msg_hdr = (struct msghdr) {
.msg_name = ,
.msg_namelen = sizeof(addr),
.msg_iov = ,
.msg_iovlen = 1,
},
};

return sendmmsg(fd, , 1, 0);
}

see https://godbolt.org/z/pwXyzE

[Bug c/82283] Wrong warning with -Wmissing-field-initializers

2020-02-22 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283

--- Comment #4 from Yann Droneaud  ---
Also with the ({}) GCC extension:

struct a {
int b;
int c;
};

void d(struct a *);

void e(void) {

struct a f = {
 .b = ({
   int g = 0;
   g;
  })
};

d();
}

It produces the warning:

: In function 'e':

:10:17: error: missing initializer for field 'c' of 'struct a'
[-Werror=missing-field-initializers]
   10 | })};
  | ^
:3:7: note: 'c' declared here
3 |   int c;
  |   ^
cc1: all warnings being treated as errors
Compiler returned: 1

See https://godbolt.org/z/VJAuv4

(Note: this example and the one above were reduced by c-reduce
https://embed.cs.utah.edu/creduce/ )

[Bug c/82283] Wrong warning with -Wmissing-field-initializers

2020-02-22 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82283

Yann Droneaud  changed:

   What|Removed |Added

 CC||yann at droneaud dot fr

--- Comment #3 from Yann Droneaud  ---
I'm experiencing the same issue in multiple cases, even with latest GCC trunk
(10.x).

I believe the following code is C99 conformant, but still trigger an unexpected
warning:

struct a {
int b;
};

struct c {
struct a d;
int e;
};

void f(struct c *);

void g(void) {
struct c h = {.d = (struct a){0}};
f();
}

It produces the following warning:

: In function 'g':
:10:30: error: missing initializer for field 'e' of 'struct c'
[-Weror=missing-field-initializers]
   10 |   struct c h = {.d = (struct a){0}};
  |  ^
:6:7: note: 'e' declared here
6 |   int e;
  |   ^
cc1: all warnings being treated as errors
Compiler returned: 1

See https://godbolt.org/z/vQLYRX

[Bug tree-optimization/82803] Wildly excessive calls to __tls_get_addr with optimizations enabled.

2019-09-25 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82803

--- Comment #12 from Yann Droneaud  ---
(In reply to Yann Droneaud from comment #8)
> Created attachment 46903 [details]
> An artificial test case for gcc to emit 17 calls to __tls_get_addr()
>

It's possible to "workaround" this issue by using some __asm__ statement such
as OPTIMIZER_HIDE_VAR() from Linux kernel, see
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/compiler.h?h=v5.3#n169

   __asm__ ("" : "=r" (var) : "0" (var))

As base line, an artificial benchmark using attachment #46903 in an ELF shared
library, have following results when run through perf:

 Performance counter stats for './case' (100 runs):

932,83 msec task-clock:u   #0,999 CPUs utilized   ( +-  0,38% )
 0  context-switches:u #0,000 K/sec  
 0  cpu-migrations:u   #0,000 K/sec  
51  page-faults:u  #0,054 K/sec   ( +-  0,19% )
 2 528 214 520  cycles:u   #2,710 GHz ( +-  0,30% )
 4 150 148 436  instructions:u #1,64  insn per cycle  ( +-  0,00% )
 1 530 031 707  branches:u # 1640,205 M/sec   ( +-  0,00% )
51 236  branch-misses:u#0,00% of all branches ( +-  7,24% )

   0,93364 +- 0,00359 seconds time elapsed  ( +-  0,38% )

Applying the following change to attachment #46903

  --- case.c~   2019-09-20 15:39:41.852356614 +0200
  +++ case.c2019-09-25 21:38:47.620696710 +0200
  @@ -1,8 +1,15 @@
   int process(int *);

  +#define HIDE_VAR(v) __asm__ ("" : "=r" (v) : "0" (v))
  +
   static int *state(void)
   {
  - static __thread int s[16];
  + static __thread int __s[16];
  + int *s = __s;
  +
  + HIDE_VAR(s);
  +
return s;
   }

And running the benchmark again through perf, the results are:

 Performance counter stats for './case' (100 runs):

540,54 msec task-clock:u   #0,999 CPUs utilized   ( +-  0,22% )
 0  context-switches:u #0,000 K/sec  
 0  cpu-migrations:u   #0,000 K/sec  
50  page-faults:u  #0,093 K/sec   ( +-  0,17% )
 1 469 494 111  cycles:u   #2,719 GHz ( +-  0,12% )
 1 530 148 010  instructions:u #1,04  insn per cycle  ( +-  0,00% )
   730 031 281  branches:u # 1350,554 M/sec   ( +-  0,00% )
74 613  branch-misses:u#0,01% of all branches ( +- 18,61% )

   0,54102 +- 0,00119 seconds time elapsed  ( +-  0,22% )

With the workaround, the benchmark took 42% less time. It's 1.72x faster.

[Bug rtl-optimization/82803] Wildly excessive calls to __tls_get_addr with optimizations enabled.

2019-09-23 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82803

--- Comment #10 from Yann Droneaud  ---
Some more snippets, generated with creduce:

-8<
  void a(long *);
  int b(void);
  void c(void);
  long d(void) {
static __thread long e;
a();
if (b())
  c();
return e;
  }
--8<
  int a(void);
  void b(long *);
  void c(void) {
static __thread long d;
if (d || a())
  d = 0;
b();
  }
--8<
  void a(int *);
  int b(int *);
  int c(void) {
static __thread int d;
a();
while (b());
return 0;
  }
--8<
  void b(int *);
  int c(int *);
  int d(void) {
static __thread int a;
if (a)
  while (c());
b();
return 0;
  }
--8<
  int b(void);
  void c(void);
  void d(int *);
  int e(void) {
static __thread int a[2];
d(a);
do {
  d(a);
  if (b())
c();
} while (a[0] && a[1]);
d(a);
return 0;
  }
--8<

Those make gcc emits 2 or more calls to __tls_get_addr().

[Bug rtl-optimization/82803] Wildly excessive calls to __tls_get_addr with optimizations enabled.

2019-09-20 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82803

--- Comment #9 from Yann Droneaud  ---
This issue is also reported as bug #81501

[Bug rtl-optimization/81501] Unneccessary calls to __tls_get_addr() in simple thread-singleton pattern

2019-09-20 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81501

Yann Droneaud  changed:

   What|Removed |Added

 CC||yann at droneaud dot fr

--- Comment #3 from Yann Droneaud  ---
See also bug #82803.

[Bug rtl-optimization/82803] Wildly excessive calls to __tls_get_addr with optimizations enabled.

2019-09-20 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82803

Yann Droneaud  changed:

   What|Removed |Added

 CC||yann at droneaud dot fr

--- Comment #8 from Yann Droneaud  ---
Created attachment 46903
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46903=edit
An artificial test case for gcc to emit 17 calls to __tls_get_addr()

Using Thread Local Storage (TLS) is a pain: the issue reported here still apply
on latest GCC.

I've code such as

  static struct state *state(void) __attribute__((pure));
  static struct state *state(void)
  {
  static __thread struct state s;

  return 
  }

  int do(void)
  {
  struct state * const s = state();
  int res;

  /* do something */

  return res;
  }

Once compiled, code for my real function contains 6 calls to __tls_get_addr().
Which is far more than expected. And far more than necessary.
Clang compile the same code and emit a single call to __tls_get_addr(). Both on
Linux amd64, -O3 -fPIC.

The attached testcase is an example which is designed to trigger 17 calls to
__tls_get_addr(). As you will see, there's about one per conditional + function
call pair.

Once again, clang is able to emit code with a single call to __tls_get_addr().

You can check for yourself: https://godbolt.org/z/QVGjka

[Bug c/86647] Test on constant expression (unsigned) -1 < 0 triggers a spurious -Wtype-limits warning

2019-09-06 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86647

--- Comment #5 from Yann Droneaud  ---
I've reproduced the issue with 

bool test(void)
{
return ((unsigned int)0 - 1) < 0;
}

See https://godbolt.org/z/b1QqIC

[Bug c/86647] Test on constant expression (unsigned) -1 < 0 triggers a spurious -Wtype-limits warning

2019-09-06 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86647

--- Comment #4 from Yann Droneaud  ---
*** Bug 91685 has been marked as a duplicate of this bug. ***

[Bug c/91685] -Wtype-limits warns for constant expression

2019-09-06 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91685

Yann Droneaud  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 CC||yann at droneaud dot fr
 Resolution|--- |DUPLICATE

--- Comment #1 from Yann Droneaud  ---
My issue is the same as bug #86647.

*** This bug has been marked as a duplicate of bug 86647 ***

[Bug c++/81642] -Wtype-limits should not trigger for defined numbers

2019-09-06 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81642

Yann Droneaud  changed:

   What|Removed |Added

 CC||yann at droneaud dot fr

--- Comment #3 from Yann Droneaud  ---
See also bug #86647 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86647

[Bug c/86647] Test on constant expression (unsigned) -1 < 0 triggers a spurious -Wtype-limits warning

2019-09-06 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86647

Yann Droneaud  changed:

   What|Removed |Added

 CC||yann at droneaud dot fr

--- Comment #3 from Yann Droneaud  ---
See also bug #81642 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81642

[Bug c/91685] New: -Wtype-limits warns for constant expression

2019-09-06 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91685

Bug ID: 91685
   Summary: -Wtype-limits warns for constant expression
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: yann at droneaud dot fr
  Target Milestone: ---

I'm was trying to implement a test for socklen_t type signedness, because on
some platform it's signed and some it's unsigned. For signed socklen_t, I
wanted to rejected negative values.

I found following code triggers a warning:

$ cat test.c

#include 

bool test_unsigned(void)
{
return ((unsigned int)0 - 1) < 0;
}

$ gcc -O2 -Wall -Wextra -c test.c 
warning: comparison of unsigned expression in '< 0' is always false
[-Wtype-limits]

According to the documentation for -Wtype-limits, this warning should not be
produced, because expression is constant:

> Warn if a comparison is always true or always false due to the limited range 
> of the data type, but do not warn for constant expressions. For example, warn 
> if an unsigned variable is compared against zero with < or >=. This warning 
> is also enabled by -Wextra. 

https://gcc.gnu.org/onlinedocs/gcc-9.2.0/gcc/Warning-Options.html#index-Wtype-limits

I've made some tests on godbolt, see https://godbolt.org/z/b1QqIC and found
clang doesn't trigger the warning.

Perhaps warning here is welcomed and documentation should be updated ?

In the mean time, I still looking for a portable way to test if socklen_t is
negative on platform where it's signed ...

[Bug c++/90885] GCC should warn about 2^16 and 2^32 and 2^64

2019-06-14 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90885

--- Comment #7 from Yann Droneaud  ---
The issue was noted on twitter by John Regehr, in
https://twitter.com/johnregehr/status/1139295920997068800 and following
messages.

The warning was suggest again by John Regehr in
https://twitter.com/johnregehr/status/1139302389612077056

[Bug middle-end/90037] [9 Regression] -Wnull-dereference false positive after r269302

2019-04-11 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90037

Yann Droneaud  changed:

   What|Removed |Added

  Attachment #46138|0   |1
is obsolete||

--- Comment #4 from Yann Droneaud  ---
Created attachment 46139
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46139=edit
Reduced reproducer sample

(In reply to Yann Droneaud from comment #3)
> Created attachment 46138 [details]
> Reduced reproducer sample
> 
> I've used creduce[1][2] to generate a smaller reproducer sample, see
> https://godbolt.org/z/Ae2x_h
> 

I've used an improved "interestingness script" to generate a reproducer sample
which trigger less unrelated warnings.

See https://godbolt.org/z/542lS0

[Bug middle-end/90037] [9 Regression] -Wnull-dereference false positive after r269302

2019-04-10 Thread yann at droneaud dot fr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90037

--- Comment #3 from Yann Droneaud  ---
Created attachment 46138
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46138=edit
Reduced reproducer sample

I've used creduce[1][2] to generate a smaller reproducer sample, see
https://godbolt.org/z/Ae2x_h

[1] http://embed.cs.utah.edu/creduce/
[2] https://github.com/csmith-project/creduce

[Bug c/60722] New: __builtin_choose_expr() does not allow 'CONST_EXP' using const variable

2014-03-31 Thread yann at droneaud dot fr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60722

Bug ID: 60722
   Summary: __builtin_choose_expr() does not allow 'CONST_EXP'
using const variable
   Product: gcc
   Version: 4.9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: yann at droneaud dot fr

Created attachment 32498
  -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=32498action=edit
testcase

Hi,

I'm trying to use __builtin_choose_expr() with a test against a const variable:

#define VALUE 123

int
test(void)
{
const int value = VALUE;
int v1, v2;

v1 = __builtin_choose_expr(__builtin_constant_p(VALUE),
   (__builtin_choose_expr(VALUE = 10,
  2,
  (__builtin_choose_expr(VALUE = 0,
 1,
 0,
-1);

v1 = __builtin_choose_expr(__builtin_constant_p(value),
   (__builtin_choose_expr(value = 10,
  2,
  (__builtin_choose_expr(value = 0,
 1,
 0,
   -1);

return v1 - v2;
}




The first expression is considering a constant defined as a macro.
And the second expression is considering a constant variable.

With gcc 4.9.0 20140313 (experimental), I'm facing the following error:

$ /opt/gcc/bin/gcc -O2 -c test.c 
test.c: In function ‘test’:
test.c:21:11: erreur: first argument to ‘__builtin_choose_expr’ not a constant
  (__builtin_choose_expr(value = 0,
   ^
test.c:19:9: erreur: first argument to ‘__builtin_choose_expr’ not a constant
(__builtin_choose_expr(value = 10,
 ^

(Note: with gcc 4.8, I'm also having the issue with _builtin_constant_p(value),
as bug #19449)


It's a pity gcc is not able to consider (value = 0) as a constant expression
while its obvious
that 'value' is a constant variable (!).

It makes usage of __builtin_choose_expr() not applicable in my case.

[Bug c/58872] New: RFC: more builtins for bit manipulation

2013-10-25 Thread yann at droneaud dot fr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58872

Bug ID: 58872
   Summary: RFC: more builtins for bit manipulation
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: enhancement
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: yann at droneaud dot fr

Current bit manipulation builtins can be found in documentation:
http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins

GCC could benefit of more bit manipulation builtins, for example:

- rotate bit right:

  __builtin_ror8(uint8_t v, int count)
  __builtin_ror16(uint16_t v, int count)
  __builtin_ror32(uint32_t v, int count)
  __builtin_ror64(uint64_t v, int count)

- rotate bit left:

  __builtin_rol8(uint8_t v, int count)
  __builtin_rol16(uint16_t v, int count)
  __builtin_rol32(uint32_t v, int count)
  __builtin_rol64(uint64_t v, int count)

- reverse bit string (bit swap):

  __builtin_brev8(uint8_t v, int index, int count)
  __builtin_brev16(uint16_t v, int index, int count)
  __builtin_brev32(uint32_t v, int index, int count)
  __builtin_brev64(uint64_t v, int index, int count)


[Bug c/58872] RFC: more builtins for bit manipulation

2013-10-25 Thread yann at droneaud dot fr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58872

Yann Droneaud yann at droneaud dot fr changed:

   What|Removed |Added

 CC||yann at droneaud dot fr

--- Comment #2 from Yann Droneaud yann at droneaud dot fr ---
(In reply to Marc Glisse from comment #1)
 What do the arguments of brev mean?
 Related to PR 50481.

The prototype for the reverse bit string builtin was designed to be useful to
reverse bits in a subset of a integer value, starting at index with count
bits.

The general use case is likely to reverse all bits in a variable, (uint64_t for
example):

uint64_t v;
__builtin_brev64(v, 0, sizeof(v) * 8);

But I thought it might be interesting to have a more general purpose builtin.

Actually, the builtin arguments for reverse should probably match what's
currently available on modern hardware.


[Bug c/57908] New: alignment of arrays allocated stack on amd64/x86_64: 16 bytes ?

2013-07-16 Thread yann at droneaud dot fr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57908

Bug ID: 57908
   Summary: alignment of arrays allocated stack on amd64/x86_64:
16 bytes ?
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: yann at droneaud dot fr

According to System V Application Binary Interface, AMD64 Architecture
Processor Supplement, Draft Version 0.90

Aggregates and Unions
-

An array uses the same alignment as its elements, except that a local or 
global array variable that requires at least 16 bytes, or a C99 local or 
global variable-length array variable, always has alignment of at least 16 
bytes.[4]
No other changes required.

[4] The alignment requirement allows the use of SSE instructions when 
operating on the array.
The compiler cannot in general calculate the size of a variable-length 
array (VLA), but it is expected that most VLAs will require at least 16 
bytes, so it is logical to mandate that VLAs have at least a 16-byte 
alignment.


As I understand the ABI specifications, arrays allocated on stack must be
aligned on 16 bytes boundaries, whatever its length is: eg. an array of 7 bytes
get aligned on 16 bytes boundaries.

A test program seems to verify that, with gcc version 4.8.1 20130603 (Red Hat
4.8.1-1) (GCC) :

 kind name  address   size   alignment   required

   Arrays
   object | u8 | 0x7fffefdd486f |1 | 1 |1
   object |   u8_0 | 0x7fffefdd4860 |8 |32 |1
   object |   u8_1 | 0x7fffefdd4850 |7 |16 |1
   object |   u8_2 | 0x7fffefdd4840 |6 |64 |1
   object |   u8_3 | 0x7fffefdd4830 |5 |16 |1
   object |   u8_4 | 0x7fffefdd4820 |4 |32 |1
   object |   u8_5 | 0x7fffefdd4810 |3 |16 |1
   object |   u8_6 | 0x7fffefdd4800 |2 |  2048 |1
   object |   u8_7 | 0x7fffefdd47ff |1 | 1 |1
   object |   u8_8 | 0x7fffefdd47fe |1 | 2 |1

IMHO it's a waste of memory and this behavor is inconsistent regarding
structure layout: eg. arrays in structure are not aligned on 16 bytes boundary.

But let's say the specification mandate such stack allocation, aligned on 16
bytes boundary.

Then enter LLVM/Clang clang version 3.3 (tags/RELEASE_33/rc3):

 kind name  address   size   alignment   required

   Arrays
   object | u8 | 0x7fff45f4154f |1 | 1 |1
   object |   u8_0 | 0x7fff45f41547 |8 | 1 |1
   object |   u8_1 | 0x7fff45f41540 |7 |64 |1
   object |   u8_2 | 0x7fff45f4153a |6 | 2 |1
   object |   u8_3 | 0x7fff45f41535 |5 | 1 |1
   object |   u8_4 | 0x7fff45f41531 |4 | 1 |1
   object |   u8_5 | 0x7fff45f4152e |3 | 2 |1
   object |   u8_6 | 0x7fff45f4152c |2 | 4 |1
   object |   u8_7 | 0x7fff45f4152b |1 | 1 |1
   object |   u8_8 | 0x7fff45f4152a |1 | 2 |1

It seems that Clang is not aligning arrays on stack to 16 bytes boundary.

Note: for both compiler, tested on Fedora 19, the results were produced with a
test program compiled with default optimisation flag, with -O3, the results are
quite the same.

The source code of the test is available here:
https://gitorious.org/opteya/alignment/blobs/master/stack-alignment.c


[Bug c/57908] alignment of arrays allocated stack on amd64/x86_64: 16 bytes ?

2013-07-16 Thread yann at droneaud dot fr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57908

--- Comment #1 from Yann Droneaud yann at droneaud dot fr ---
Additionally, for ARM target (ARMv7), it seems GCC align arrays on stack to 4
bytes boundary ... but I don't found the ABI specification that require such
alignment.

 kind name  address   size   alignment   required

   Arrays
   object | u8 | 0xf6fff017 |1 | 1 |1
   object |   u8_0 | 0xf6fff00c |8 | 4 |1
   object |   u8_1 | 0xf6fff004 |7 | 4 |1
   object |   u8_2 | 0xf6ffeffc |6 | 4 |1
   object |   u8_3 | 0xf6ffeff4 |5 | 4 |1
   object |   u8_4 | 0xf6ffeff0 |4 |16 |1
   object |   u8_5 | 0xf6ffefec |3 | 4 |1
   object |   u8_6 | 0xf6ffefe8 |2 | 8 |1
   object |   u8_7 | 0xf6ffefe4 |1 | 4 |1
   object |   u8_8 | 0xf6ffefe3 |1 | 1 |1


[Bug target/57908] alignment of arrays allocated stack on amd64/x86_64: 16 bytes ?

2013-07-16 Thread yann at droneaud dot fr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57908

--- Comment #4 from Yann Droneaud yann at droneaud dot fr ---
(In reply to Andrew Pinski from comment #2)
 Your test program is not fully testing things correctly.
  kind name  address   size   alignment   required
object |   u8_5 | 0x7fffefdd4810 |3 |16 |1
object |   u8_6 | 0x7fffefdd4800 |2 |  2048 |1
object |   u8_7 | 0x7fffefdd47ff |1 | 1 |1
 
 Shows why.  There are two variables right next to each other but the
 alignment recorded is 2048 but that was just accidental.  The alignment of
 u8_6 is 16 due to the next variable at 10.

Have you noticed that u8_7 is an array of 1 element only ?
Array of 1 element (bytes) only are not aligned on 16 bytes boundary.
Array of 2 bytes and greater get aligned on 16 bytes boundary.

Should I show another test case ?


[Bug target/57908] alignment of arrays allocated stack on amd64/x86_64: 16 bytes ?

2013-07-16 Thread yann at droneaud dot fr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57908

Yann Droneaud yann at droneaud dot fr changed:

   What|Removed |Added

 Status|RESOLVED|UNCONFIRMED
 Resolution|INVALID |---

--- Comment #5 from Yann Droneaud yann at droneaud dot fr ---
(In reply to Yann Droneaud from comment #4)
 (In reply to Andrew Pinski from comment #2)
  Your test program is not fully testing things correctly.
   kind name  address   size   alignment   required
 object |   u8_5 | 0x7fffefdd4810 |3 |16 |1
 object |   u8_6 | 0x7fffefdd4800 |2 |  2048 |1
 object |   u8_7 | 0x7fffefdd47ff |1 | 1 |1
  
  Shows why.  There are two variables right next to each other but the
  alignment recorded is 2048 but that was just accidental.  The alignment of
  u8_6 is 16 due to the next variable at 10.
 
 Have you noticed that u8_7 is an array of 1 element only ?
 Array of 1 element (bytes) only are not aligned on 16 bytes boundary.
 Array of 2 bytes and greater get aligned on 16 bytes boundary.
 
 Should I show another test case ?

 kind name  address   size   alignment   required

 type |uint8_t |N/A |1 |   N/A |1 
 type | uint8_t[2] |N/A |2 |   N/A |1 

   Arrays
   object |   u8_0 | 0x7fff7671e25f |1 | 1 |1
   object |   u8_1 | 0x7fff7671e250 |3 |16 |1
   object |   u8_2 | 0x7fff7671e240 |7 |64 |1
   object |   u8_3 | 0x7fff7671e230 |5 |16 |1
   object |   u8_4 | 0x7fff7671e220 |2 |32 |1
   object |   u8_5 | 0x7fff7671e21f |1 | 1 |1
   object |   u8_6 | 0x7fff7671e210 |3 |16 |1
   object |   u8_7 | 0x7fff7671e200 |5 |   512 |1
   object |   u8_8 | 0x7fff7671e1f0 |7 |16 |1
   object |   u8_9 | 0x7fff7671e1e0 |2 |32 |1
   object |  u8_10 | 0x7fff7671e1d0 |   11 |16 |1
   object |  u8_11 | 0x7fff7671e1c0 |3 |64 |1
   object |  u8_12 | 0x7fff7671e1b0 |   13 |16 |1
   object |  u8_13 | 0x7fff7671e1a0 |2 |32 |1
   object |  u8_14 | 0x7fff7671e19f |1 | 1 |1
   object |  u8_15 | 0x7fff7671e190 |2 |16 |1


[Bug target/57908] alignment of arrays allocated stack on amd64/x86_64: 16 bytes ?

2013-07-16 Thread yann at droneaud dot fr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57908

--- Comment #6 from Yann Droneaud yann at droneaud dot fr ---
Created attachment 30512
  -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=30512action=edit
Demonstrate stack allocation of array aligned on 16 bytes


[Bug target/57908] alignment of arrays allocated stack on amd64/x86_64: 16 bytes ?

2013-07-16 Thread yann at droneaud dot fr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57908

--- Comment #8 from Yann Droneaud yann at droneaud dot fr ---
Using -Os show different results:

   Arrays
   object |   u8_0 | 0x7fff9b4c05bc |1 | 4 |1
   object |   u8_1 | 0x7fff9b4c05c7 |3 | 1 |1
   object |   u8_2 | 0x7fff9b4c05da |7 | 2 |1
   object |   u8_3 | 0x7fff9b4c05d0 |5 |16 |1
   object |   u8_4 | 0x7fff9b4c05bf |2 | 1 |1
   object |   u8_5 | 0x7fff9b4c05bd |1 | 1 |1
   object |   u8_6 | 0x7fff9b4c05ca |3 | 2 |1
   object |   u8_7 | 0x7fff9b4c05d5 |5 | 1 |1
   object |   u8_8 | 0x7fff9b4c05e1 |7 | 1 |1
   object |   u8_9 | 0x7fff9b4c05c1 |2 | 1 |1
   object |  u8_10 | 0x7fff9b4c05e8 |   11 | 8 |1
   object |  u8_11 | 0x7fff9b4c05cd |3 | 1 |1
   object |  u8_12 | 0x7fff9b4c05f3 |   13 | 1 |1
   object |  u8_13 | 0x7fff9b4c05c3 |2 | 1 |1
   object |  u8_14 | 0x7fff9b4c05be |1 | 2 |1
   object |  u8_15 | 0x7fff9b4c05c5 |2 | 1 |1


So GCC is using 16 bytes to align array allocated on stack by default but it's
not enforcing such alignment.
I guess it's all about optimisation ... but wasting up to 14 bytes to get an
array of 2 bytes aligned might be overkill.

Could someone comment on which optimisation is achieved by aligning such small
arrays ?

Regards.


[Bug target/57908] alignment of arrays allocated stack on amd64/x86_64: 16 bytes ?

2013-07-16 Thread yann at droneaud dot fr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57908

--- Comment #10 from Yann Droneaud yann at droneaud dot fr ---
(In reply to Andrew Pinski from comment #9)
 (In reply to Yann Droneaud from comment #8)
  Could someone comment on which optimisation is achieved by aligning such
  small arrays ?
 
 The simple answer is so each array is more likely to fit into a cache line:
One use of this macro is to increase alignment of medium-size
data to make it all fit in fewer cache lines.  */

Thanks for the investigation.

Initially I thought it would be better to pack such arrays to fit whole cache
line: fewer cache lines will be used and most of the arrays would be already in
cache lines.

But according to http://stackoverflow.com/a/7281770:

On x86 cache lines are 64 bytes, however, to prevent false sharing, you need
to follow the guidelines of the processor you are targeting (intel has some
special notes on its netburst based processors), generally you need to align to
64 bytes for this (intel states that you should also avoid crossing 16 byte
boundries).

This start to make sense to me.

I'm likely buying the argument for global variables but for local variables, I
think they are probably not going to be shared a lot across CPUs. But I haven't
data for this so I won't continue that way.

Thanks a lot for answer my question.


[Bug target/57911] New: alignment of arrays allocated stack on ARM : 4 bytes ?

2013-07-16 Thread yann at droneaud dot fr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57911

Bug ID: 57911
   Summary: alignment of arrays allocated stack on ARM : 4 bytes ?
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: yann at droneaud dot fr

Hi

Following discussion in bug #57908, especially bug #57908 comment #1,
on ARMv7, I'm very surprised that array of bytes are aligned on 4 bytes
boundary when allocated on stack.

Using attachment #30512, I'm able to produce the following results
using GCC arm-none-linux-gnueabi-gcc (Sourcery CodeBench Lite 2013.05-24)
4.7.3.
Another custom GCC 4.7.2 produces same results.

with default option:

 kind name  address   size   alignment   required

 type |uint8_t |N/A |1 |   N/A |1 
 type | uint8_t[2] |N/A |2 |   N/A |1 

   Arrays
   object |   u8_0 | 0xf6fff00c |1 | 4 |1
   object |   u8_1 | 0xf6fff008 |3 | 8 |1
   object |   u8_2 | 0xf6fff000 |7 |  4096 |1
   object |   u8_3 | 0xf6ffeff8 |5 | 8 |1
   object |   u8_4 | 0xf6ffeff4 |2 | 4 |1
   object |   u8_5 | 0xf6ffeff0 |1 |16 |1
   object |   u8_6 | 0xf6ffefec |3 | 4 |1
   object |   u8_7 | 0xf6ffefe4 |5 | 4 |1
   object |   u8_8 | 0xf6ffefdc |7 | 4 |1
   object |   u8_9 | 0xf6ffefd8 |2 | 8 |1
   object |  u8_10 | 0xf6ffefcc |   11 | 4 |1
   object |  u8_11 | 0xf6ffefc8 |3 | 8 |1
   object |  u8_12 | 0xf6ffefb8 |   13 | 8 |1
   object |  u8_13 | 0xf6ffefb4 |2 | 4 |1
   object |  u8_14 | 0xf6ffefb0 |1 |16 |1
   object |  u8_15 | 0xf6ffefac |2 | 4 |1

with -Os:

 kind name  address   size   alignment   required

 type |uint8_t |N/A |1 |   N/A |1 
 type | uint8_t[2] |N/A |2 |   N/A |1 

   Arrays
   object |   u8_0 | 0xf6ffef9c |1 | 4 |1
   object |   u8_1 | 0xf6ffefb8 |3 | 8 |1
   object |   u8_2 | 0xf6ffefd4 |7 | 4 |1
   object |   u8_3 | 0xf6ffefc4 |5 | 4 |1
   object |   u8_4 | 0xf6ffefa8 |2 | 8 |1
   object |   u8_5 | 0xf6ffefa0 |1 |32 |1
   object |   u8_6 | 0xf6ffefbc |3 | 4 |1
   object |   u8_7 | 0xf6ffefcc |5 | 4 |1
   object |   u8_8 | 0xf6ffefdc |7 | 4 |1
   object |   u8_9 | 0xf6ffefac |2 | 4 |1
   object |  u8_10 | 0xf6ffefe4 |   11 | 4 |1
   object |  u8_11 | 0xf6ffefc0 |3 |64 |1
   object |  u8_12 | 0xf6ffeff0 |   13 |16 |1
   object |  u8_13 | 0xf6ffefb0 |2 |16 |1
   object |  u8_14 | 0xf6ffefa4 |1 | 4 |1
   object |  u8_15 | 0xf6ffefb4 |2 | 4 |1


I'm reading AAPCS (IHI0042E) and I don't found any requirement for array
allocated on stack to be aligned on 4 bytes.

It's a pity that -Os, as suggested by Andrew Pinski in bug #57908 comment #7,
doesn't align the array on 1 bytes boundary.


[Bug c/57889] New: Improvement: builtin to return a string from a type (type to string builtin)

2013-07-12 Thread yann at droneaud dot fr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57889

Bug ID: 57889
   Summary: Improvement: builtin to return a string from a type
(type to string builtin)
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: enhancement
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: yann at droneaud dot fr

Hi,

It might be of interest to have a builtin to convert a type name to a string.
Given a type or a variable, the builtin would return the type of it as a
string.
It could be used to build debug messages:


#define ASSERT_NULL(p) do { \
 if ((p) == NULL)   \
printf(%s * %s == NULL\n, __builtin_typestringof(*p), #p); \
} while(0);

Regards.


[Bug other/55899] New: GCC should provide built-ins in stdint.h data types flavor/version/variation

2013-01-07 Thread yann at droneaud dot fr


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55899



 Bug #: 55899

   Summary: GCC should provide built-ins in stdint.h data types

flavor/version/variation

Classification: Unclassified

   Product: gcc

   Version: unknown

Status: UNCONFIRMED

  Severity: enhancement

  Priority: P3

 Component: other

AssignedTo: unassig...@gcc.gnu.org

ReportedBy: y...@droneaud.fr





Built-in functions such as 

 __builtin_clz(unsigned int x)

 __builtin_ctz(unsigned int x)

 __builtin_ffs(unsigned int x)

 etc.

are lacking variant based on C99 stdint.h data type.



Currently there's

 __builtin_clzl(unsigned long x)

 __builtin_clzll(unsigned long long x)



I'd like to have:

 __builtin_clz32(uint32_t x)

 __builtin_clz64(uint64_t x)



This would help to hard code the number of bits when using such construct to

know the number of bit needed to hold a value:



(8 * sizeof(unsigned int)) - __builtin_clz(value)



when value is of type uint32_t:



 32 - __builtin_clz32(value)



Note: there's already __builtin_bswap32(int32_t x) and

__builtin_bswap64(int64_t x)


[Bug c/51579] New: GCC should be able report a warning for usage of parameters marked with __attribute__((unused))

2011-12-16 Thread yann at droneaud dot fr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51579

 Bug #: 51579
   Summary: GCC should be able report a warning for usage of
parameters marked with __attribute__((unused))
Classification: Unclassified
   Product: gcc
   Version: 4.6.2
Status: UNCONFIRMED
  Severity: enhancement
  Priority: P3
 Component: c
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: y...@droneaud.fr


I would like to see GCC emit a warning when a parameter marked as unused is in
fact used in the function. The warning option could be something like
-Wunused-parameter-used

For example, the following code doesn't produce any warning.

int foo (int *ptr, int val __attribute__((unused)))
{
   int res;

   res = *ptr + val;

   return res;
}

It would be interesting to have a warning like this:

test.c: In function 'foo':
test.c:5:21: warning: parameter 'val' is used but marked as unused in
declaration [-Wunused-parameter-used]

Same thing could apply to function, type and variable specified with
__attribute__((unused))

Additionally, a new attribute warn_use could be introduced to enforce the
unused attribute, since unused attribute is not meant to prevent usage:

- This attribute, attached to a function, means that the function is meant to
be possibly unused
- When attached to a type (including a union or a struct), this attribute
means that variables of that type are meant to appear possibly unused
- This attribute, attached to a variable, means that the variable is meant to
be possibly unused


[Bug c/51579] GCC should be able report a warning for usage of parameters marked with __attribute__((unused))

2011-12-16 Thread yann at droneaud dot fr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51579

--- Comment #2 from Yann Droneaud yann at droneaud dot fr 2011-12-16 15:25:41 
UTC ---
(In reply to comment #1)
 I don't think we should start warning each time an __attribute__((unused))
 parameter is actually used. In my experience that's absolutely common and
 pervasive.

That's why it must not be the default behavor,
so I'm not asking for inclusion in -Wunused.

 If the parameter is meant to *never* be used, should be completely
 removed, no?

Sometimes you cannot remove the parameter, since the function signature is
provided by, for example for a callback in some graphic toolkit.

What's the point of specifying that something is not used if your going to use
it anyway :)
If there's no penalty to put __attribute__((unused)), one mad developer could
put __attribute__((unused)) on all functions arguments, just in case.
(but in the end, it's easier to disable warning with -Wno-unused).

Having the warning could help programmer remember to remove the attribute which
is now, in turn, not used.

This would enforce some contract between the function declaration and its own
implementation.

 Or maybe what you are really asking for are unnamed parameters,
 like in C++, which indeed can be handy sometimes when dealing with ABI
 stability issues, etc? Seems something different, however.

Having the C++ unnamed parameter behavor could help, but would require some
preprocessor magic to be fully portable, for example.

#if defined(__GNUC__) || defined(__cplusplus)
# define UNUSED(name)
#else
# define UNUSED(name) unused_ ## name
#endif

int foo (int *ptr, int UNUSED(var))
{
}

Currently, one can do:

#if defined(__GNUC__)
# define UNUSED __attribute__((unused))
#else
# define UNUSED
#endif

int foo (int *ptr, int UNUSED var)
{
}