|
From: Jonathan P. <jon...@co...> - 2003-11-19 22:54:24
|
Hi there,
Thanks for implementing the MMX instruction set!
Now that we can run with mmx enabled we're seeing the "uninitialized
value" warning quite a bit. As far as we can tell everything works just
fine so this feels like a false positive. I've stepped into the
debugger when the errors occur and all the addresses look fine as well -
the pointers are well within the middle of a large array that has been
written to many times before the error starts showing up.
Has anybody else seen this?
Here's our memcpy_mmx routine that is causing the problem:
void memcpy_mmx(unsigned char *to, const unsigned char *from, size_t len)
{
register int i;
// align destination
for (i = (int)to & 0x3 ; i-- && len > 0 ; len--) {
*to++ = *from++;
}
// copy 64-byte chunks
i = len >> 6;
while (i--) {
__asm__ __volatile__ (
" movq (%0), %%mm0\n"
" movq 8(%0), %%mm1\n"
" movq 16(%0), %%mm2\n"
" movq 24(%0), %%mm3\n"
" movq %%mm0, (%1)\n"
" movq %%mm1, 8(%1)\n"
" movq %%mm2, 16(%1)\n"
" movq %%mm3, 24(%1)\n"
" movq 32(%0), %%mm0\n"
" movq 40(%0), %%mm1\n"
" movq 48(%0), %%mm2\n"
" movq 56(%0), %%mm3\n"
" movq %%mm0, 32(%1)\n"
" movq %%mm1, 40(%1)\n"
" movq %%mm2, 48(%1)\n"
" movq %%mm3, 56(%1)\n"
: : "r" (from), "r" (to) : "memory");
from += 64;
to += 64;
}
// copy 64-bits at a time
i = (len & 0x38) >> 3;
while (i--) {
__asm__ __volatile__ (
" movq (%0), %%mm0\n"
" movq %%mm0, (%1)\n"
: : "r" (from), "r" (to) : "memory");
to += 8;
from += 8;
}
// copy last few bytes if necessary
for (i = len & 7 ; i-- > 0 ;) {
*to++ = *from++;
}
}
Can you CC me directly since I am not on the mailing list? Thanks!
JP
|
|
From: Jeremy F. <je...@go...> - 2003-11-19 23:11:40
|
On Wed, 2003-11-19 at 14:53, Jonathan Payne wrote: > Thanks for implementing the MMX instruction set! > > Now that we can run with mmx enabled we're seeing the "uninitialized > value" warning quite a bit. As far as we can tell everything works just > fine so this feels like a false positive. I've stepped into the > debugger when the errors occur and all the addresses look fine as well - > the pointers are well within the middle of a large array that has been > written to many times before the error starts showing up. > > Has anybody else seen this? Normally memcheck will ignore it if you merely read an undefined value - it's only when you use it as a pointer or in a conditional does it complain. But for floating point instructions (which includes MMX), it checks for validity when you do the read, regardless of what you do with the data later on. Your program shows why memcheck spends so much effort in tracking undefined values around rather than complaining as soon as they appear. Perfectly ordinary, correct programs can result in undefined values appearing. For example, a structure may have holes left by padding, which are never initialized. If you do memcpy(&a, &b, sizeof(a)), then this will copy the undefined holes into a from b. With your memcpy_mmx, this will raise spurious errors, because it will read the holes along with everything else and complain about them. There's no easy fix, unfortunately. memcheck doesn't do a detailed model of the FPU or MMX instructions like it does with integer instructions, so it can't do bit-by-bit tracking. Until Valgrind is taught a more complete model, there's no real workaround, other than to initialize everything. J |
|
From: Nicholas N. <nj...@ca...> - 2003-11-19 23:23:14
|
On Wed, 19 Nov 2003, Jeremy Fitzhardinge wrote:
> There's no easy fix, unfortunately. memcheck doesn't do a detailed
> model of the FPU or MMX instructions like it does with integer
> instructions, so it can't do bit-by-bit tracking. Until Valgrind is
> taught a more complete model, there's no real workaround, other than to
> initialize everything.
Or avoid using memcpy_mmx(). You could use something like this in your
code:
if (RUNNING_ON_VALGRIND) {
memcpy(...)
} else {
memcpy_mmx(...)
}
Not ideal, but should hopefully keep you going.
N
|
|
From: Dirk M. <dm...@gm...> - 2003-11-19 23:23:40
|
On Wednesday 19 November 2003 23:53, Jonathan Payne wrote: > the pointers are well within the middle of a large array that has been > written to many times before the error starts showing up. the stuff that has been written there must have been defined in the first place. > Here's our memcpy_mmx routine that is causing the problem: are you copying partially uninitialized data? The way MMX instructions are implemented in valgrind means that it will check for definedness the first time it reads the data into a register. This is different from non-MMX use of the code, since that one will only complain when there is actually a decision (conditional jump or syscall) depending on an uninitialised value. However, the complexity of MMX does not allow accurate modelling of uninitialised values. Anyway, a small selfcontained example will make it easy to spot the problem. |