All of lore.kernel.org
 help / color / mirror / Atom feed
From: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Dibyendu Majumdar <mobile@majumdar.org.uk>,
	Linux-Sparse <linux-sparse@vger.kernel.org>
Subject: Re: Potential incorrect simplification
Date: Tue, 28 Mar 2017 19:00:50 +0200	[thread overview]
Message-ID: <20170328170049.2y6lwxx64yzjjwmc@macpro.local> (raw)
In-Reply-To: <CA+55aFx6g3-+6tJ_6Uqu4K1pQoDnqcXrjSGYsryLjjksEtT06A@mail.gmail.com>

On Tue, Mar 28, 2017 at 09:20:58AM -0700, Linus Torvalds wrote:
> On Tue, Mar 28, 2017 at 7:19 AM, Dibyendu Majumdar
> <mobile@majumdar.org.uk> wrote:
> >
> > Well the unsimplified output is correct. The problem appears after
> > simplification.
> 
> No. The unsimplified output has the exact same bug:
> 
>   main:
>   .L0:
>         <entry-point>
>         load.32     %r1 <- 0[s3]
>         shl.32      %r2 <- $1, $6
>         and.32      %r3 <- %r1, $-65
> 
> That "load.32" loads an uninitialized value from the stack.
> 
> The simplification then just simplifies the uninitialized load to just
> be an uninitialized pseudo instead. Exact same code.
> 
> And arguably both unsimplified and simplified code is "correct" in the
> sense that it's exactly what the original source code does:
> 
>    s3.onebit = 1;
> 
> becomes
> 
>         and.32      %r3 <- %r4, $-65
>         or.32       %r4 <- %r3, $64
> 
> where that "and" is obviously pointless (well, "obviously" to a human,
> not so sparse ;), but it's basically the code sequence "leave the
> uninitialized bits alone, set bit 6 to 1". And then comes the *truly*
> stupid code that does
> 
>         lsr.32      %r6 <- %r4, $6
>         cast.32     %r7 <- (1) %r6
> 
> which is "shift bit 6 down to bit zero, and cast (aka sign-extend) the
> one-bit value to 32 bits" and then
> 
>         setne.32    %r8 <- %r7, $1
>         br          %r8, .L1, .L3
> 
> test if the result is 1, do a conditional branch on the result.
> 
> So the code is "correct". It may be confusing, because simplification
> turns a uninitialized load into just an uninitialized variable, and
> what also happens is that since SSA means that (by definition) every
> initialization dominates every use, we have this situation where the
> first assignment to the pseudo becomes the dominator of even the
> uninitialized *previous* use of the pseudo, which is why you see that
> odd sequence
> 
>         and.32      %r3 <- %r4, $-65
>         or.32       %r4 <- %r3, $64
> 
> which *initializes* the pseudo %r4 in the second instruction, but uses
> it in the first one. That's a classic pattern of uninitialized pseudos
> in sparse exactly because of the SSA logic.
> 
> But it is all internally consistent, and the simplification is
> "correct". The simplification phase very much has a "garbage in,
> garbage out" model.

I agree, of course, but I think there is a problem anyway.
The problem here with this %r4 is created by the single-store
shortcut which replace all loads with the same value as the one
used for the unique store (even loads that are not dominated
by the store). Fair enough, don't use uninitialized vars.

Now, if you remove this single-store shortcut and just let the normal
find_dominating_stores() do its job, the resulting code become
the expected:
	ret.32      $0

Not just by coincidence (I checked the intermediate steps):
sparse deduces then correctly that the value in the conditional
is always true and everything become dead after that.

But what annoys me really is that:
-) once you remove the single-store shortcut, it seems there is
   other problems (I just saw it by doing some code comparison,
   I need to create a few clear examples).
-) here the variable is always undefined, but once you have a var
   undefined in one path and defined in another one path and
   always used when defined then things become really messed up
   (misplaced phi-nodes). It happen for example with code like:
	int foo(int a, int b)
	{
		int var = 0;
		int r;
	
		if (a)
			var = 1;
		if (b)
			r = var;
	
		return r;		// undef if !b
	}
   Wich is perfectly defined when called with a non-zero b.
   I have reasons to believe it's totally unrelated issues though.

