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

            Bug ID: 86380
           Summary: Incorrect inequality in function chose_multiplier in
                    file expmed.c in GCC.8.1.0 and earlier versions
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: colinwb at yahoo dot co.uk
  Target Milestone: ---

In this line near the end of function choose_multiplier in file expmed.c
        return mhigh.to_uhwi () >= mask;
the ">=" should really be ">".
As it is when precision = n < HOST_BITS_PER_WIDE_INT and d = 2**(n-1) + 1,
so post_shift = 2*n - 1 - n = n - 1 and mhigh = 2**n - 1,
choose_multiplier wrongly returns that the upper bit should be set.

unsigned HOST_WIDE_INT
choose_multiplier (unsigned HOST_WIDE_INT d, int n, int precision,
                   unsigned HOST_WIDE_INT *multiplier_ptr,
                   int *post_shift_ptr, int *lgup_ptr)
...
  *post_shift_ptr = post_shift;
  *lgup_ptr = lgup;
  if (n < HOST_BITS_PER_WIDE_INT)
    {
      unsigned HOST_WIDE_INT mask = (HOST_WIDE_INT_1U << n) - 1;
      *multiplier_ptr = mhigh.to_uhwi () & mask;
      return mhigh.to_uhwi () >= mask;
    }
  else
    {
      *multiplier_ptr = mhigh.to_uhwi ();
      return wi::extract_uhwi (mhigh, HOST_BITS_PER_WIDE_INT, 1);
    }
}

Reply via email to