Your message dated Wed, 29 May 2024 15:34:31 +0200
with message-id <zlcu5yd8wzm3y...@ariel.home>
and subject line Re: Bug#1070299: gcc-14: Wrong vectorized code generated with
-O3, ok without -O.
has caused the Debian Bug report #1070299,
regarding gcc-14: Wrong vectorized code generated with -O3, ok without -O.
to be marked as done.
This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.
(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact ow...@bugs.debian.org
immediately.)
--
1070299: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1070299
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems
--- Begin Message ---
Package: gcc-14
Version: 14-20240429-1
Severity: important
X-Debbugs-Cc: f96h...@chalmers.se
Dear Maintainer,
When compiling the attached code, the pexpo_keep_min() function fails
to handle the fifth item in the list if it was compiled with -O3.
Compiled without an -O option, it works as expected.
I have looked a bit, but not deeply, in the assembler code, and it looks
like the first four items are handled with an vectorized operation.
Then the fifth item is 'forgotten'.
The problem also applies to 14-20240330-1. Does not happen with 13.2.0-23.
Compiling the offending function in a separate file, since if the printf()
is present with the compilation, the issue does not manifest.
The expected output is
100 200 300 400 500
The bad output is
100 200 300 400 50000
Best regards,
Håkan
-- System Information:
Debian Release: trixie/sid
APT prefers unstable
APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)
Kernel: Linux 6.1.0-20-amd64 (SMP w/8 CPU threads; PREEMPT)
Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_FIRMWARE_WORKAROUND,
TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE
Locale: LANG=C, LC_CTYPE=C.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: unable to detect
Versions of packages gcc-14 depends on:
ii binutils 2.42-4
ii gcc-14-base 14-20240429-1
ii gcc-14-x86-64-linux-gnu 14-20240429-1
Versions of packages gcc-14 recommends:
ii libc6-dev 2.37-19
Versions of packages gcc-14 suggests:
pn gcc-14-doc <none>
pn gcc-14-locales <none>
pn gcc-14-multilib <none>
-- no debconf information
*** prime_factor.c
#include "prime_factor.h"
void pexpo_keep_min(struct prime_exponents *a,
const struct prime_exponents *b)
{
int i;
for (i = 0; i < a->num_blocks; i++)
{
a->expo[i] =
(b->expo[i] < a->expo[i]) ?
b->expo[i] : a->expo[i];
}
}
*** prime_factor.h
#include <stdint.h>
typedef int32_t prime_exp_t;
struct prime_exponents
{
int num_blocks;
union
{
prime_exp_t expo[4];
};
};
void pexpo_keep_min(struct prime_exponents *keep_fpf,
const struct prime_exponents *in_fpf);
*** test.c
#include "prime_factor.h"
#include <stdio.h>
int test(struct prime_exponents *a, struct prime_exponents *b)
{
a->num_blocks = 5;
a->expo[0] = 10000;
a->expo[1] = 20000;
a->expo[2] = 30000;
a->expo[3] = 40000;
a->expo[4] = 50000;
b->num_blocks = 5;
b->expo[0] = 100;
b->expo[1] = 200;
b->expo[2] = 300;
b->expo[3] = 400;
b->expo[4] = 500;
pexpo_keep_min(a, b);
printf ("%d %d %d %d %d\n",
a->expo[0],
a->expo[1],
a->expo[2],
a->expo[3],
a->expo[4]);
}
int main()
{
int area1[16];
int area2[16];
test((struct prime_exponents *) area1,
(struct prime_exponents *) area2);
return 0;
}
*** run.sh
gcc-14 prime_factor.c -c -o pf-O3.o -O3
gcc-14 prime_factor.c -c -o pf.o
gcc-14 test.c -c -o test.o -O3
gcc-14 test.o pf-O3.o -o test-O3
gcc-14 test.o pf.o -o test
./test-O3
./test
--- End Message ---
--- Begin Message ---
Hi Håkan,
On 2024-05-03 12:27, Håkan T Johansson wrote:
> When compiling the attached code, the pexpo_keep_min() function fails
> to handle the fifth item in the list if it was compiled with -O3.
[...]
> struct prime_exponents
> {
> int num_blocks;
> union
> {
> prime_exp_t expo[4];
> };
> };
> a->num_blocks = 5;
> a->expo[0] = 10000;
> a->expo[1] = 20000;
> a->expo[2] = 30000;
> a->expo[3] = 40000;
> a->expo[4] = 50000;
Building the code with -Wall, gcc finds that there is an out-of-bound
array access right there. By bumping the size of expo to 5 in
prime_factor.h the code works fine at all optimization levels.
One gotcha is that the issue is only caught at O2 or O3 because the
expensive analysis passes which enable these to be caught only happen
when certain optimisation steps are taken.
Here's the full output when building with -Wall:
$ gcc-14 test.c -c -o test.o -O3 -Wall
test.c: In function 'test':
test.c:28:1: warning: control reaches end of non-void function [-Wreturn-type]
28 | }
| ^
test.c:11:10: warning: array subscript 4 is above array bounds of
'prime_exp_t[4]' {aka 'int[4]'} [-Warray-bounds=]
11 | a->expo[4] = 50000;
| ~~~~~~~^~~
In file included from test.c:1:
prime_factor.h:10:22: note: while referencing 'expo'
10 | prime_exp_t expo[4];
| ^~~~
test.c:18:10: warning: array subscript 4 is above array bounds of
'prime_exp_t[4]' {aka 'int[4]'} [-Warray-bounds=]
18 | b->expo[4] = 500;
| ~~~~~~~^~~
prime_factor.h:10:22: note: while referencing 'expo'
10 | prime_exp_t expo[4];
| ^~~~
test.c:22:3: warning: array subscript 4 is above array bounds of
'prime_exp_t[4]' {aka 'int[4]'} [-Warray-bounds=]
22 | printf ("%d %d %d %d %d\n",
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
23 | a->expo[0],
| ~~~~~~~~~~~
24 | a->expo[1],
| ~~~~~~~~~~~
25 | a->expo[2],
| ~~~~~~~~~~~
26 | a->expo[3],
| ~~~~~~~~~~~
27 | a->expo[4]);
| ~~~~~~~~~~~
prime_factor.h:10:22: note: while referencing 'expo'
10 | prime_exp_t expo[4];
| ^~~~
--- End Message ---