[Bug c++/54498] New: incorrect code generation from g++ -O on x86_64

2012-09-05 Thread stevenj at alum dot mit.edu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54498

 Bug #: 54498
   Summary: incorrect code generation from g++ -O on x86_64
Classification: Unclassified
   Product: gcc
   Version: 4.7.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: stev...@alum.mit.edu


Created attachment 28136
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=28136
preprocessed source exhibiting the problem

The attached preprocessed source (bug.ii) illustrates an apparent incorrect
code generation when it is compiled with g++ -O version 4.7.1 on x86_64 (Debian
GNU/Linux).

The program executes two iterations of a loop, calling a function that returns
two slightly different complex numbers in the two iterations.  After the second
iteration, it prints the absolute value of the difference.  The correct output
(when compiled without optimization) is:

   ft (it = 0) = -491.697+887.05i
   ft (it = 1) = -491.692+887.026i
   abs(ft - prev_ft) = 0.0245153

(0.0245153 is the correct absolute difference of the two previous numbers.) 
When compiled with -O, it produces:

   ft (it = 0) = -491.697+887.05i
   ft (it = 1) = -491.692+887.026i
   abs(ft - prev_ft) = 491.692

Note that the first two numbers are the same, but the absolute value of the
difference is wrong.

The problem disappears if I use g++ 4.4.5, or if I make minor changes to the
code; I've tried to boil it down to the minimal code that exhibits the problem.

Steven

PS. The preprocessed source is rather long only because it #includes 
and ; the program source at the end is quite short.

PPS. Some of my g++ -v output follows, indicating the g++ configuration options
etcetera:

Target: x86_64-unknown-linux-gnu
Configured with: ../configure
--prefix=/home/stevenj/downloads/gcc/gcc-4.7.1/OBJ/../local --disable-multilib
--enable-languages=c,c++
GNU C++ (GCC) version 4.7.1 (x86_64-unknown-linux-gnu)
compiled by GNU C version 4.7.1, GMP version 4.3.2, MPFR version 3.0.0-p3,
MPC version 0.8.2
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072


[Bug fortran/49509] cannot promote types for arguments passed by value

2011-06-22 Thread stevenj at alum dot mit.edu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49509

--- Comment #4 from stevenj at alum dot mit.edu 2011-06-23 03:23:06 UTC ---
Section 12.4.1.2 of Fortran 2003 standard:
"If the dummy argument has the VALUE attribute it becomes associated with a
definable anonymous data object whose initial value is that of the actual
argument."

Furthermore, NOTE 12.22 says:
"If the VALUE attribute is specified, the effect is as if the actual argument
is assigned to a temporary, and the temporary is then argument associated with
the dummy argument.  The actual mechanism by which this happens is determined
by the processor."

Thus, if you have a subroutine foo(x) with T, VALUE :: X, then the standard
requires that 

  call foo(y)

have the same "effect as if" you did

 T :: temp
 temp = y
 call foo(temp)

with pass by reference.  But in that case, it would be valid to assign y to a
wider type T.

This implicitly contravenes the wording earlier in the section that the dummy
and actual argument be "type compatible (5.1.1.2)".   It is unfortunate that it
is not explicit on this point, however -- one could argue that there is a bug
in the standard here.


[Bug fortran/49509] cannot promote types for arguments passed by value

2011-06-22 Thread stevenj at alum dot mit.edu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49509

--- Comment #2 from stevenj at alum dot mit.edu 2011-06-23 02:54:50 UTC ---
You're missing the point.  Traditionally in Fortran, all arguments were passed
*by reference*, in which case it is clearly a requirement that actual parameter
match the formal parameter's type exactly, because the formal parameter refers
to the *same memory* as the actual parameter.

However, in this case we are passing by value.  This should act just like an
assignment of the formal parameter to the actual parameter (as opposed to
having them be the *same* object as in passing by reference).  Hence, just like
an assignment statement the compiler should be able to assign a narrower
integer type to a wider one.

