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

            Bug ID: 93819
           Summary: PPC64 builtin vec_rlnm() argument order is wrong.
           Product: gcc
           Version: 7.5.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: cel at us dot ibm.com
  Target Milestone: ---

Created attachment 47872
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47872&action=edit
test program to demonstrate the bug.

The API for the PPC 64 vec_rlnm() builtin says:

VEC_RLNM (ARG1, ARG2, ARG3)
Purpose:
  Rotates each element of a vector left; then intersects (AND) it with a mask.

  Result value:
  Each element of vector ARG1 is rotated left; then intersected (AND) with a
mask       
  specified by ARG2 and ARG3.

  ARG2 contains the shift count for each element in the low-order byte, with  
  other bytes zero.

  ARG3 contains the mask begin and mask end for each element, with the mask end 
  in the low-order byte, the mask begin in the next higher byte, and other
bytes 
  zero.

  vector unsigned int vec_rlnm (vector unsigned int, vector unsigned int,
    vector unsigned int);

  vector unsigned long long vec_rlnm (vector unsigned long long, 
    vector unsigned long long, vector unsigned long long);

However the current implementation has the shift value in argument 3 and the
mask information in argument 2.

The following is the output from a test program:


ABI says:
VEC_RLNM (ARG1, ARG2, ARG3)
ARG2 contains the shift count for each element in the low-order
byte, with other bytes zero.
ARG3 contains the mask begin and mask end for each element, with
the mask end in the low-order byte, the mask begin in the next
higher byte, and other bytes zero.

Vector int test case: mask begin = 0, mask end = 4, shift = 16

vec_arg1_int[0] = 0x12345678
vec_arg2_int[0] = 16 (0x10)
vec_arg3_int[0] = 4 (0x4)
vec_result_int[0] = 0x23450000
ERROR: Int result does not match expected result 0x50000000
vec_arg1_int[1] = 0x23456789
vec_arg2_int[1] = 16 (0x10)
vec_arg3_int[1] = 4 (0x4)
vec_result_int[1] = 0x34560000
ERROR: Int result does not match expected result 0x60000000
vec_arg1_int[2] = 0x3456789a
vec_arg2_int[2] = 16 (0x10)
vec_arg3_int[2] = 4 (0x4)
vec_result_int[2] = 0x45678000
ERROR: Int result does not match expected result 0x78000000
vec_arg1_int[3] = 0x456789ab
vec_arg2_int[3] = 16 (0x10)
vec_arg3_int[3] = 4 (0x4)
vec_result_int[3] = 0x56788000
ERROR: Int result does not match expected result 0x88000000
Vector long long int test case: mask begin = 0, mask end = 4, shift = 20

vec_arg1_di[0] = 0x123456789abcde00
vec_arg2_di[0] = 20 (0x14)
vec_arg3_di[0] = 4 (0x4)
vec_result_di[0] = 0x2345600000000000
ERROR: Long long int result does not match expected result 0x6000000000000000
vec_arg1_di[1] = 0x23456789abcdef11
vec_arg2_di[1] = 20 (0x14)
vec_arg3_di[1] = 4 (0x4)
vec_result_di[1] = 0x3456780000000000
ERROR: Long long int result does not match expected result 0x7800000000000000

If we look at the ve_result_int[0] = 0x23450000, the input vec_arg1_int[0] =
0x12345678 was shifted by 0x4 (value in arg3 not arg2) and then ANDed with a
mask starting at bit 0 (counting bits from left to right) thru bit 16, all
other bits were set to zero.  The expected result is also given above.

Attached is the test program which was compiled with the following command:

gcc -g -mcpu=power9 check-builtin-vec_rlnm-runnable.c -o
check-builtin-vec_rlnm-runnable

Reply via email to