The codegen for atomic instructions with indirect/reference operands on Itanium seems to be bogus: % cat bar.F subroutine atomic_add(lhs, rhs) real lhs, rhs !$omp atomic lhs = rhs + lhs end % gfortran -v -fopenmp -O1 -S bar.F Using built-in specs. Target: ia64-unknown-linux-gnu Configured with: /net/gnu-13/export/gnu/src/gcc-4.2/gcc/configure --enable-cloca le=gnu --with-system-zlib --with-demangler-in-ld --enable-shared --enable-thread s=posix --enable-haifa --enable-checking=assert --prefix=/usr/gcc-4.2 --with-loc al-prefix=/usr/local . . . % cat bar.s .file "bar.F" .pred.safe_across_calls p1-p5,p16-p63 .text .align 16 .global atomic_add_# .proc atomic_add_# atomic_add_: .prologue .body ld4 r14 = [r32] ldfs f6 = [r33] ;; setf.s f7 = r14 ;; fadd.s f7 = f7, f6 ;; getf.s r16 = f7 mov r15 = r14 .L2: ;; addp4 r14 = r15, r0 ;; mov ar.ccv = r14 mf ;; cmpxchg4.rel r14 = [r32], r16, ar.ccv ;; cmp4.eq p6, p7 = r14, r15 (p6) br.ret.dpnt.many rp mov r15 = r14 br .L2 ;; .endp atomic_add_# .ident "GCC: (GNU) 4.2.0" Note that the fp add instruction is not in the retry path, so if the cmpxchg fails because of contention from another thread, the incorrect result will be written to the atomic location. The bug happens in all versions of gfortran 4.2.x and 4.3.0 that I have tried. It does not happen if lhs is a symbolic constant. It happens for all data types, not just fp. It happens for all optimization levels.
Does the same thing happen with C? void foo(float *lhs, float*rhs) { #pragma omp atomic *lhs = *rhs + *lhs; }
Subject: RE: Bogus codegen for openmp atomics w/ indirects operands on IPF The C example looks correct (but you have to use the += operator to get a legal example, which might have affected things): % cat foo.c void foo(float *lhs, float*rhs) { #pragma omp atomic *lhs += *rhs; } % gcc -fopenmp -O1 -S foo.c % cat foo.s .file "foo.c" .pred.safe_across_calls p1-p5,p16-p63 .text .align 16 .global foo# .proc foo# foo: .prologue .body ldfs f6 = [r33] ld4 r15 = [r32] ;; mov r16 = r15 .L2: setf.s f7 = r15 ;; fadd.s f7 = f7, f6 ;; getf.s r15 = f7 addp4 r14 = r16, r0 ;; mov ar.ccv = r14 mf ;; cmpxchg4.rel r17 = [r32], r15, ar.ccv ;; mov r15 = r17 cmp4.eq p6, p7 = r17, r16 (p6) br.ret.dpnt.many rp mov r16 = r17 br .L2 ;; .endp foo# .ident "GCC: (GNU) 4.2.0" -bb -----Original Message----- From: fxcoudert at gcc dot gnu dot org [mailto:gcc-bugzilla@gcc.gnu.org] Sent: Thursday, November 08, 2007 6:50 AM To: Bliss, Brian E Subject: [Bug fortran/34020] Bogus codegen for openmp atomics w/ indirects operands on IPF ------- Comment #1 from fxcoudert at gcc dot gnu dot org 2007-11-08 12:49 ------- Does the same thing happen with C? void foo(float *lhs, float*rhs) { #pragma omp atomic *lhs = *rhs + *lhs; } -- fxcoudert at gcc dot gnu dot org changed: What |Removed |Added ------------------------------------------------------------------------ ---- CC| |fxcoudert at gcc dot gnu dot | |org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34020 ------- You are receiving this mail because: ------- You reported the bug, or are watching the reporter.
Subject: Bug 34020 Author: jakub Date: Sat Nov 10 07:51:55 2007 New Revision: 130069 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=130069 Log: PR fortran/34020 * gimplify.c (goa_lhs_expr_p): Inside INDIRECT_REF handle unshared nops. * testsuite/libgomp.fortran/pr34020.f90: New test. Added: trunk/libgomp/testsuite/libgomp.fortran/pr34020.f90 Modified: trunk/gcc/ChangeLog trunk/gcc/gimplify.c trunk/libgomp/ChangeLog
Fixed on the trunk so far.
No plan for 4.2 backport.
See 39354.