[PATCH] Fix get_min_precision in __builtin_*_overflow expansion (PR target/66112)

Jakub Jelinek jakub@redhat.com
Tue May 12 18:43:00 GMT 2015


Hi!

This patch fixes a thinko in get_min_precision.  If we want UNSIGNED
number and arg_min is signed, but non-negative, calling wi::min_precision
with SIGNED resulted in one bigger precision than necessary.  If
get_min_precision is originally called with SIGNED and sign is then
changed into UNSIGNED, this will be accounted for in the + (orig_sign != sign)
later on.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2015-05-12  Jakub Jelinek  <jakub@redhat.com>

	PR target/66112
	* internal-fn.c (get_min_precision): Use UNSIGNED instead of
	SIGNED to get precision of non-negative value.

	* gcc.target/i386/pr66112-1.c: New test.

--- gcc/internal-fn.c.jj	2015-04-17 13:50:55.000000000 +0200
+++ gcc/internal-fn.c	2015-05-12 10:33:13.380205685 +0200
@@ -399,7 +399,7 @@ get_min_precision (tree arg, signop sign
     }
   else if (sign == UNSIGNED && !wi::neg_p (arg_min, SIGNED))
     {
-      int p = wi::min_precision (arg_max, SIGNED);
+      int p = wi::min_precision (arg_max, UNSIGNED);
       prec = MIN (prec, p);
     }
   return prec + (orig_sign != sign);
--- gcc/testsuite/gcc.target/i386/pr66112-1.c.jj	2015-05-12 10:36:11.253284919 +0200
+++ gcc/testsuite/gcc.target/i386/pr66112-1.c	2015-05-12 10:36:57.239529802 +0200
@@ -0,0 +1,16 @@
+/* PR target/66112 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned int
+foo (long long a, long long b)
+{
+  unsigned int res;
+  a &= ~0U;
+  b &= ~0U;
+  if (__builtin_mul_overflow (a, b, &res))
+    res = 0x123U;
+  return res;
+}
+
+/* { dg-final { scan-assembler "jn?o\[ \t\]" } } */

	Jakub



More information about the Gcc-patches mailing list