[Bug tree-optimization/95853] Failure to optimize add overflow pattern to __builtin_add_overflow

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Nov 20 15:48:28 GMT 2020


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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Created attachment 49606
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49606&action=edit
gcc11-pr95853-wip.patch

I've tried to implement this, but on:
#if __SIZEOF_INT128__
typedef __uint128_t W;
typedef unsigned long long T;
#else
typedef unsigned long long W;
typedef unsigned int T;
#endif

struct S { int p; T r; };

struct S
foo (T x, T y)
{
  W z = (W) x + y;
  return (struct S) { z > ~(T) 0, (T) z };
}

struct S
bar (T x)
{
  W z = (W) x + 132;
  return (struct S) { z > ~(T) 0, (T) z };
}

struct S
baz (T x, unsigned short y)
{
  W z = (W) x + y;
  return (struct S) { z > ~(T) 0, (T) z };
}

struct S
qux (unsigned short x, T y)
{
  W z = (W) x + y;
  return (struct S) { z > ~(T) 0, (T) z };
}

it actually handles only the baz and qux functions.  The problem is that for
foo and bar forwprop1 (for this optimization unhelpfully) forward propagates
the addition, so we end up with:
  _1 = (__int128 unsigned) x_6(D);
  _2 = (__int128 unsigned) y_7(D);
  z_8 = _1 + _2;
  _3 = z_8 > 18446744073709551615;
  _4 = (int) _3;
  _5 = x_6(D) + y_7(D);
  D.1971.p = _4;
  D.1971.r = _5;
  return D.1971;
and there is no (easy) connection between the two additions.  I guess I could
look through immediate uses of the rhs1's setter in that case.


More information about the Gcc-bugs mailing list