I'm getting the error message: ==30994== Memcheck, a memory error detector. ==30994== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al. ==30994== Using LibVEX rev 1367, a library for dynamic binary translation. ==30994== Copyright (C) 2004-2005, and GNU GPL'd, by OpenWorks LLP. ==30994== Using valgrind-3.0.1, a dynamic binary instrumentation framework. ==30994== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al. ==30994== For more details, rerun with: -v ==30994== ==30994== Invalid read of size 8 ==30994== at 0x400862: set_hes_eig_ (test.f90:18) ==30994== by 0x4007FD: MAIN__ (test.f90:7) ==30994== by 0x40089D: main (fmain.c:18) ==30994== Address 0x12329498 is 0 bytes after a block of size 72 alloc'd ==30994== at 0x11B1C166: malloc (vg_replace_malloc.c:149) ==30994== by 0x11C2B0B8: _gfortrani_get_mem (memory.c:99) ==30994== by 0x11C2B0EC: malloc_with_header (memory.c:125) ==30994== by 0x11C2B220: allocate_size (memory.c:228) ==30994== by 0x40075E: MAIN__ (test.f90:4) ==30994== by 0x40089D: main (fmain.c:18) for the following code, compiled using gfortran 4.0.1 (and the other versions I tested, 4.0X) and -g -O2 -ffast-math on opteron, or with -march=pentium4 - mfpmath=sse on intel: IMPLICIT NONE integer, parameter :: ndf=6 real(KIND=8), allocatable, dimension(:) :: eigval,work ALLOCATE(eigval(ndf)) ALLOCATE(work(ndf)) eigval=1.0_8 CALL set_hes_eig(ndf,eigval,work) END SUBROUTINE set_hes_eig(ndf,eigval,work) IMPLICIT NONE INTEGER, INTENT(IN) :: ndf REAL(KIND=8), INTENT(INOUT) :: eigval(ndf), work(ndf) REAL(KIND=8), PARAMETER :: one = 1.0_8 INTEGER :: indf LOGICAL :: neg DO indf = 1, ndf IF( eigval(indf) < 0.0_8 )THEN work(indf) = - one ELSE work(indf) = one END IF END DO END SUBROUTINE set_hes_eig with the asm (objdump -D): 0000000000400830 <set_hes_eig_>: 400830: 8b 07 mov (%rdi),%eax 400832: 85 c0 test %eax,%eax 400834: 7e 4b jle 400881 <set_hes_eig_+0x51> 400836: 66 0f 57 d2 xorpd %xmm2,%xmm2 40083a: 8d 78 01 lea 0x1(%rax),%edi 40083d: b9 01 00 00 00 mov $0x1,%ecx 400842: 48 63 c1 movslq %ecx,%rax 400845: 66 0f 12 05 63 01 00 movlpd 355(%rip),%xmm0 # 4009b0 <_IO_stdin_used+0x8> 40084c: 00 40084d: f2 0f 10 da movsd %xmm2,%xmm3 400851: 48 ff c8 dec %rax 400854: 66 0f 12 0d 5c 01 00 movlpd 348(%rip),%xmm1 # 4009b8 <_IO_stdin_used+0x10> 40085b: 00 40085c: ff c1 inc %ecx 40085e: f2 0f 10 e0 movsd %xmm0,%xmm4 400862: f2 0f c2 1c c6 02 cmplesd (%rsi,%rax,8),%xmm3 400868: 39 cf cmp %ecx,%edi 40086a: 66 0f 54 e3 andpd %xmm3,%xmm4 40086e: 66 0f 55 d9 andnpd %xmm1,%xmm3 400872: 66 0f 56 dc orpd %xmm4,%xmm3 400876: f2 0f 10 c3 movsd %xmm3,%xmm0 40087a: f2 0f 11 04 c2 movsd %xmm0,(%rdx,%rax,8) 40087f: 75 c1 jne 400842 <set_hes_eig_+0x12> 400881: f3 c3 repz retq The code itself is valid (don't know about the asm), and there is no such error if compiled with -O2 or -O1 -ffastmath. I've therefore filed a PR with gcc (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25607), but it was suggested that this could be a valgrind issue.
I've just checked that the same error is issued by valgrind 3.1.0
Yeh, it's a bug in Valgrind's SSE instruction decoder, which causes it to read 128-bit chunks from memory when in fact it should only be reading 64-bits. Well spotted. You can cancel the gcc bug. I'll contemplate a fix. 0x400862: cmpsd $2,(%rsi,%rax,8),%xmm3 ------ IMark(0x400862, 6) ------ PUT(168) = 0x400862:I64 t8 = Add64(GET:I64(48),Shl64(GET:I64(0),0x3:I8)) t7 = CmpLE64F0x2(GET:V128(248),LDle:V128(t8)) PUT(248) = t7 ^^^^^^^^^^^^^ 128-bit load
Julian fixed this in VEX SVN revisions 1521 and 1522.