http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61111

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
I rather suspect a merge error.  The following two need to match to not
oscillate:

          /* Minimize the number of bits set in C1, i.e. C1 := C1 & ~C2,
             unless (C1 & ~C2) | (C2 & C3) for some C3 is a mask of some
             mode which allows further optimizations.  */
          c1 &= msk;
          c2 &= msk;
          wide_int c3 = c1.and_not (c2);
          for (w = BITS_PER_UNIT; w <= width; w <<= 1)
            {
              wide_int mask = wi::mask (width - w, false,
                                        TYPE_PRECISION (type));
              if (((c1 | c2) & mask) == mask && c1.and_not (mask) == 0)
                {
                  c3 = mask;
                  break;
                }
            }

and

              /* Avoid the transform if arg1 is a mask of some
                 mode which allows further optimizations.  */
              int pop = wi::popcount (warg1);
              if (!(pop >= BITS_PER_UNIT
                    && exact_log2 (pop) != -1
                    && wi::mask (pop, false, warg1.get_precision ()) == warg1))
                return fold_build2_loc (loc, code, type, op0,
                                        wide_int_to_tree (type, masked));

where the above is from

              unsigned HOST_WIDE_INT mask
                = HOST_WIDE_INT_M1U >> (HOST_BITS_PER_WIDE_INT - w);

that doesn't match the wi::mask call which should instead use w, not
width - w as argument?

That fixes the testcase.

Reply via email to