[wide-int] Simplify div_if_zero_remainder

Richard Sandiford rdsandiford@googlemail.com
Sat Nov 9 11:09:00 GMT 2013


wide-int adds some code to div_if_zero_remainder to handle mismatched signs.
I think it's trying to make sure that we do the division to "infinite"
precision, extending each operand according to its own sign.  We can do
that more easily using wi::to_widest.  Using to::widest should also be
chaper.

Tested on powerpc64-linux-gnu and by rerunning the assembly comparison.
OK to install?

Thanks,
Richard


Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	2013-11-09 09:39:28.207810833 +0000
+++ gcc/fold-const.c	2013-11-09 09:39:29.198817531 +0000
@@ -170,31 +170,10 @@ protected_set_expr_location_unshare (tre
 tree
 div_if_zero_remainder (const_tree arg1, const_tree arg2)
 {
-  wide_int quo;
-  wide_int warg1 = arg1;
-  wide_int warg2 = arg2;
-  signop sgn = TYPE_SIGN (TREE_TYPE (arg1));
-  signop sgn2 = TYPE_SIGN (TREE_TYPE (arg2));
+  widest_int quo;
 
-  if (sgn != sgn2)
-    {
-      /* When signedness mismatches, we promote the unsigned value to
-	 a signed value.  We preserve the value by extending the
-	 precision by 1 bit, iff the top bit is set.  */
-      if (sgn == UNSIGNED)
-	{
-	  if (wi::neg_p (warg1))
-	    warg1 = wide_int::from (warg1, warg1.get_precision () + 1, sgn);
-	  sgn = SIGNED;
-	}
-      else
-	{
-	  if (wi::neg_p (warg2))
-	    warg2 = wide_int::from (warg2, warg2.get_precision () + 1, sgn2);
-	}
-    }
-
-  if (wi::multiple_of_p (warg1, warg2, sgn, &quo))
+  if (wi::multiple_of_p (wi::to_widest (arg1), wi::to_widest (arg2),
+			 SIGNED, &quo))
     return wide_int_to_tree (TREE_TYPE (arg1), quo);
 
   return NULL_TREE; 



More information about the Gcc-patches mailing list