-- Luc Van Oostenryck

  reply	other threads:[~2017-03-28 17:00 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-28 12:40 Potential incorrect simplification Dibyendu Majumdar
2017-03-28 13:34 ` Luc Van Oostenryck
2017-03-28 13:58   ` Dibyendu Majumdar
2017-03-28 14:11     ` Luc Van Oostenryck
2017-03-28 14:19       ` Dibyendu Majumdar
2017-03-28 16:20         ` Linus Torvalds
2017-03-28 17:00           ` Luc Van Oostenryck [this message]
2017-03-28 18:02             ` Linus Torvalds
2017-03-28 20:27               ` Luc Van Oostenryck
2017-03-28 21:57                 ` Linus Torvalds
2017-03-28 22:28                   ` Luc Van Oostenryck
2017-03-28 22:22           ` Dibyendu Majumdar
2017-08-06 12:46           ` Christopher Li
2017-08-06 14:00             ` Luc Van Oostenryck
2017-08-06 14:24               ` Christopher Li
2017-08-06 14:54                 ` Christopher Li
2017-08-06 15:07                 ` Luc Van Oostenryck
2017-08-06 15:51                   ` Christopher Li
2017-08-06 16:51                     ` Luc Van Oostenryck
2017-08-06 18:35                       ` Christopher Li
2017-08-06 19:51                         ` Dibyendu Majumdar
2017-08-06 20:08                           ` Luc Van Oostenryck
2017-08-06 19:52                         ` Luc Van Oostenryck
2017-08-06 23:34                           ` Christopher Li
2017-08-07  0:31                             ` Luc Van Oostenryck
2017-08-07  0:38                               ` Christopher Li
2017-08-06 15:52                 ` Dibyendu Majumdar
2017-08-06 16:56                   ` Luc Van Oostenryck
2017-08-06 17:04                     ` Dibyendu Majumdar
2017-08-06 17:45                       ` Luc Van Oostenryck
2017-08-06 17:58                         ` Dibyendu Majumdar
2017-08-06 18:15                           ` Luc Van Oostenryck
2017-08-06 18:18                             ` Dibyendu Majumdar
2017-08-06 18:31                               ` Luc Van Oostenryck
2017-08-07 19:11                   ` [PATCH v2 0/8] fix loading of partially defined bitfield Luc Van Oostenryck
2017-08-07 19:11                     ` [PATCH v2 1/8] Remove single-store shortcut Luc Van Oostenryck
2017-08-07 21:42                       ` Linus Torvalds
2017-08-10  0:29                         ` Christopher Li
2017-08-10  0:41                           ` Luc Van Oostenryck
2017-08-10  0:53                             ` Christopher Li
2017-08-10 11:01                       ` Christopher Li
2017-08-10 12:26                         ` Luc Van Oostenryck
2017-08-10 13:25                           ` Christopher Li
2017-08-07 19:11                     ` [PATCH v2 2/8] new helper: def_opcode() Luc Van Oostenryck
2017-08-07 19:12                     ` [PATCH v2 3/8] reuse nbr_pseudo_users() Luc Van Oostenryck
2017-08-07 19:12                     ` [PATCH v2 4/8] change the masking when loading bitfields Luc Van Oostenryck
2017-08-07 19:12                     ` [PATCH v2 5/8] simplify ((A & M') | B ) & M when M' & M == 0 Luc Van Oostenryck
2017-08-07 19:12                     ` [PATCH v2 6/8] transform (A & M) >> S to (A >> S) & (M >> S) Luc Van Oostenryck
2017-08-08  0:22                       ` Christopher Li
2017-08-08  0:29                         ` Luc Van Oostenryck
2017-08-08  1:48                           ` Christopher Li
2017-08-08  1:00                         ` Linus Torvalds
2017-08-08  1:38                           ` Luc Van Oostenryck
2017-08-08  1:50                           ` Christopher Li
2017-08-07 19:12                     ` [PATCH v2 7/8] transform (A << S) >> S into A & (-1 " Luc Van Oostenryck
2017-08-07 21:54                       ` Linus Torvalds
2017-08-07 22:08                         ` Luc Van Oostenryck
2017-08-07 22:27                           ` Luc Van Oostenryck
2017-08-07 19:12                     ` [PATCH v2 8/8] fix: cast of OP_AND only valid if it's an OP_CAST Luc Van Oostenryck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170328170049.2y6lwxx64yzjjwmc@macpro.local \
    --to=luc.vanoostenryck@gmail.com \
    --cc=linux-sparse@vger.kernel.org \
    --cc=mobile@majumdar.org.uk \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.