[Bug c++/54498] New: incorrect code generation from g++ -O on x86_64
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
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
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
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
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
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, ...)
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
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
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
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
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
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
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.