On May 12, 2015 8:40:32 PM GMT+02:00, Jakub Jelinek <ja...@redhat.com> wrote: >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?
OK. Thanks, Richard. >2015-05-12 Jakub Jelinek <ja...@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