[Bug target/97437] builtins subcarry and addcarry still not generate the right code. Not get optimized to immediate value

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Oct 15 12:29:32 GMT 2020


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

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Anyway,
#include <x86intrin.h>

void
foo (unsigned int a[4], unsigned int b[4])
{
  unsigned char carry = 0;
  carry = _addcarry_u32 (carry, 42, b[0], &a[0]);
  carry = _addcarry_u32 (carry, b[1], 43, &a[1]);
  carry = _addcarry_u32 (carry, 0, b[2], &a[2]);
  _addcarry_u32 (carry, b[3], 1, &a[3]);
}

void
bar (unsigned int a[4], unsigned int b[4])
{
  unsigned char carry = 0;
  carry = _subborrow_u32 (carry, a[0], 42, &a[0]);
  carry = _subborrow_u32 (carry, a[1], 43, &a[1]);
  carry = _subborrow_u32 (carry, a[2], 0, &a[2]);
  _subborrow_u32 (carry, a[3], 1, &a[3]);
}

void
baz (unsigned long long a[4], unsigned long long b[4])
{
  unsigned char carry = 0;
  carry = _addcarry_u64 (carry, 42, b[0], &a[0]);
  carry = _addcarry_u64 (carry, b[1], 43, &a[1]);
  carry = _addcarry_u64 (carry, 0, b[2], &a[2]);
  _addcarry_u64 (carry, b[3], 1, &a[3]);
}

void
qux (unsigned long long a[4], unsigned long long b[4])
{
  unsigned char carry = 0;
  carry = _subborrow_u64 (carry, a[0], 42, &a[0]);
  carry = _subborrow_u64 (carry, a[1], 43, &a[1]);
  carry = _subborrow_u64 (carry, a[2], 0, &a[2]);
  _subborrow_u64 (carry, a[3], 1, &a[3]);
}
shows an optimization problem, here the immediates aren't used multiple times,
so it would be certainly beneficial to use the immediate forms.
The problem is that neither the addcarry<mode> nor subborrow<mode> patterns do
allow immediates, addcarry<mode> has *addcarry<mode>_1 alternative that should
handle them but isn't matched in this case, and subborrow<mode> doesn't have
any.  The problem is that in order to describe what the patterns are doing in
detail we need to zero_extend the operands, but having zero_extend of a
const_int is not valid RTL.  Unfortunately when combiner substitutes immediates
into these, it simplifies the patterns too and we lose the CCCmode that the
patterns need, and unlike the fix committed yesterday, SELECT_CC_MODE can't
really do anything about that, because the comparisons aren't really specific
to CCCmode.


More information about the Gcc-bugs mailing list