[Bug tree-optimization/113224] Warning "is used uninitialized" raised for an initialized variable

2024-01-03 Thread gandalf at winds dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113224

--- Comment #3 from gandalf at winds dot org ---
Thank you for the suggestion. I'll try the union.

[Bug tree-optimization/113224] New: Warning "is used uninitialized" raised for an initialized variable

2024-01-03 Thread gandalf at winds dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113224

Bug ID: 113224
   Summary: Warning "is used uninitialized" raised for an
initialized variable
   Product: gcc
   Version: 13.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: gandalf at winds dot org
  Target Milestone: ---
Target: x86_64-pc-linux-gnu

In an attempt to convert a float value bytewise to an integer, this function
returns the following unexpected GCC warnings at optimization level -O2 and -O3
on x86_64:

unsigned int myfunc() {
  float _f=2.5;
  unsigned int *_x=(unsigned int *)&_f;
  return *_x;
}

gcc -O2 -Wall test12.c -c

test12.c: In function 'myfunc':
test12.c:4:10: warning: '_f' is used uninitialized
test12.c:2:9: note: '_f' declared here

It compiles correctly, at least. The warning goes away when
-fno-strict-aliasing is applied.

[Bug target/112615] gcc incorrectly assumes char *x[2]={"str1", "str2"} has 16-byte minimum alignment and generates SSE instructions (e.g. movaps) when accessing this data

2023-11-18 Thread gandalf at winds dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112615

gandalf at winds dot org changed:

   What|Removed |Added

 Resolution|FIXED   |INVALID

[Bug target/112615] gcc incorrectly assumes char *x[2]={"str1", "str2"} has 16-byte minimum alignment and generates SSE instructions (e.g. movaps) when accessing this data

2023-11-18 Thread gandalf at winds dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112615

gandalf at winds dot org changed:

   What|Removed |Added

 Resolution|INVALID |FIXED

--- Comment #3 from gandalf at winds dot org ---
Thank you for the insight. Sounds like a bug in Oracle's compiler then.

I have just finished adding the aligned(8) attribute to glibc's __tzname on my
system and recompiled glibc. I verified this fixed the problem (no segfault).

Thanks much.

[Bug c/112615] New: gcc incorrectly assumes char *x[2]={"str1", "str2"} has 16-byte minimum alignment and generates SSE instructions (e.g. movaps) when accessing this data

2023-11-18 Thread gandalf at winds dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112615

Bug ID: 112615
   Summary: gcc incorrectly assumes char *x[2]={"str1", "str2"}
has 16-byte minimum alignment and generates SSE
instructions (e.g. movaps) when accessing this data
   Product: gcc
   Version: 13.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: gandalf at winds dot org
  Target Milestone: ---

I ran into the following problem while trying to get Oracle 21c to run on
Gentoo OS under glibc-2.38 and GCC 13.2 on x86-64 with SSE instructions
enabled.

glibc-2.38's time/tzset.c file (see
https://github.com/bminor/glibc/blob/master/time/tzset.c) has the following
non-static declaration on line 31:

char *__tzname[2] = { (char *) "GMT", (char *) "GMT" };

GCC wrongly assumes that this variable __tzname has a minimum alignment of 16
bytes instead of 8. GCC thus generates the following assembly instructions for
this portion of __tzset_parse_tz() when compiling with -march=x86-64:

327   /* Get the standard time zone abbreviations.  */
328   if (parse_tzname (, 0) && parse_offset (, 0))
   0x0a6f <+63>:movups %xmm0,0x0(%rip)# 0xa76
<__tzset_parse_tz+70>
   0x0a76 <+70>:movups %xmm0,0x0(%rip)# 0xa7d
<__tzset_parse_tz+77>
   0x0a7d <+77>:movups %xmm0,0x0(%rip)# 0xa84
<__tzset_parse_tz+84>
   0x0a84 <+84>:movups %xmm0,0x0(%rip)# 0xa8b
<__tzset_parse_tz+91>
   0x0a8b <+91>:call   0x440 
   0x0a90 <+96>:test   %al,%al
   0x0a92 <+98>:jne0xac8 <__tzset_parse_tz+152>
   0x0a94 <+100>:   movq   0x0(%rip),%xmm0# 0xa9c
<__tzset_parse_tz+108>

132   __tzname[1] = (char *) tz_rules[1].name;
   0x0a9c <+108>:   xor%eax,%eax
   0x0a9e <+110>:   xor%edx,%edx
   0x0aa0 <+112>:   pinsrq $0x1,0x0(%rip),%xmm0# 0xaab
<__tzset_parse_tz+123>

129   __daylight = tz_rules[0].offset != tz_rules[1].offset;
   0x0aab <+123>:   mov%edx,0x0(%rip)# 0xab1
<__tzset_parse_tz+129>

130   __timezone = -tz_rules[0].offset;
   0x0ab1 <+129>:   mov%rax,0x0(%rip)# 0xab8
<__tzset_parse_tz+136>

