With this compiler: [descartes:gcc/objdirs/gambc-v4_1_2] lucier% /pkgs/gcc-4.4.0-64/bin/gcc -v Using built-in specs. Target: powerpc64-apple-darwin9.5.0 Configured with: ../../mainline/configure CC='/usr/bin/gcc-4.0 -mcpu=970 -m64' --disable-werror --build=powerpc64-apple-darwin9.5.0 --host=powerpc64-apple-darwin9.5.0 --target=powerpc64-apple-darwin9.5.0 --with-gmp-include=/sw/include/ --with-gmp-lib=/sw/lib/ppc64 --with-mpfr-include=/sw/include/ --with-mpfr-lib=/sw/lib/ppc64 --prefix=/pkgs/gcc-4.4.0-64 --with-libiconv-prefix=/usr --with-system-zlib Thread model: posix gcc version 4.4.0 20081020 (experimental) [trunk revision 141240] (GCC) I get this error: [descartes:gcc/objdirs/gambc-v4_1_2] lucier% /pkgs/gcc-4.4.0-64/bin/gcc -save-temps -mcpu=970 -m64 -I../include -I. -no-cpp-precomp -Wall -W -Wno-unused -O1 -fno-math-errno -fschedule-insns2 -fno-trapping-math -fno-strict-aliasing -fwrapv -fomit-frame-pointer -fPIC -fno-common -DHAVE_CONFIG_H -D___PRIMAL -D___LIBRARY -c assemtest.i gcc: unrecognized option '-no-cpp-precomp' assemtest.s:69:Parameter error: expression must be a multiple of 4 (parameter 2) The offending assembler command is ldu r0,7(r9) I'll include assemtest.i; the code itself is about 50 lines of machine-generated C code, plus a lot of declarations so I could get it to compile separately.
Created attachment 16517 [details] test file input This is the .i file
Created attachment 16518 [details] test file output
Reduced testcase: double y, z; void foo (long x) { y = *(double *) ((long *) (x - 1) + 1); z = *(double *) ((long *) (x - 1) + 1); } $ gcc -m64 -O -c ldu.c /tmp/ccYujYhd.s: Assembler messages: /tmp/ccYujYhd.s:20: Error: operand out of domain (7 is not a multiple of 4) The insn is generated during auto-inc-dec. (insn 9 8 10 2 ldu.c:4 (set (reg:DF 122) (mem:DF (pre_modify:DI (reg/f:DI 119 [ D.1253 ]) (plus:DI (reg/f:DI 119 [ D.1253 ]) (const_int 7 [0x7]))) [0 S8 A64])) 345 {*movdf_hardfloat64} (expr_list:REG_INC (reg/f:DI 119 [ D.1253 ]) (nil)))
I think this is rs6000_legitimate_address at fault here, it shouldn't say it is valid memory address. In the: if (GET_CODE (x) == PRE_MODIFY block in that function, rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict) is true because: 3649 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64) 3650 extra = 4; 3651 else if (offset & 3) 3652 return false; only checks the offset being multiple of 4 if not DFmode or DDmode. If that is correct, I think rs6000_legitimate_address should in the PRE_MODIFY case explicitly check that if offset is a constant that it is multiple of 4.
The test in rs6000_legitimate_offset_address_p is for something completely different. This should be tested in rs6000_legitimate_address: if (GET_CODE (x) == PRE_MODIFY && mode != TImode && mode != TFmode && mode != TDmode && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_POWERPC64 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE)) && (TARGET_POWERPC64 || mode != DImode) && !ALTIVEC_VECTOR_MODE (mode) && !SPE_VECTOR_MODE (mode) /* Restrict addressing for DI because of our SUBREG hackery. */ && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == DDmode || mode == DImode)) && TARGET_UPDATE && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict) && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict) || legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)) && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0))) return 1;
Created attachment 16519 [details] gcc44-pr37878.patch So something like this?
Also, note the problem is a DFmode value in a GPR. FPRs can handle the non-word-aligned offset. Forcing all DFmode to be 64 bit aligned is not an option because that is known to impose a severe performance penalty. For non-update form, we have handled this in rs6000_legitimize_reload_address.
Created attachment 16526 [details] gcc44-pr37878.patch Just for the record, after discussions on IRC the bug was identified in word_offset_memref_operand.
I bootstrapped and regtested the suggested patch. There was one fewer FAIL in the gcc tests: FAIL: gcc.c-torture/execute/nestfunc-6.c execution, -O0 and one more failure in the libgomp tests: FAIL: libgomp.fortran/crayptr2.f90 -O3 -fomit-frame-pointer -funroll-loops execution test However, it's not clear to me from the output of gdb implies that this may is a problem with the compiled code (the command lines are taken from the log file): [descartes:powerpc64-apple-darwin9.5.0/libgomp/testsuite] lucier% /Users/lucier/programs/gcc/objdirs/mainline/gcc/xgcc -B/Users/lucier/programs/gcc/objdirs/mainline/gcc/ /Users/lucier/programs/gcc/mainline/libgomp/testsuite/libgomp.fortran/crayptr2.f90 -B/Users/lucier/programs/gcc/objdirs/mainline/powerpc64-apple-darwin9.5.0/./libgomp/ -I/Users/lucier/programs/gcc/objdirs/mainline/powerpc64-apple-darwin9.5.0/./libgomp -I/Users/lucier/programs/gcc/mainline/libgomp/testsuite/.. -shared-libgcc -fmessage-length=0 -fopenmp -O3 -fomit-frame-pointer -funroll-loops -fopenmp -fcray-pointer -static-libgcc -L/Users/lucier/programs/gcc/objdirs/mainline/powerpc64-apple-darwin9.5.0/./libgomp/.libs -lgomp -L/Users/lucier/programs/gcc/objdirs/mainline/powerpc64-apple-darwin9.5.0/./libgomp/../libgfortran/.libs -lgfortranbegin -lgfortran -lm -mcpu=970 -m64 -o ./crayptr2.exe [descartes:powerpc64-apple-darwin9.5.0/libgomp/testsuite] lucier% env LD_LIBRARY_PATH=.:/Users/lucier/programs/gcc/objdirs/mainline/powerpc64-apple-darwin9.5.0/./libgomp/.libs:/Users/lucier/programs/gcc/objdirs/mainline/gcc:/Users/lucier/programs/gcc/objdirs/mainline/powerpc64-apple-darwin9.5.0/./libgomp/../libgfortran/.libs:.:/Users/lucier/programs/gcc/objdirs/mainline/powerpc64-apple-darwin9.5.0/./libgomp/.libs:/Users/lucier/programs/gcc/objdirs/mainline/gcc:/Users/lucier/programs/gcc/objdirs/mainline/powerpc64-apple-darwin9.5.0/./libgomp/../libgfortran/.libs gdb ./crayptr2.exe GNU gdb 6.3.50-20050815 (Apple version gdb-962) (Sat Jul 26 08:17:57 UTC 2008) Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "powerpc-apple-darwin"...Reading symbols for shared libraries .... done (gdb) run Starting program: /Users/lucier/programs/gcc/objdirs/mainline/powerpc64-apple-darwin9.5.0/libgomp/testsuite/crayptr2.exe warning: posix_spawn failed, trying execvp, error: 86 Reading symbols for shared libraries +++.. done Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000 0x0000000100001678 in MAIN__.omp_fn.0 () (gdb) where #0 0x0000000100001678 in MAIN__.omp_fn.0 () #1 0x000000010000187c in MAIN__ () #2 0x00000001000018e4 in main (argc=1, argv=<value temporarily unavailable, due to optimizations>) at ../../../../mainline/libgfortran/fmain.c:21 It is completely reproducible, however. Brad
This patch fixes my original problem and the reduced test case. The two testresults reports I referred to earlier are at http://gcc.gnu.org/ml/gcc-testresults/2008-10/msg01616.html and http://gcc.gnu.org/ml/gcc-testresults/2008-10/msg01427.html Thanks! Brad
Created attachment 16576 [details] disallow illegal displacement wrapped in PRE_MODIFY or PRE_INC/DEC I think this patch accomplishes the effect but easier to follow with the address form localized in one place.
Created attachment 16577 [details] another refinement Jakub suggested a further refinement to hoist a common sub-expression.
Subject: Bug 37878 Author: dje Date: Wed Oct 29 23:33:02 2008 New Revision: 141450 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=141450 Log: PR target/37878 * config/rs6000/predicates.md (word_offset_memref_operand): Restructure code and look inside auto-inc/dec addresses. Modified: trunk/gcc/ChangeLog trunk/gcc/config/rs6000/predicates.md
Thank you, this fixes the original bug. I took the liberty of closing this bug report. Thanks again. Brad