[patch] for PR 21963

Zdenek Dvorak rakdver@atrey.karlin.mff.cuni.cz
Thu Jun 9 07:33:00 GMT 2005


Hello,

this bug is caused by the fact that constant_multiple_of is used
slightly differently in get_computation_aff and in
get_computation_cost_at.  Concretely, assume that sizeof (long) = sizeof
(void *) = 64 and sizeof (int) = 32, and type of 's' is int.  Now
suppose that the step of the use we are expressing is ustep = '(long) s',
and step of the candidate is cstep = '(void *) (long) s'.

In get_computation_cost_at, we use constant_multiple_of directly on
these values.  This strips the nop cast to void * from cstep and
determines that ustep and cstep are equal, and that the use can
be expressed for cost 0.

In get_computation_aff, both ustep and cstep are first casted to
unsigned long.  I.e. ustep = '(unsigned long) s', and
cstep = '(unsigned long) (void *) (long) s'.  After striping nops,
cstep becomes '(long) s', which is not recognized as equal to
'(unsigned long) s', and that the use cannot be expressed.  This
causes us to return NULL for the computation and segfault shortly
follows.

It would be possible to change constant_multiple_of to handle this
case, but as long as we use constant_multiple_of differently in
the two functions, we risk similar problems.  Thus, as a first step,
this patch causes get_computation_aff to also work with the uncasted
values whenever possible.

Bootstrapped & regtested on ppc and x86_64.

Zdenek

	PR tree-optimization/21963
	* tree-ssa-loop-ivopts.c (get_computation_aff): Use
	constant_multiple_of in the same way get_computation_cost_at does.

Index: tree-ssa-loop-ivopts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop-ivopts.c,v
retrieving revision 2.79
diff -c -3 -p -r2.79 tree-ssa-loop-ivopts.c
*** tree-ssa-loop-ivopts.c	8 Jun 2005 22:47:07 -0000	2.79
--- tree-ssa-loop-ivopts.c	8 Jun 2005 22:59:05 -0000
*************** get_computation_aff (struct loop *loop,
*** 2983,2988 ****
--- 2983,2989 ----
    unsigned HOST_WIDE_INT ustepi, cstepi;
    HOST_WIDE_INT ratioi;
    struct affine_tree_combination cbase_aff, expr_aff;
+   tree cstep_orig = cstep, ustep_orig = ustep;
  
    if (TYPE_PRECISION (utype) > TYPE_PRECISION (ctype))
      {
*************** get_computation_aff (struct loop *loop,
*** 3012,3024 ****
        expr = fold_convert (uutype, expr);
        cbase = fold_convert (uutype, cbase);
        cstep = fold_convert (uutype, cstep);
      }
  
!   if (cst_and_fits_in_hwi (cstep)
!       && cst_and_fits_in_hwi (ustep))
      {
!       ustepi = int_cst_value (ustep);
!       cstepi = int_cst_value (cstep);
  
        if (!divide (TYPE_PRECISION (uutype), ustepi, cstepi, &ratioi))
  	{
--- 3013,3030 ----
        expr = fold_convert (uutype, expr);
        cbase = fold_convert (uutype, cbase);
        cstep = fold_convert (uutype, cstep);
+ 
+       /* If the conversion is not noop, we must take it into account when
+ 	 considering the value of the step.  */
+       if (TYPE_PRECISION (utype) < TYPE_PRECISION (ctype))
+ 	cstep_orig = cstep;
      }
  
!   if (cst_and_fits_in_hwi (cstep_orig)
!       && cst_and_fits_in_hwi (ustep_orig))
      {
!       ustepi = int_cst_value (ustep_orig);
!       cstepi = int_cst_value (cstep_orig);
  
        if (!divide (TYPE_PRECISION (uutype), ustepi, cstepi, &ratioi))
  	{
*************** get_computation_aff (struct loop *loop,
*** 3032,3038 ****
      }
    else
      {
!       ratio = constant_multiple_of (uutype, ustep, cstep);
        if (!ratio)
  	return false;
  
--- 3038,3044 ----
      }
    else
      {
!       ratio = constant_multiple_of (uutype, ustep_orig, cstep_orig);
        if (!ratio)
  	return false;
  



More information about the Gcc-patches mailing list