131   __tzname[0] = (char *) tz_rules[0].name;
132   __tzname[1] = (char *) tz_rules[1].name;
   0x0ab8 <+136>:   movaps %xmm0,0x0(%rip)# 0xabf
<__tzset_parse_tz+143>

In the above, line 131 and 132 are combined into a "movaps" instruction that
requires 16-byte alignment to work properly. However, if a C program is
compiled with a variable called __tzname that is not 16-byte aligned (due to
the fact that char* only requires 8-byte alignment), and this is then linked to
glibc (causing the locally defined __tzname to override the one declared in
glibc), and the if(parse_tzname()) check on line 328 fails due to an invalid TZ
environment variable setting (such as is the case when using Oracle 21c on
Gentoo), the movaps instruction above causes a segmentation fault. Here is an
example test.c C program:

#include 
#include 

/* Specifically align __tzname to a non-16-byte boundary */
__attribute__((aligned(8))) char *__tzname[2]={"GMT", "GMT"};

char *x="xx";  // This is here to take up the first 8 bytes in .data

int main()
{
  struct tm tm={};
  printf("%ld\n", mktime());
  return 0;
}

$ gcc -O3 -march=x86-64 test.c -o test -Wall -ggdb3
$ nm test | grep __tzname
00404028 D __tzname
$ ./test
-2209057200
$ TZ=xx ./test
Segmentation fault (core dumped)

Removing the __attribute__((aligned(8))) from the test.c program, as follows,
causes the following change:

#include 
#include 

/* GCC now aligns __tzname to 16 bytes */
char *__tzname[2]={"GMT", "GMT"};
char *x="xx";

int main()
{
  struct tm tm={};
  printf("%ld\n", mktime());
  return 0;
}

$ gcc -O3 -march=x86-64 test.c -o test -Wall -ggdb3
$ nm test | grep __tzname
00404030 D __tzname
$ ./test
-2209057200
$ TZ=xx ./test
-2209057200

In the examples above, the "x" variable is used to consume 8 bytes in .data, so
that the next available address for "__tzname" is 0x404028.

Assuming a minimum alignment of 16 for __tzname only makes sense when you're
either compiling the whole program or when __tzname is static, but GCC should
not do this when the variable is non-static (as is the case when tzset.o is
compiled inside the glibc source package).

I should clarify that optimizing the variable's address to use 16-byte
alignment can be ideal for data storage vs cache-line boundaries and so this
optimization should likely remain. But the instructions acting on this data
area must assume an 8-byte minimum alignment here, not 16.

[Bug target/109236] [avr] Invalid code of signed 16-bit compare optimization

2023-03-21 Thread gandalf at winds dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109236

gandalf at winds dot org changed:

   What|Removed |Added

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

--- Comment #2 from gandalf at winds dot org ---
Thank you, I hadn't thought of that at all. That was precisely my problem and I
developed a work-around. Not a bug.

[Bug c/109236] New: [avr] Invalid code of signed 16-bit compare optimization

2023-03-21 Thread gandalf at winds dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109236

Bug ID: 109236
   Summary: [avr] Invalid code of signed 16-bit compare
optimization
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: gandalf at winds dot org
  Target Milestone: ---

I'm seeing incorrect code when -O1 or higher is used on AVR (atmega1284p). The
compiler generates code that compares "x" to "y", instead of performing the
subtraction and comparing against 0. This subtraction matters since "x" and "y"
are signed 16-bit variables, and the math in the expression "x-y <= 0" stays as
16-bit in AVR (as opposed to being promoted to 32-bit ints in e.g. x86).

gcc -v:

Using built-in specs.
Reading specs from /usr/local/avr/lib/gcc/avr/12.2.0/device-specs/specs-avr2
COLLECT_GCC=avr-gcc
COLLECT_LTO_WRAPPER=/usr/local/avr/libexec/gcc/avr/12.2.0/lto-wrapper
Target: avr
Configured with: ../configure --target=avr --prefix=/usr/local/avr
--disable-nls --enable-languages=c --disable-bootstrap --disable-libssp
Thread model: single
Supported LTO compression algorithms: zlib zstd
gcc version 12.2.0 (GCC)

Sample code:

_Bool compare(short x, short y)
{
  return (x-y <= 0);
}

Compiled using: gcc -O1 -mmcu=atmega1284p -c -o test.o test.c

ASM result:

 :
   0:   9c 01   movwr18, r24
   2:   81 e0   ldi r24, 0x01   ; 1
   4:   62 17   cp  r22, r18< X compared directly to Y;
no subtraction
   6:   73 07   cpc r23, r19
   8:   04 f4   brge.+0 ; 0xa 
   a:   80 e0   ldi r24, 0x00   ; 0

000c <.L2>:
   c:   08 95   ret

I instead expect to see a subtraction between r22:23 and r18:19, then a compare
against r1 (zero).

The following testcase causes an incorrect computation:

compare(-30737, 24799) returns 1 on AVR; expected 0.  (-30737 - (24799)) as
signed 16-bit = 1, which is not <= 0.

For the record, changing the function to "return ((short)(x-y) <= 0)" produces
the same incorrect code.

