During an --enable-checking=valgrind (and the normal checks) bootstrap, stage2 gives warnings compiling ggc-common.c. The first one is: ==29462== Conditional jump or move depends on uninitialised value(s) ==29462== at 0x853CB22: do_fix_trunc (real.c:963) 963 if (REAL_EXP (r) <= 0) (gdb) bt #0 0x0853cb22 in do_fix_trunc (r=0x52bfd9cc, a=0x52bfd9b4) at /home/drow/src/gcc/gcc/real.c:963 #1 0x0853e1be in real_trunc (r=0x52bfd9b4, mode=VOIDmode, x=0x7) at /home/drow/src/gcc/gcc/real.c:4610 #2 0x0825fcaf in fold_convert_const (code=FIX_TRUNC_EXPR, type=0x1bb93488, arg1=0x1c194a80) at /home/drow/src/gcc/gcc/fold-const.c:1754 #3 0x080f9a0b in evaluate_stmt (stmt=Variable "stmt" is not available. ) at /home/drow/src/gcc/gcc/tree-ssa-ccp.c:853 #4 0x080fa0a8 in ccp_visit_stmt (stmt=0x1c191f54, taken_edge_p=0x7, output_p=0x4000007) at /home/drow/src/gcc/gcc/tree-ssa-ccp.c:1065 #5 0x08146f48 in simulate_stmt (stmt=0x1c191f54) at /home/drow/src/gcc/gcc/tree-ssa-propagate.c:306 #6 0x081474f0 in ssa_propagate (visit_stmt=0x4000007, visit_phi=0x4000007) at /home/drow/src/gcc/gcc/tree-ssa-propagate.c:429 #7 0x080fa77c in execute_ssa_ccp () at /home/drow/src/gcc/gcc/tree-ssa-ccp.c:1207 The code being compiled is the check of min_expand. It looks like stage1 has miscompiled stage2, because do_fix_trunc starts by copying *r to *a, but at this read of *r r->uexp is still undefined. That's just a guess. Compiler is: GNU C version 4.0.0 20041012 (it took three days and a bit to do the valgrind bootstrap).
Created attachment 7389 [details] Testcase. valgrind --db-attach=yes gcc/stage2/cc1 -fpreprocessed ggc-common2.i -quiet -O1 -o ggc-common.s
REAL_VALUE_TYPE x = TREE_REAL_CST (arg1);
Any news about this one?
I just stumbled over this one, too. Even shorter testcase: valgrind --tool=memcheck cc1 -quiet vg.c ================================== int foo() { return 1.0 + 1.1; } ==================================
Roger, the problem appears with your patch for PR17151: http://gcc.gnu.org/ml/gcc-cvs/2004-09/msg01231.html It looks like this causes a miscompilation of the stage2 compiler.
Just another data point: Reverting the patch on current mainline makes the problem disappear.
Are you sure this is not just a bug in valgrind? I have verified that with current CVS I get ERROR SUMMARY: 37 errors from 21 contexts (suppressed: 12 from 1) while if I rebuild stage1's combine.o with Roger's patch backed out, link new stage1 cc1, then rebuild stage2's real.o with the new stage1 cc1 and link new stage2 cc1, I get ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 1) I did a binary search on real.s and e.g. one of the valgrind errors is triggered by following change in real.s: @@ -6453,8 +6453,8 @@ round_for_format: .p2align 2,,3 .L997: movl (%ebp), %eax + subl $-2147483648, %eax shrl $5, %eax - xorl $67108864, %eax subl $67108864, %eax cmpl %eax, 32(%esp) jge .L979 With the xorl there are no errors, with subl there is one error. But I don't see any functional difference between these two. If I replace 28 occurences of these subl $0x80000000, %eax before >> 5 to xorl $0x4000000, %eax after >> 5 (I left out encoders/decoders of non-ieee formats), valgrind stops reporting any errors. So to me this looks like valgrind not handling subl $0x80000000, %eax instruction correctly. Do you agree? I used valgrind 2.2.0.
BTW, if I replace all subl $-2147483648, %eax instructions in real.s by: xorl $-2147483648, %eax (note that all such instructions are followed either by shrl, or addl, so any differences in %eflags are ignored), it shuts valgrind up as well.
To prove this is a valgrind bug and not GCC bug, I wrote a small self-contained testcase on which valgrind complains: #define EXP_BITS (32 - 5) struct real_value { unsigned int cl : 2; unsigned int sign : 1; unsigned int signalling : 1; unsigned int canonical : 1; unsigned int uexp : EXP_BITS; unsigned long sig[4]; }; #if defined __i386__ && defined USE_ASM #define REAL_EXP(REAL) \ ({ int ret; \ __asm ("movl (%%eax),%%eax; subl $0x80000000,%%eax; shrl $5, %%eax; subl $0x4000000,%%eax" \ : "=a" (ret) : "a" (REAL), "m" (*(REAL))); \ ret; }) #else #define REAL_EXP(REAL) \ ((int)((REAL)->uexp ^ (unsigned int)(1 << (EXP_BITS - 1))) \ - (1 << (EXP_BITS - 1))) #endif #if __GNUC__ >= 3 #define __noinline __attribute ((noinline)) #else #define __noinline #endif int dummy; void __noinline bar (void) { ++dummy; } void __noinline foo (struct real_value *r) { if (REAL_EXP (r) <= 5) bar (); } int main (void) { struct real_value r; r.uexp = 0x21; foo (&r); return 0; } Both with -DUSE_ASM and without CVS GCC generates the same assembly and in both cases valgrind --tool=memcheck /tmp/test fails with: ==31022== Conditional jump or move depends on uninitialised value(s) ==31022== at 0x8048368: foo (test.c:41) ==31022== by 0x80483A4: main (test.c:50)
So closing as invalid, please report this to valgrind then.
Just for reference, this is now tracked in http://bugs.kde.org/show_bug.cgi?id=97042