[Bug middle-end/91358] Wrong code with dynamic allocation and optional like class

2019-08-05 Thread matz at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91358

Michael Matz  changed:

   What|Removed |Added

 CC||matz at gcc dot gnu.org

--- Comment #1 from Michael Matz  ---
No wrong code involved here.  The uninitialized register that valgrind
complains
about is only uninitialized in exactly the case when %ebp (aka .m_initialized)
is zero.  So the insn sequence

=> 0x004007af <+31>:test   %rbx,%rbx
   0x004007b2 <+34>:je 0x4007b9 )+41>
   0x004007b4 <+36>:test   %bpl,%bpl
   0x004007b7 <+39>:jne0x4007c0 )+48>
   0x004007b9 <+41>:add$0x8,%rsp

goes to 0x4007b9 no matter what.  (if %rbx==uninit happens to be zero, then
directly, otherwise via the not-taken jump at 0x4007b7, because %ebp is zero).

The read from the uninitialized memory itself (from .ptr) is harmless as well,
because the memory backing that access must be there, as the structure is
large enough.

So, if you've seen a real problem somewhere (and not just valgrind complaining
about uninitialized registers in comparisons), then you've reduced the testcase
too much.  (The abort() in the testcase leads me to think that this was once
a larger testcase where the abort was triggered unexpectedly.  I'll note that
it isn't triggered with this testcase.)

[Bug middle-end/91358] Wrong code with dynamic allocation and optional like class

2019-08-06 Thread antoshkka at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91358

--- Comment #2 from Antony Polukhin  ---
(In reply to Michael Matz from comment #1)
> So, if you've seen a real problem somewhere (and not just valgrind
> complaining about uninitialized registers in comparisons),
> then you've reduced the testcase too much.

The original test case was not hitting the abort. Only the valgrind was
complaining. Original test case uses boost::variant, boost::optional and
std::vector, so it's quite hard to analyze. Part of the assembly with two
checks after the delete looks quite the same.

Valgrind complains are distracting. GDB entering the destructor is missleading.
Is there a simple way to change the GCC codegen to avoid the issue and not
affect performance?

Otherwise, is there some kind of a pattern that valgrind/gdb could detect to
avoid false positives?

[Bug middle-end/91358] Wrong code with dynamic allocation and optional like class

2019-08-06 Thread matz at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91358

--- Comment #3 from Michael Matz  ---
(In reply to Antony Polukhin from comment #2)
> (In reply to Michael Matz from comment #1)
> Valgrind complains are distracting. GDB entering the destructor is
> missleading. Is there a simple way to change the GCC codegen to avoid the
> issue and not affect performance?

The only way I see would be to emit the jumpy sequence that RTL generates
(sometimes) from "if (x & y)" in the opposite order. There's no real reason
within the intermediate form to prefer one or the other, but it might help in
practice.  (The problem will be that there's also no reason that would prevent
GCC from transforming "x & y" into "y & x", e.g. for canonicalization, and then
the other order would create the problem). 

> Otherwise, is there some kind of a pattern that valgrind/gdb could detect to
> avoid false positives?

I don't really see any, no good idea here :-/

[Bug middle-end/91358] Wrong code with dynamic allocation and optional like class

2019-08-07 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91358

Richard Biener  changed:

   What|Removed |Added

   Keywords|wrong-code  |
 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |WONTFIX

--- Comment #4 from Richard Biener  ---
Indeed "speculating" [uninitialized] loads is something GCC frequently does if
it
knowns those loads do not trap.  I guess valgrind could be improved to check
only at uses of the uninit value?

[Bug middle-end/91358] Wrong code with dynamic allocation and optional like class

2019-08-07 Thread glisse at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91358

--- Comment #5 from Marc Glisse  ---
(In reply to Richard Biener from comment #4)
> I guess valgrind could be improved to check
> only at uses of the uninit value?

It is used. In the easy case it would be used in "undef & 0", so the result
does not depend on undef. It may get a bit complicated for valgrind to
recognize all operations that do not depend on one of the operands, but a
subset would be doable. However, here we transform:
if (x) if (y) ...
to
if (x & y)
and expand to
if (y) if (x) ...
where y may be undefined when !x. After a few jumps we end up in the same
place, but that seems impossible for valgrind to handle.

[Bug middle-end/91358] Wrong code with dynamic allocation and optional like class

2019-08-08 Thread antoshkka at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91358

--- Comment #6 from Antony Polukhin  ---
(In reply to Michael Matz from comment #3)
> I don't really see any, no good idea here :-/

How about moving all the optimizations based on reading uninitialized values
under a flag like -funinitialized-logic, so that users could build with -O2
-fno-uninitialized-logic ?

[Bug middle-end/91358] Wrong code with dynamic allocation and optional like class

2019-08-08 Thread matz at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91358

--- Comment #7 from Michael Matz  ---
(In reply to Antony Polukhin from comment #6)
> (In reply to Michael Matz from comment #3)
> > I don't really see any, no good idea here :-/
> 
> How about moving all the optimizations based on reading uninitialized values
> under a flag like -funinitialized-logic, so that users could build with -O2
> -fno-uninitialized-logic ?

That can't work in general.  How would you propose that GCC automagically
detects that in:

struct S {int a, b;};
int foo (struct S *s) { return s->a ? s->b : 0; }

the read of ->b is uninitialized?  After all, it might have been initialized
by the caller or not.