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