[Bug target/80808] [7/8 Regression] gnupg miscompilation on arm starting with r241660

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Mon May 22 07:44:00 GMT 2017


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80808

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Smaller testcase that still works at -O1 and fails at -O2 (+ -march=armv7-a
-mfpu=vfpv3-d16 -mfloat-abi=hard in both cases):

static __attribute__ ((noinline, noclone)) unsigned
mpihelp_divrem (unsigned *qp, int qextra_limbs,
                unsigned *np, int nsize,
                unsigned *dp, int dsize)
{
  unsigned most_significant_q_limb = 0;
  switch (dsize)
    {
    case 0:
      return 1 / dsize;
    case 2:
      {
        int i;
        unsigned n1, n0, n2, d1, d0;
        np += nsize - 2;
        d1 = dp[1];
        d0 = dp[0];
        n1 = np[1];
        n0 = np[0];
        if (n1 >= d1 && (n1 > d1 || n0 >= d0))
          {
            __asm__ ("subs %1, %4, %5\n" "sbc  %0, %2, %3"
                     : "=r" (n1), "=&r" (n0)
                     : "r" (n1), "rI" (d1), "r" (n0), "rI" (d0));
            most_significant_q_limb = 1;
          }
        for (i = qextra_limbs + nsize - 2 - 1; i >= 0; i--)
          {
            unsigned q;
            unsigned r;
            if (i >= qextra_limbs)
              np--;
            else
              np[0] = 0;
            if (n1 == d1)
              {
                q = ~(unsigned) 0;
                r = n0 + d1;
                if (r < d1)
                  {
                    __asm__ ("adds %1, %4, %5\n" "adc  %0, %2, %3"
                             : "=r" (n1), "=&r" (n0)
                             : "%r" (r - d0), "rI" (0),
                               "%r" (np[0]), "rI" (d0));
                    qp[i] = q;
                    continue;
                  }
                n1 = d0 - (d0 != 0 ? 1 : 0);
                n0 = -d0;
              }
            else
              {
                do
                  {
                    unsigned __d1, __d0, __q1, __q0, __r1, __r0, __m;
                    __d1 = (d1 >> ((8 * (4)) / 2));
                    __d0 = (d1 & ((1U << ((8 * (4)) / 2)) - 1));
                    __r1 = (n1) % __d1;
                    __q1 = (n1) / __d1;
                    __m = (unsigned) __q1 *__d0;
                    __r1 = __r1 * (1U << ((8 * (4)) / 2))
                           | ((unsigned) (n0) >> ((8 * (4)) / 2));
                    if (__r1 < __m)
                      {
                        __q1--, __r1 += (d1);
                        if (__r1 >= (d1))
                          if (__r1 < __m)
                            __q1--, __r1 += (d1);
                      }
                    __r1 -= __m;
                    __r0 = __r1 % __d1;
                    __q0 = __r1 / __d1;
                    __m = (unsigned) __q0 *__d0;
                    __r0 = __r0 * (1U << ((8 * (4)) / 2))
                           | (n0 & (((unsigned) 1 << ((8 * (4)) / 2)) - 1));
                    if (__r0 < __m)
                      {
                        __q0--, __r0 += (d1);
                        if (__r0 >= (d1))
                          if (__r0 < __m)
                            __q0--, __r0 += (d1);
                      }
                    __r0 -= __m;
                    q = (unsigned) __q1 * (1U << ((8 * (4)) / 2)) | __q0;
                    r = __r0;
                  }
                while (0);
                __asm__ ("umull %r1, %r0, %r2, %r3"
                         : "=&r" (n1), "=r" (n0)
                         : "r" (d0), "r" (q):"r0", "r1");
              }
            n2 = np[0];
          q_test:
            if (n1 > r || (n1 == r && n0 > n2))
              {
                q--;
                __asm__ ("subs %1, %4, %5\n" "sbc  %0, %2, %3"
                         : "=r" (n1), "=&r" (n0)
                         : "r" (n1), "rI" (0), "r" (n0), "rI" (d0));
                r += d1;
                if (r >= d1)
                  goto q_test;
              }
            qp[i] = q;
            __asm__ ("subs %1, %4, %5\n" "sbc  %0, %2, %3"
                     : "=r" (n1), "=&r" (n0)
                     : "r" (r), "rI" (n1), "r" (n2), "rI" (n0));
          }
        np[1] = n1;
        np[0] = n0;
      }
      break;
    default:
      __builtin_abort ();
    }
  return most_significant_q_limb;
}

int
main ()
{
  unsigned qp[1];
  unsigned np[3] = { 0xdaafeaa6, 0x0e77816a, 1 };
  unsigned dp[2] = { 0x6816ec64, 0xb9d5666d };
  volatile int l = 0;
  unsigned ret = mpihelp_divrem (qp + l, 0 + l, np + l, 3 + l, dp + l, 2 + l);
  if (ret != 0 || qp[0] != 1 || np[0] != 0x7298fe42 || np[1] != 0x54a21afd)
    __builtin_abort ();
  return 0;
}


More information about the Gcc-bugs mailing list