[Bug c/114366] New: computed labels do not reflect true values of instruction pointer ranges when function is inlined

2024-03-16 Thread godmar at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114366

Bug ID: 114366
   Summary: computed labels do not reflect true values of
instruction pointer ranges when function is inlined
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: godmar at gmail dot com
  Target Milestone: ---

Created attachment 57718
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=57718=edit
using labels as values example

Hi, we recently got tripped up by the following:

```c
#include 

void *beginPtr, *endPtr;
int x;
static void smallfunction(void)
{
beginPtr = &
endPtr = &
begin:
x++;
end:
}

int
main()
{
smallfunction();
assert(beginPtr < endPtr);
}
```
When compiled with `-O0`, this program completes successfully. When compiled
with `-O2`, this program fails its assertion because the following assembly
code is produced:

```
.L2:
.L3:
leaq.L2(%rip), %rdx
leaq.L3(%rip), %rax
addl$1, x(%rip)
```

which IMO should be something like:
```
.L2:
leaq.L2(%rip), %rdx
leaq.L3(%rip), %rax
addl$1, x(%rip)
.L3:
```

I understand that using labels as values is a GCC extension, and I have read
the comment in the documentation [1] that warns that & might have a
different value if a function is inlined.  (Adding the noinline attribute fixes
the problem at the cost of some performance.)  Also note that "different
values" is not the same as not being computed correctly.

We encountered this problem building an exception handler.

I will note that gcc will not inline the function if the computed values are
actually used in a goto statement; when trying to force it to inline it, it
throws an error.

Is this a bug, or undocumented behavior? Perhaps the documentation should be
clarified.  

[1] https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html

[Bug tree-optimization/105051] consider not combining malloc + memset to calloc when inside calloc itself

2022-03-25 Thread godmar at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105051

--- Comment #4 from Godmar Back  ---
Don't let perfect be the enemy of good.  IMO, the detection doesn't need to be
perfect in the sense of not having false negatives.  All 3 bug reports of the
calloc implementations you broke called malloc + memset directly in calloc,
something that (I'd guess?) should be more readily detectable.

[Bug tree-optimization/105051] consider not combining malloc + memset to calloc when inside calloc itself

2022-03-24 Thread godmar at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105051

--- Comment #2 from Godmar Back  ---
Thank you for your reply.  

To make sure I understand, the only work-around is to completely disable all
builtins (as in -fno-builtin), or is using `-fno-builtin-memset` as I proposed
sufficient?

I'm not sure why this bug is invalid, either. To me, applying this optimization
inside `calloc` seems invalid.

[Bug tree-optimization/105051] New: consider not combining malloc + memset to calloc when inside calloc itself

2022-03-24 Thread godmar at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105051

Bug ID: 105051
   Summary: consider not combining malloc + memset to calloc when
inside calloc itself
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: godmar at gmail dot com
  Target Milestone: ---

gcc 8.5.0 (and later) just broke our 18-year-old calloc implementation, which
goes like this:

void *
calloc (size_t a, size_t b)
{
  /* Calculate block size and make sure it fits in size_t. */
  size_t size = a * b;

  /* Allocate and zero memory. */
  void *p = malloc (size);
  if (p != NULL)
memset (p, 0, size);

  return p;
}

by producing this ingenuous code sequence:

calloc:
imulq   %rsi, %rdi
movl$1, %esi
jmp calloc


I believe that this is due to an optimization whereby a sequence of malloc
followed by memset is transformed into a call to calloc.

My suggestion would be to suppress this optimization inside a function that is
itself called calloc as it leads to an infinite loop.

I'm also curious what the proper work-around is.  Is it `-fno-builtin-memset`?

I discovered this in 8.5.0 but Godbolt says it's present in the trunk as of
now:
https://godbolt.org/z/MKMT98qnr

This may be related to Bug #83022

[Bug c/99588] New: variable set but not used warning on static _Atomic assignment

2021-03-14 Thread godmar at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99588

Bug ID: 99588
   Summary: variable set but not used warning on static _Atomic
assignment
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: godmar at gmail dot com
  Target Milestone: ---

A student shared this program with me:

#include 
#include 

void test() {
static _Atomic int x = 0;
printf("%d\n", x += 1);
}

int main(int argc, char **argv) {
for(int i = 0; i < 10; i++) {
test();
}
}

which on the current x86_64 trunk (and earlier versions) as per godbolt yields
a warning:

: In function 'test':
:5:24: warning: variable 'x' set but not used
[-Wunused-but-set-variable]
5 | static _Atomic int x = 0;
  |^
Compiler returned: 0

If the _Atomic modifier is removed, the warning disappears. Is this kosher?