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

            Bug ID: 79941
           Summary: [7 Regression] Altivec vec_vmuleub regression
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jakub at gcc dot gnu.org
  Target Milestone: ---

As mentioned in https://bugzilla.redhat.com/show_bug.cgi?id=1429961,
vec_vmul{e,o}u{b,h} as well as vec_vmul{e,o} with unsigned vector arguments
regressed, most likely with r243807.

Short testcase:

#include <altivec.h>

int
main ()
{
  vector unsigned char v0 = {1, 0, 0, 0, 0, 0, 0, 0};
  vector unsigned char v1 = {0xff, 0, 0, 0, 0, 0, 0, 0};
  vector unsigned short res = vec_vmuleub (v0, v1);
  if (res[0] != (unsigned short)v0[0] * (unsigned short)v1[0])
    __builtin_abort ();
  return 0;
}

The problem is that for e.g. __builtin_vec_vmuleub, for some strange reason the
builtin function type is using signed vector arguments and result.
There is also VMULEUB_UNS and similar stuff, but the corresponding builtin
doesn't seem to work either (and nothing in altivec.h uses it).
That unexpected function prototype results in VIEW_CONVERT_EXPRs being added
for the arguments and return value, and then it is folded by
rs6000_gimple_fold_builtin into
VEC_WIDEN_MULT_EVEN_EXPR/VEC_WIDEN_MULT_ODD_EXPR, but as the arguments are
signed vectors, in the end it works as the *sb builtin instead.

So, either the weird builtin function prototypes are bugs, then likely the
VMULEUB_UNS etc. stuff should be removed and rs6000.c (builtin_function_type)
should treat the non-UNS suffixed UB/UH mule/mulo builtins as unsigned.

Or rs6000_gimple_fold_builtin needs to VIEW_CONVERT_EXPR the arguments again to
unsigned and back if there is signedness mismatch.

Reply via email to