Bug 34020 - Bogus codegen for openmp atomics w/ indirects operands on IPF
Summary: Bogus codegen for openmp atomics w/ indirects operands on IPF
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.2.0
: P3 normal
Target Milestone: ---
Assignee: Jakub Jelinek
URL: http://gcc.gnu.org/ml/gcc-patches/200...
Keywords: openmp
Depends on:
Blocks:
 
Reported: 2007-11-08 00:11 UTC by Brian Bliss
Modified: 2009-03-02 22:47 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2007-11-09 07:28:13


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Brian Bliss 2007-11-08 00:11:18 UTC
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.
Comment 1 Francois-Xavier Coudert 2007-11-08 12:49:50 UTC
Does the same thing happen with C?

void foo(float *lhs, float*rhs) {
#pragma omp atomic
  *lhs = *rhs + *lhs;
}
Comment 2 Brian Bliss 2007-11-09 00:06:28 UTC
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.
Comment 3 Jakub Jelinek 2007-11-10 07:52:05 UTC
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

Comment 4 Jakub Jelinek 2007-11-10 07:55:10 UTC
Fixed on the trunk so far.
Comment 5 Jakub Jelinek 2008-03-10 10:26:47 UTC
No plan for 4.2 backport.
Comment 6 Brian Bliss 2009-03-02 22:47:09 UTC
See 39354.