Hence, the familiar old requirements of the Fortran standard are irrelevant.
The question is, what does the Fortran 2003 standard require for passing by
value, which is I believe is NEW IN FORTRAN 2003, and is SPECIFIC TO BIND(C)
functions.


[Bug fortran/49509] cannot promote types for arguments passed by value

2011-06-22 Thread stevenj at alum dot mit.edu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49509

--- Comment #3 from stevenj at alum dot mit.edu 2011-06-23 03:00:47 UTC ---
> Hence, the familiar old requirements of the Fortran standard are irrelevant.
> The question is, what does the Fortran 2003 standard require for passing by
> value, which is I believe is NEW IN FORTRAN 2003, and is SPECIFIC TO BIND(C)
> functions.

Just checked, and the VALUE attribute it is indeed new in Fortran 2003, but it
is not specific to bind(C).

But the point remains that your usual understanding of Fortran semantics does
not apply here.


[Bug fortran/49509] New: cannot promote types for arguments passed by value

2011-06-22 Thread stevenj at alum dot mit.edu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49509

   Summary: cannot promote types for arguments passed by value
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: fortran
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: stev...@alum.mit.edu


Compile the following test program gfortran, which is a toy example of
iso_c_binding that calls malloc(3).

  program bug

  use, intrinsic :: iso_c_binding
  implicit none
  interface
 type(C_PTR) function malloc(n) bind(C, name='malloc')
   import
   integer(C_SIZE_T), value :: n
 end function malloc
  end interface

  integer, parameter :: n = 3
  integer(C_SIZE_T) sz
  type(C_PTR) p
  p = malloc(n)  ! compiler error, cannot promote argument passed by value
  sz = n ! ... whereas assignment succeeds
  p = malloc(sz)

  end program bug

I obtain the following error:

  promote.f03:15.13:

p = malloc(n) ! compiler error, cannot promote argument type
   1
  Error: Type mismatch in argument 'n' at (1); passed INTEGER(4) to INTEGER(8)

(Similarly with older versions of gcc.)  Note that "n" is passed by value, so
my understanding is that this should act much like the assignment sz = n (which
succeeds): gfortran should automatically promote n to a size_t, like any other
assignment of a narrower type to a wider type.

Please consider applying the same type-promotion rules that are used for
assignments to passing arguments by value.  (I don't have the Fortran 2003
standard handy, but it is hard to believe that the two situations should be
treated differently.)


[Bug fortran/49501] support ATTRIBUTES ALIGN in gfortran

2011-06-22 Thread stevenj at alum dot mit.edu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49501

--- Comment #1 from stevenj at alum dot mit.edu 2011-06-22 17:38:25 UTC ---
Actually, it looks like there is a way to allocate aligned memory, albeit a 
bit ugly, thanks to Fortran 2003's C interoperability.  Declare a bind(C)
interface to e.g. posix_memalign, and then use C_F_POINTER intrinsic to convert
this into a pointer to a Fortran array.


[Bug fortran/41209] Add full ATTRIBUTE support to gfortran (ALIGN, (WEAK)ALIAS, ...)

2011-06-21 Thread stevenj at alum dot mit.edu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41209

stevenj at alum dot mit.edu changed:

   What|Removed |Added

 CC||stevenj at alum dot mit.edu

--- Comment #7 from stevenj at alum dot mit.edu 2011-06-22 05:17:45 UTC ---
Note that Bug 49501 (requesting at least ATTRIBUTES ALIGN) is also related to
this one.


[Bug fortran/49501] New: support ATTRIBUTES ALIGN in gfortran

2011-06-21 Thread stevenj at alum dot mit.edu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49501

   Summary: support ATTRIBUTES ALIGN in gfortran
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: enhancement
  Priority: P3
 Component: fortran
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: stev...@alum.mit.edu


Please add support for a ATTRIBUTES ALIGN compiler directive to gfortran,
similar to the Intel Fortran compiler:
  
http://software.intel.com/sites/products/documentation/hpc/composerxe/en-us/fortran/mac/lref_for/source_files/rfattali.htm

Note in particular that this should also apply to allocatable arrays:
   http://software.intel.com/en-us/forums/showthread.php?t=78361

