The problem starts when the operand scanner in mem-ssa determines that since 
neither
u[1] nor u[2] have corresponding SFTs, they get to use 'u' directly.  This is 
different
from mainline.  In mainline we use SFT.0 for all of them:

foo ()
{
  short unsigned int u[1];

  #   SFT.0_2 = V_MUST_DEF <SFT.0_1>;
  u[0] = 1;

  #   SFT.0_3 = V_MUST_DEF <SFT.0_2>;
  u[0] = 0;

  #   SFT.0_4 = V_MAY_DEF <SFT.0_3>;
  u[1] = 1;

  #   SFT.0_5 = V_MAY_DEF <SFT.0_4>;
  u[2] = 2;

  [ ... ]
}

Which does not trigger the validation error, but I believe it's less precise
than what is computed in mem-ssa.  Certainly u[1] and u[2] cannot affect u[0].
Nor can they affect each other, but this is undefined code, so it's not such a
big deal.

The verifier is being tricked because it uses a fairly simple test:

  if (is_virtual && var_ann (SSA_NAME_VAR (ssa_name))
      && get_subvars_for_var (SSA_NAME_VAR (ssa_name)) != NULL)
    {
      error ("found real variable when subvariables should have appeared");
    ....

I'm meaning to change the verifier to check if the statement is really
referencing a sub-variable, but first I wanted to check if the idea
makes sense.


Sure. If you want to make the verifier trigger less on undefined code
because you are optimizing it better, feel free!

Just be careful you don't get tricked by the pointer version of the above.

struct foo {
int a[1];
};

struct foo *b = malloc(sizeof(foo) + 30 ints)
b->a[24] = 9;

We guarantee this will work.

--Dan

Reply via email to