[tree-ssa] fix latent & real bugs in BIT_FIELD_REFs

Paolo Bonzini paolo.bonzini@polimi.it
Wed Mar 24 16:04:00 GMT 2004


> In fact, we don't even need to handle BIT_FIELD_REFs in
> get_virtual_var.  It's only called from add_stmt_operand, which should
> never be receiving a BIT_FIELD_REF.

Nope.  You can get a BIT_FIELD_REF from add_stmt_operand when fold tries to 
put together separate COMPONENT_REFs into a single BIT_FIELD_REF; then you 
want a virtual use from a BIT_FIELD_REF -- indeed that's why my testcase 
failed *with current unpatched treessa*.  Take a look at what the test case 
does.

main ()
{
  unsigned char T.1;
  unsigned char T.0;

<bb 0>:
  #   i_2 = VDEF <i_1>;
  i.b = 1;
  #   VUSE <i_2>;
  T.0_3 = BIT_FIELD_REF <i, 8, 0>;
  T.1_4 = T.0_3 & 3;
  if (T.1_4 == 1) goto <L0>; else goto <L1>;

<L0>:;
  exit (0);

<L1>:;
  #   i_5 = VDEF <i_2>;
  i.c = 0;
  #   VUSE <i_5>;                     <<<<<<<<
  T.0_6 = BIT_FIELD_REF <i, 8, 0>;
  T.1_7 = T.0_6 & 3;
  if (T.1_7 == 1) goto <L2>; else goto <L3>;

<L2>:;
  exit (0);

<L3>:;
  abort ();
}

If the marked VUSE is not there, dom somehow believes that i_2 is ok as well 
and threads through the jump to L3, because the same test was false above.  
And if get_virtual_var does not handle BIT_FIELD_REFs, you get wrong code. 
:-(

> Notice how the handler for
> ARRAY_REF/COMPONENT_REF calls add_stmt_operand directly, but the
> original handler for BIT_FIELD_REF recurses into TREE_OPERAND(t,0). 
> That's why you were running into the verifier ICE.

It seems to me (unlike I miss something obvious) that the change to 
get_expr_operands is just an optimization, you end up calling 
add_stmt_operand anyway as soon as you recurse into get_expr_operands and 
reach this point:

  /* If we found a variable, add it to DEFS or USES depending on the
     operand flags.  */
  if (SSA_VAR_P (expr))
    {
      add_stmt_operand (expr_p, stmt, flags, prev_vops);
      return;
    }


BIT_FIELD_REF *can* and *will* appear with both real and virtual operands, 
unlike COMPONENT_REF; if its operand is virtual, it behaves exactly like 
COMPONENT_REF (with a VUSE), while if it is real, it is a simple USE.

Paolo

-------------------------------------------------
This mail sent through IMP: http://horde.org/imp/



More information about the Gcc-patches mailing list