Currently, there is no way to allocate 16-byte or 32-byte aligned memory in
gfortran.  16-byte aligned memory is needed for SSE/SSE2, and 32-byte aligned
memory is needed for upcoming AVX instructions.   This means that allocated
memory cannot be passed to optimized SIMD routines written in low-level
languages.

It seems reasonable to follow Intel's lead here rather than to invent an
incompatible GNU extension.

Note that Bug #41209 (which requests even more complete ATTRIBUTE support,
including ALIGN) depends on this one.

Previously, Bug #24261, which requested a way to get 16-byte alignment, was
closed based on the erroneous assertion that this is a glibc/malloc bug.  This
is false, because no standard C type requires more than 8-byte alignment (on
both 32-bit and 64-bit machines).  Hopefully this is even more obvious now that
there is a need in numerics for 32-byte alignment (AVX instructions), which is
even farther from requirements of standard C types.


[Bug c/48956] -Wconversion should warn when a complex value is assigned to a real result

2011-05-12 Thread stevenj at alum dot mit.edu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48956

--- Comment #6 from stevenj at alum dot mit.edu 2011-05-12 22:33:59 UTC ---
Thanks, I was somewhat aware of the additional requirements for applying
patches to the official tree (probably I should also file a copyright
assignment), but I wanted to check with you that I was on the right track
first.   I'm a bit swamped this week, but should be able to do all this next
week.


[Bug c/48956] -Wconversion should warn when a complex value is assigned to a real result

2011-05-11 Thread stevenj at alum dot mit.edu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48956

--- Comment #4 from stevenj at alum dot mit.edu 2011-05-11 20:16:57 UTC ---
Created attachment 24230
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=24230
patch to add a -Wconversion warning for complex -> real conversions

I believe the attached patch (against gcc 4.6.0) implements the feature I
requested.  It emits a warning for implicit conversions of complex types to
real (or integer) types.  It also emits a warning for similarly converting
complex constants, unless the imaginary part of the constant is zero in which
case it is treated as a real (or integer) constant given by the real part.

Note that complex->complex conversions are still not checked (e.g. no warning
is given in converting a complex double to a complex float, etcetera), but at
least I didn't add any regressions in that regard.

For example, when compiling the following test file:

#include 
#include 

double foo(double complex z)
{
 complex double zc = 1 + 1i;
 complex double zc0 = 1 + 0i;

 float complex zf = z;

 double x = z;
 float xf = z;
 int i = z;

 double xc = 1 + 1i;
 double xc0 = 1 + 0i;
 int ic = 1.1 + 1.1i;
 int ic0 = 1.1 + 0.0i;

 return sqrt(z) + csqrt(z);
}

with "gcc -Wconversion -c", the unpatched gcc gives no warnings whereas the
patched gcc emits:

complex-Wconversion-tst.c: In function ‘foo’:
complex-Wconversion-tst.c:11:6: warning: conversion to ‘double’ from ‘complex
double’ may alter its value [-Wconversion]
complex-Wconversion-tst.c:12:6: warning: conversion to ‘float’ from ‘complex
double’ may alter its value [-Wconversion]
complex-Wconversion-tst.c:13:6: warning: conversion to ‘int’ from ‘complex
double’ may alter its value [-Wconversion]
complex-Wconversion-tst.c:15:6: warning: conversion to ‘double’ alters ‘complex
int’ constant value [-Wconversion]
complex-Wconversion-tst.c:17:6: warning: conversion to ‘int’ alters ‘complex
double’ constant value [-Wconversion]
complex-Wconversion-tst.c:18:6: warning: conversion to ‘int’ alters ‘double’
constant value [-Wconversion]
complex-Wconversion-tst.c:20:6: warning: conversion to ‘double’ from ‘complex
double’ may alter its value [-Wconversion]
complex-Wconversion-tst.c:20:21: warning: conversion to ‘double’ from ‘complex
double’ may alter its value [-Wconversion]

