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

Reply via email to