Compiling the function without optimization correctly returns 0.

It's possible other signed variable sizes besides 16-bit have the same problem,
but I did not test this.

[Bug debug/107012] [debug, dwarf-5] Missing line information for evaluating macros

2022-09-22 Thread gandalf at winds dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107012

--- Comment #1 from gandalf at winds dot org ---
Created attachment 53615
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53615=edit
objdump output for dwarf-5

[Bug debug/107012] New: [debug, dwarf-5] Missing line information for evaluating macros

2022-09-22 Thread gandalf at winds dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107012

Bug ID: 107012
   Summary: [debug, dwarf-5] Missing line information for
evaluating macros
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: debug
  Assignee: unassigned at gcc dot gnu.org
  Reporter: gandalf at winds dot org
  Target Milestone: ---

Created attachment 53614
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53614=edit
objdump output for dwarf-4

GCC 12 now defaults to outputting debug information via dwarf-5. Compared to
dwarf-4 (which works), gdb's interpretation of dwarf-5 seems to show that we're
missing the correct line information, which causes gdb to not be able to
correctly find and evaluate a macro on the command line due to being in the
wrong context. It's not clear whether gcc is not correctly emitting all the
information, or if gdb is not correctly reading all the information.

Breaking at the "main" function and attempting to run "info macro X" produces
the error message, "The symbol `X' has no definition as a C/C++ preprocessor
macro at macro.c:-1".

The same behavior happens when breaking at any other point in a C program, and
not just at "main".

In both examples below, the breakpoint output shows we're at line 5 in macro.c:

$ cat macro.c
#define TEST_MACRO 42

int main()
{
  return 0;
}

### DWARF-4 Example ###

$ gcc -O3 -ggdb3 -gdwarf-4 macro.c -o macro
$ gdb macro 
GNU gdb (Gentoo 12.1 vanilla) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from macro...
(gdb) break main
Breakpoint 1 at 0x401020: file macro.c, line 5.
(gdb) run
Starting program: /g/macro 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Breakpoint 1, main () at macro.c:5
5 return 0;
(gdb) info macro TEST_MACRO
Defined at /g/macro.c:1
#define TEST_MACRO 42
(gdb) p TEST_MACRO
$1 = 42
(gdb) quit

### DWARF-5 EXAMPLE ###

$ gcc -O3 -ggdb3 -gdwarf-5 macro.c -o macro
$ gdb macro
GNU gdb (Gentoo 12.1 vanilla) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from macro...
(gdb) break main
Breakpoint 1 at 0x401020: file macro.c, line 5.
(gdb) run
Starting program: /g/macro 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Breakpoint 1, main () at macro.c:5
5 return 0;
(gdb) info macro TEST_MACRO
The symbol `TEST_MACRO' has no definition as a C/C++ preprocessor macro
at /g/macro.c:-1
(gdb) p TEST_MACRO
No symbol "TEST_MACRO" in current context.
(gdb) quit


Software versions:

$ gdb -v
GNU gdb (Gentoo 12.1 vanilla) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/12.2.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with:
/var/tmp/portage/sys-devel/gcc-12.2.0/work/gcc-12.2.0/configure
--host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --prefix=/usr
--bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/12.2.0
--includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include
--datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/12.2.0
--mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/12.2.0/man
--infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/12.2.0/info
--with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include/g++-v12

[Bug tree-optimization/100256] New: spurious stringop-overflow warning with memset(..., sizeof(dest)) on variable-length array at -O3

2021-04-25 Thread gandalf at winds dot org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100256

Bug ID: 100256
   Summary: spurious stringop-overflow warning with memset(...,
sizeof(dest)) on variable-length array at -O3
   Product: gcc
   Version: 10.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: gandalf at winds dot org
  Target Milestone: ---

When 'j_degree' is unknown per the function below, -O3 causes a
stringop-overflow warning to be emitted on memset() with strange region sizes.
The code snapshot below is the result of trying to simplify/remove as many
lines as I could while still causing the warning to generate.

GCC 10.3.0 and GCC 11.0.1 commit a6f018fcc6ce9236ff37eac33b01a0a80103c9f6,
running on x86_64-pc-linux-gnu (Gentoo):

---

typedef long unsigned int size_t;

extern void *memset (void *__s, int __c, size_t __n) __attribute__
((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));

extern void *calloc (size_t __nmemb, size_t __size)
 __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__))
__attribute__ ((__alloc_size__ (1, 2))) ;

static void setup_matrix(double **ppd_xx, double *pd_xy, int j_degree)
{
  int kk;
  double ad_xsum[j_degree*2 + 1];

  memset(ad_xsum,0,sizeof(ad_xsum));

  for(kk=0; kk < j_degree*2 + 1; kk++) {
ad_xsum[kk]++;
if(kk < j_degree + 1)
  pd_xy[kk]++;
  }
}

void polyfit(int j_degree, double ad_coef[], double *pd_xy, double **ppd_xx)
{
  int jj;

  for(jj=0;jj