Bug 17415 - 3dNOW and gcc3.3 possible oddities
Summary: 3dNOW and gcc3.3 possible oddities
Status: RESOLVED DUPLICATE of bug 19161
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 3.3
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: ssemmx, wrong-code
Depends on:
Blocks:
 
Reported: 2004-09-11 07:54 UTC by plm
Modified: 2005-07-23 22:49 UTC (History)
1 user (show)

See Also:
Host:
Target: i686-pc-linux-gnu (3dnow)
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Non-C++ Example (307 bytes, text/plain)
2004-09-13 11:07 UTC, Francis Whittle
Details

Note You need to log in before you can comment on or make changes to this bug.
Description plm 2004-09-11 07:54:23 UTC
I was mucking around with 3dNOW and gcc3.3, and I think I've found a bug. As you
can see, the result in vector 'c' is correct, but the input vector 'a' has been
damaged.

$ cat test.cc

#include <stdio.h>

typedef int V2SF __attribute__((mode(V2SF)));

struct vec2f {
  union {
    V2SF vec;
    struct {
      float x;
      float y;
    };
  };

  vec2f(){};
  vec2f( const vec2f& v )
  : vec(v.vec)
    {};
  vec2f( const V2SF& v )
  : vec(v)
    {};
  vec2f( float x, float y)
  : x(x), y(y)
    {};
};


inline vec2f mul( const vec2f &a, const vec2f &b )
{ return vec2f( __builtin_ia32_pfmul(a.vec,b.vec) ); }


int main()
{
  vec2f a( 1.0, 2.0 );
  vec2f b( 3.0, 4.0 );

  printf( "a = %g %g\n", a.x, a.y );
  printf( "b = %g %g\n", b.x, b.y );
  printf( "mul\n" );
  vec2f c = mul(a,b);
  printf( "a = %g %g\n", a.x, a.y );
  printf( "b = %g %g\n", b.x, b.y );
  printf( "c = %g %g\n", c.x, c.y );
  return 0;
};


$ g++ -o test -O3 -fno-strict-aliasing -march=athlon-xp
      -mmmx -msse -m3dnow test.cc
$ ./test
a = 1 2
b = 3 4
mul
a = 1 0
b = 3 4
c = 3 8

One of the local users had a look at this any said

  with everything except -O3 we get:

  ./test
  a = 1 2
  b = 3 4
  mul
  a = 1 nan
  b = 3 4
  c = 3 8

  Very interesting.

  with -march=i586:
   ./test

  a = 1 2
  b = 3 4
  mul
  a = 0 0
  b = 3 4
  c = 3 8

  -march=[i486,i386]:
  a = nan 2

  Combinations of the other -m flags don't seem to make a difference, 
  (except if you remove -m3dnow, where it fails at compile, oddly 
  enough due to the lack of a __builtin_ia32_pfmul function.)

  That's some very strange behaivour.  Sorry I can't help.. 


It's quite possible that I'm missing something obvious here. The manual is a bit
sparse on this matter. Especially how to get data into and out of the vectors.
Comment 1 Francis Whittle 2004-09-13 11:07:53 UTC
Created attachment 7119 [details]
Non-C++ Example

Not just in C++, assured.  The error is in the builtins.

An example in C pour vous.
Comment 2 Francis Whittle 2004-09-13 11:23:13 UTC
(Follow-up to comment #1)
(Sorry about the bugspam)
This yields more or less the same effect:

$ gcc-3.3 -O3 -m3dnow -o 3dnow_test 3dnow-test.c
$ ./3dnow_test
a = [1 2]
b = [3 4]
mul
a = [1 0]
b = [3 4]
c = [3 8]

Oddly enough, in 3.5 we get a different result....

gcc-3.5, -O3 -m3dnow

a = [1 2]
b = [3 4]
mul
a = [nan 2]
b = [3 4]
c = [nan 8]

O0, 3dnow

a = [1 2]
b = [3 4]
mul
a = [1 nan]
b = [3 4]
c = [nan 8]

O1, 3dnow

a = [1 2]
b = [3 4]
mul
a = [1 nan]
b = [3 4]
c = [3 8]

O3, 3dnow, arch=athlon

a = [1 2]
b = [3 4]
mul
a = [nan 2]
b = [3 4]
c = [3 8]

Comment 3 Steven Bosscher 2004-12-19 15:05:27 UTC
With GCC4 (CVS HEAD) I can't compile the test case:  
  
t.cc:1: warning: specifying vector types with __attribute__ ((mode)) is  
deprecated  
t.cc:1: warning: use __attribute__ ((vector_size)) instead  
t.cc:1: error: mode 'V2SF' applied to inappropriate type  
t.cc: In function 'vec2f mul(const vec2f&, const vec2f&)':  
t.cc:26: error: '__builtin_ia32_pfmul' was not declared in this scope  
  
With gcc 3.3.4, I also get:  
t.cc: In function `vec2f mul(const vec2f&, const vec2f&)':  
t.cc:28: error: `__builtin_ia32_pfmul' undeclared (first use this function)  
t.cc:28: error: (Each undeclared identifier is reported only once for each  
   function it appears in.)  
  
For the C test case, I get: 
t.c: In function `mul': 
t.c:15: error: cast to union type from type not present in union 
 
Comment 4 Andrew Pinski 2005-01-15 08:17:06 UTC
To fix the compiling C++/C example use the following code:
typedef float V2SF __attribute__((mode(V2SF)));
Comment 5 Richard Henderson 2005-01-18 09:52:44 UTC

*** This bug has been marked as a duplicate of 19161 ***