This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] Fix some pessimizations due to fixes for PRs 27144 and 27639


Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz> writes:

> Hello,
> 
> > Unfortunately, this patch causes a regression of builtins-14.c on (at
> > least) i686-pc-linux-gnu.  The problem is that the compiler miscompiles
> > itself, incorrectly optimizing the loop in real.c:div_significands.
> > Because you claim to have bootstrapped and regression tested on
> > i686, I supect that it wasn't the bootstrapped compiler that you
> > used for regression testing [a stage1 compiler regtests fine].
> 
> here is the fix.  The problem was that we assumed that if
> 0 <= x <= bound, cst >= 0, and x - cst >= 0, then
> x - cst <= bound - cst.  This is true in signed types,
> however, for the unsigned ones, we must also know that x >= cst,
> otherwise the subtraction overflows.
> 
> Bootstrapped & regtested on i686, x86_64 and ppc.
> 
> Zdenek
> 
> 	* tree-ssa-loop-niter.c (implies_ge_p): New function.
> 	(derive_constant_upper_bound): Handle OP0 - CST in unsigned types
> 	correctly.
> 
> Index: tree-ssa-loop-niter.c
> ===================================================================
> *** tree-ssa-loop-niter.c	(revision 114758)
> --- tree-ssa-loop-niter.c	(working copy)
> *************** implies_nonnegative_p (tree cond, tree v
> *** 1491,1496 ****
> --- 1491,1514 ----
>     return nonzero_p (compare);
>   }
>   
> + /* Returns true if we can prove that COND ==> A >= B.  */
> + 
> + static bool
> + implies_ge_p (tree cond, tree a, tree b)
> + {
> +   tree compare = fold_build2 (GE_EXPR, boolean_type_node, a, b);
> 
  You could probably save some memory by using fold_binary here.

> +   if (nonzero_p (compare))
> +     return true;
> + 
> +   if (nonzero_p (cond))
> +     return false;

 Then calling build2 here if compare is NULL_TREE.

> +   compare = tree_simplify_using_condition_1 (cond, compare);
> + 
> +   return nonzero_p (compare);
> + }
> + 
>   /* Returns a constant upper bound on the value of expression VAL.  VAL
>      is considered to be unsigned.  If its type is signed, its value must
>      be nonnegative.
> *************** derive_constant_upper_bound (tree val, t
> *** 1554,1561 ****
>   	  || !implies_nonnegative_p (additional, op0))
>   	return max;
>   
> !       /* Canonicalize to OP0 - CST.  */
>         cst = tree_to_double_int (op1);
>         if (TREE_CODE (val) == PLUS_EXPR)
>   	cst = double_int_neg (cst);
>   
> --- 1572,1582 ----
>   	  || !implies_nonnegative_p (additional, op0))
>   	return max;
>   
> !       /* Canonicalize to OP0 - CST.  Consider CST to be signed, in order to
> ! 	 choose the most logical way how to treat this constant regardless
> ! 	 of the signedness of the type.  */
>         cst = tree_to_double_int (op1);
> +       cst = double_int_sext (cst, TYPE_PRECISION (type));
>         if (TREE_CODE (val) == PLUS_EXPR)
>   	cst = double_int_neg (cst);
>   
> *************** derive_constant_upper_bound (tree val, t
> *** 1568,1574 ****
>   	  if (double_int_negative_p (cst))
>   	    return max;;
>   
> ! 	  /* Case OP0 + CST.  We need to check that
>   	     BND <= MAX (type) - CST.  */
>   
>   	  mmax = double_int_add (max, double_int_neg (cst));
> --- 1589,1595 ----
>   	  if (double_int_negative_p (cst))
>   	    return max;;
>   
> ! 	  /* OP0 + CST.  We need to check that
>   	     BND <= MAX (type) - CST.  */
>   
>   	  mmax = double_int_add (max, double_int_neg (cst));
> *************** derive_constant_upper_bound (tree val, t
> *** 1579,1587 ****
> --- 1600,1626 ----
>   	}
>         else
>   	{
> + 	  /* OP0 - CST, where CST >= 0.
> + 
> + 	     If TYPE is signed, we have already verified that OP0 >= 0, and we
> + 	     know that the result is nonnegative.  This implies that
> + 	     VAL <= BND - CST.
> + 
> + 	     If TYPE is unsigned, we must additionally know that OP0 >= CST,
> + 	     otherwise the operation underflows.
> + 	   */
> + 
> + 	  /* This should only happen if the type is unsigned; however, for
> + 	     programs that use overflowing signed arithmetics even with
> + 	     -fno-wrapv, we may get here for signed types as well.  */
>   	  if (double_int_ucmp (bnd, cst) < 0)
>   	    return max;
>   
> + 	  if (TYPE_UNSIGNED (type)
> + 	      && !implies_ge_p (additional,
> + 				op0, double_int_to_tree (type, cst)))
> + 	    return max;
> + 
>   	  bnd = double_int_add (bnd, double_int_neg (cst));
>   	}
>   
> 

-- 
Thanks,
Jim

http://www.csclub.uwaterloo.ca/~ja2morri/
http://phython.blogspot.com
http://open.nit.ca/wiki/?page=jim


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]