Note that two warnings are emitted for the last line: one for the implicit
conversion of z to a real number in sqrt(z), and the other for the implicit
conversion of the complex sqrt(z)+csqrt(z) to a real return value of foo(z).

Using creal(...) and/or explicit casts silences the warnings.  Note also that
"double xc0 = 1 + 0i;" correctly yields no warning.

As mentioned above, "float complex zf = z;" and similar complex->complex
conversions probably should emit a warning, but I have not implemented that. 
However, that is not a regression.

--SGJ


[Bug c/48956] New: -Wconversion should warn when a complex value is assigned to a real result

2011-05-10 Thread stevenj at alum dot mit.edu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48956

   Summary: -Wconversion should warn when a complex value is
assigned to a real result
   Product: gcc
   Version: 4.6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: stev...@alum.mit.edu


Consider the following C snippet:

  #include 
  double foo(complex double x) {
 return x;
  }

This is valid C code: it assigns the complex "x" value to the real result of
"foo", which implicitly returns the real part of "x".  However, the implicit
conversion from complex to real has altered a value by discarding the imaginary
part of x.  Therefore, I would expect -Wconversion to issue a warning.

Compiling this with "gcc -c -Wconversion foo.c" issues no warning, however, nor
can I find any other -W option that causes a warning to be emitted.

Please consider issuing a warning when implicitly converting complex to real
(NOT the reverse) on -Wconversion.  (In fact, -Wconversion already does this in
Fortran as noted below.)

A warning for this type of conversion would be very helpful, since silently
discarding the imaginary part in this way often indicates a bug in my
experience.  (One can come up with many similar examples, e.g. writing sqrt(x)
rather than csqrt(x) currently silently succeeds for complex x, again
discarding the imaginary part.)  If the programmer meant to take the real part,
she probably would have written "creal(x)" explicitly.

Regards,
Steven G. Johnson

PS. Note -Wconversion already DOES emit a warning for conversion to complex to
real in gfortran.  e.g.

  subroutine foo(z)
  complex z
  real x
  x = z
  write(*,*) x
  return
  end

compiles without error with gfortran -c, but gfortran -c -Wconversion emits:

  x = z 
 1
Warning: Conversion from COMPLEX(4) to REAL(4) at (1)


[Bug c/48956] -Wconversion should warn when a complex value is assigned to a real result

2011-05-10 Thread stevenj at alum dot mit.edu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48956

--- Comment #1 from stevenj at alum dot mit.edu 2011-05-11 00:01:32 UTC ---
PPS. I have reproduced this problem in gcc versions 3.3.6, 3.4.6, 4.1.3, 4.3.2,
and 4.6.0 running on an x86_64 Debian GNU/Linux system.


[Bug rtl-optimization/29874] gcc-4.1.1 generates consistently worse performming SSE code than gcc-3.4.6

2011-03-07 Thread stevenj at alum dot mit.edu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29874

--- Comment #2 from stevenj at alum dot mit.edu 2011-03-07 23:13:41 UTC ---
Created attachment 23579
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=23579
benchmark extracted from FFTW3 - size 64 FFT with SSE2

I extracted a little benchmark of a size-64 FFT using double-precision SSE2
from FFTW3; this is a hard-coded (program-generated) routine specifically for
transforms of that size, and is usually a good test of the optimizer.

I played around with the compiler flags a bit, but it seems that just "-O3" is
about as good as anything.  i.e. gcc -O3 n1fv_64.c -o n1fv_64

I then ran a few timing tests on my Debian/x86_64 box (2.83GHz Intel Xeon
E5440), with the command:
  (for n in `seq 1 40`; do time ./n1fv_64; done) 2>&1 |grep user |sort
to time it a bunch of times, keeping only the fastest result to try and remove
random variations.  The results seemed pretty repeatable.

Results:
   gcc 3.4.6:0m0.208s
   gcc 4.1.3:   0m0.216s
   gcc 4.3.2:   0m0.232s

So, there does seem to be a definite slight slowdown.  I haven't tried gcc 4.4
or 4.5, since they are not installed on this box, but seems worthwhile for
someone to try them.