[Bug tree-optimization/30016] [4.0/4.1/4.2/4.3 Regression] internal compiler error: in convert_move, at expr.c:362

dimock at csail dot mit dot edu gcc-bugzilla@gcc.gnu.org
Thu Nov 30 15:56:00 GMT 2006



------- Comment #3 from dimock at csail dot mit dot edu  2006-11-30 15:55 -------
(In reply to comment #2)
> ... first this code should be rejected which it was in 3.2.3:
> t.cc:38: invalid reinterpret_cast from type `vector float' to type `__v4F'

(0) I don't have 3.2.3 handy, but have 3.4.3 which also rejects the code. But
3.4.3 also rejects a lot of vector code which does not use reinterpret_cast on
vectors.  In fact it is difficult to write useful code for manipulating vectors
in versions of gcc before 4.0.

(1) I don't have the spec in front of me, but working from "C++ in a nutshell"
I believe that the code can not be rejected by a conforming C++ implementation.
You can have a compile-time error on reinterpret_cast only if it is used to
blur
the distinction between member functions of a class and other functions, either
by casting directly or to an object.
  Since behavior after a reinterpret_cast is undefined, you could issue a
warning and produce non-intuitive code, but the fact that the submitted error
case ran with C-style casts as a .c file and crashed the compiler with
reinterpret_cast as a .cpp file makes me believe that the gcc C++ compiler
should also produce working code for this case.
  Once again: I do not have a spec in front of me, someone should check the C++
spec.

(2a) [portability and performance] The standard way of handling the vector
extensions in gcc is to make a union of the vector and an array of the same
size so that the vector can be loaded or unloaded without making use of
machine-specific (non-portable) intrinsics or builtins.  I noticed that in my
machine-generated code which used unions everywhere, that gcc was able to
better optimize code if I took out unions where they were not needed (removing
unused unions produced different .s files on -mcpu=G4 on a PowerPC, and the
code with unions removed ran faster.  Performance not checked on pentium/SSE
since my real target is PPE/SPE.)  

(2b) Intuitively, casting between two types with the same memory representation
and alignment should work.  Also, it does work on most occasions.  The
following example casts vectors as both l-values and as r-values and produces
the expected output under gcc 4.1.1:

#include <stdio.h>
typedef float __v_4F __attribute__ ((vector_size (16)));
union __v_4Fa {float a[4];
               __v_4F v;  };

__v_4F x = {1.0f,2.0f,3.0f,4.0f};

int main(int argc, char** argv) {
  reinterpret_cast<__v_4Fa>(x).a[2] = -1.0f;
  printf ("%f %f\n", reinterpret_cast<__v_4Fa>(x).a[1], 
          reinterpret_cast<__v_4Fa>(x).a[2]);
  return 0;
}

$ gcc -O3 -o cpp-casting.out cpp-casting.cpp -lstdc++
$ ./cpp-casting.out
2.000000 -1.000000


This above code also works if I have
struct __v_4Fa {float a[4] __attribute__ ((aligned (16)));};
which also crashes the original submitted program (but I use unions since I am
trying to generate similar code for C and for C++ and gcc 4.1.1 C compiler
would reject casting to the struct, or to a union not containing a __v_4F
component).

(3) By the way: Your reduced test case also compiles without crashing on my
copy of gcc version 4.1.1 20060525 (Red Hat 4.1.1-1).  
  You seem to have caught a similar bug, but either your version of gcc is
different from the one that I reported on, or you switches are different. 


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30016



More information about the Gcc-bugs mailing list