This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[TESTCASE] gcc miscompiles Altivec code


I distilled a (not so) small example for code being miscompiled
by gcc from yesterday on linux-ppc.
This one will segfault on my maschine when compiled with -O0.

Note, originally the code was a bit more complex but then I replaced
some additions by assignments in do_something which does the same for
The unused const vector signed short zeros plays quite an important
role here; removing it will make the case pass at -O0. For some reason
gcc is emitting wrong code for a (in this case unused) vector when
creating some register pressure.

I'll check whether the result at -O2 is correct soonish as the code from
which this testcase is derived is miscompiled at -O2 (not segfaulting)
and -O0 (with segfault) and report back later.

#include <altivec.h>
#include <malloc.h>

#define Transpose(input, output) \
{ \
  vector signed short a0, a1, a2, a3, a4, a5, a6, a7; \
  vector signed short b0, b1, b2, b3, b4, b5, b6, b7; \
  b0 = vec_mergeh (input[0], input[4]);      \
  b1 = vec_mergel (input[0], input[4]);      \
  b2 = vec_mergeh (input[1], input[5]);      \
  b3 = vec_mergel (input[1], input[5]);      \
  b4 = vec_mergeh (input[2], input[6]);      \
  b5 = vec_mergel (input[2], input[6]);      \
  b6 = vec_mergeh (input[3], input[7]);      \
  b7 = vec_mergel (input[3], input[7]);      \
  a0 = vec_mergeh (b0, b4);                  \
  a1 = vec_mergel (b0, b4);                  \
  a2 = vec_mergeh (b1, b5);                  \
  a3 = vec_mergel (b1, b5);                  \
  a4 = vec_mergeh (b2, b6);                  \
  a5 = vec_mergel (b2, b6);                  \
  a6 = vec_mergeh (b3, b7);                  \
  a7 = vec_mergel (b3, b7);                  \
  output[0] = vec_mergeh (a0, a4);           \
  output[1] = vec_mergel (a0, a4);           \
  output[2] = vec_mergeh (a1, a5);           \
  output[3] = vec_mergel (a1, a5);           \
  output[4] = vec_mergeh (a2, a6);           \
  output[5] = vec_mergel (a2, a6);           \
  output[6] = vec_mergeh (a3, a7);           \
  output[7] = vec_mergel (a3, a7);           \
do_something (signed short *mem)
  const vector signed short zeros = (vector signed short) {0,0,0,0,0,0,0};
  vector signed short *vec;
  vector signed short v1[8], v2[8];

  vec = (vector signed short *) mem;
  v1[0] = vec[0];
  v1[1] = vec[1];
  v1[2] = vec[2];
  v1[3] = vec[3];
  v1[4] = vec[4];
  v1[5] = vec[5];
  v1[6] = vec[6];
  v1[7] = vec[7];

  Transpose (v1, v2); 
  Transpose (v2, v1); 
  vec[0] = v1[0];
  vec[1] = v1[1];
  vec[2] = v1[2];
  vec[3] = v1[3];
  vec[4] = v1[4];
  vec[5] = v1[5];
  vec[6] = v1[6];
  vec[7] = v1[7];

main (void)
  void *mem = memalign (128, 16);
  if (mem)
    do_something (mem);
    free (mem);
  return 0;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]