Hello,

I am doing some code instrumentation for program memory access
validation using gcc-4.1 head.
For every assignment, p=q

I pass the address of the operands, "&p" and "&q" to an external
library function.

This works fine at O0, but at O1, some legitimate code gets optimized
away. In the dumps generated by my pass( runs immediately after
t08.useless), there is a statement

*D.2383 = __taint_addr10;

The "__taint_addr10" is an artificial variable created by my pass,
which replaces the original operand, since the address of the original
operand is taken. If this variable is used later in any expression
with a binary operator or a COND_EXPR, then it must be replaced by a
copy that doesnot have its address taken. So, in this prototype
currently I replace its occurance in every rhs expression.

This statement gets optimized away in the dead code elemination(t26.dce1)
pass, because in the "is_global_hidden_store" function , there is a
check :

  if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))

which fails, and the function returns false. Thus, this statement is
not marked as necessary and gets removed.

The program which I am instrumenting is as follows:

int
main()
{
  int i, k=1, n, *x;

  printf( "Enter n: ");
  scanf( "%d", &n );

  x = malloc( (n+1) * sizeof(int));

  x[1] = 1;

  while (k)
    {
      if ( x[k]== n)
        {
            k--;
            x[k]++;
        }
      else
        {
          k++;
          x[k] = x[k-1] + 1;
        }
    }
return 0;
        
}


The dump after my instrumentation for "x[k]++" in the first if block
in while looks like -

L1:

...
...
  /* Computes in __taint_addr.121 = k*4 */
  __taint_addr.115 = k;
  D.2381 = __taint_addr.115 * 4;
  __taint_addr.125 = D.2381;


  __taint_addr.128 = x;
  D.2383 = __taint_addr.125 + __taint_addr.128;

  library_call (D.2383);

/* Computes the incremented value in D.2385 */
  D.2384 = *D.2383;
  __taint_addr.135 = D.2384;
  D.2385 = __taint_addr.135 + 1;

  __taint_addr.11 = D.2385
  *D.2383 = __taint_addr.11; /* ==> gets optimized away */



I would be thankful if someone could give me pointers to what could be
going wrong here. Clearly, The reference to *D.2383, is a valid heap
address, and hence must not be removed as a dead store. There is
something which my instrumentation is messing up.


I looked at the alias analysis dumps t20.alias1 . What I noticed is
that in function update_alias_info (),
there is a place where gcc processes each operand use is seen ,and for
pointers, it determines whether they are dereferenced by a given
statement or not. So, I added some printfs there, as follows:

FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
    {
      tree op, var;
      var_ann_t v_ann;
      struct ptr_info_def *pi;
      bool is_store, is_potential_deref;
      unsigned num_uses, num_derefs;

      op = USE_FROM_PTR (use_p);

/* Debug statemets added */

==>      fprintf (stderr, "Stament and uses\n");
==>      debug_generic_stmt (stmt);
==>      debug_generic_stmt (op);


At this point, the stmt:

#   VUSE <D.2383_307>;
*D.2383 = __taint_addr.11D.3119_323;

_doesnot_ show any used op like,

D.2383.

why is this happening?


Thanks in advance,
Prateek.

Reply via email to