xlC and Operation between types "vector unsigned int" and "int" is not allowed

294 views Asked by At

I'm trying to compile a source file on PPC64-LE. I'm using the xlC compiler and the compile is failing. GCC accepts the program, so I'm not really sure what the cause of the problems are.

Here's the command line:

$ xlc test-p8.c -qarch=pwr8 -qaltivec -o test-p8.exe

Here's the compile error:

"test-p8.c", line 113.52: 1506-324 (S) "int" cannot be converted to "vector unsigned int".
"test-p8.c", line 120.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
"test-p8.c", line 121.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
"test-p8.c", line 122.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
"test-p8.c", line 123.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
"test-p8.c", line 124.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
"test-p8.c", line 125.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
"test-p8.c", line 126.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
"test-p8.c", line 127.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
"test-p8.c", line 128.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.
"test-p8.c", line 130.15: 1506-068 (S) Operation between types "vector unsigned int" and "int" is not allowed.

Here's the relevant part of the source file. The source file is a reduced case for another problem, and it its available on GitHub.

$ cat -n test-p8.c
   ...
    12  typedef unsigned char uint8_t;
    13  typedef unsigned long long uint64_t;
    14  typedef vector unsigned char uint8x16_p8;
    15  typedef vector unsigned int uint64x2_p8;
   ...
    76  __attribute__((aligned(16)))
    77  uint8_t ks[176] = {
    78      0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x9,  0xcf, 0x4f, 0x3c,
   ...
    89  };
   ...
   113  uint64x2_p8 block = (uint64x2_p8)vec_vsx_ld(0U, (const uint8_t*)plain);
   ...
   118  block = vec_xor(block, (uint64x2_p8)vec_ld(0U, (const uint8_t*)ks));
   ...
   120  block = __builtin_crypto_vcipher(block, (uint64x2_p8)vec_ld( 16U, (const uint8_t*)ks));
   121  block = __builtin_crypto_vcipher(block, (uint64x2_p8)vec_ld( 32U, (const uint8_t*)ks));
   122  block = __builtin_crypto_vcipher(block, (uint64x2_p8)vec_ld( 48U, (const uint8_t*)ks));
   123  block = __builtin_crypto_vcipher(block, (uint64x2_p8)vec_ld( 64U, (const uint8_t*)ks));
   124  block = __builtin_crypto_vcipher(block, (uint64x2_p8)vec_ld( 80U, (const uint8_t*)ks));
   125  block = __builtin_crypto_vcipher(block, (uint64x2_p8)vec_ld( 96U, (const uint8_t*)ks));
   126  block = __builtin_crypto_vcipher(block, (uint64x2_p8)vec_ld(112U, (const uint8_t*)ks));
   127  block = __builtin_crypto_vcipher(block, (uint64x2_p8)vec_ld(128U, (const uint8_t*)ks));
   128  block = __builtin_crypto_vcipher(block, (uint64x2_p8)vec_ld(144U, (const uint8_t*)ks));
   129
   130  block = __builtin_crypto_vcipherlast(block, (uint64x2_p8)vec_ld(160U, (const uint8_t*)ks));

__builtin_crypto_vcipher is a GCC built-in, and IBM states xlC supports it.

Line 118 is like all the other lines show above, but it does not trigger a warning or error.

What is the problem, and how do I fix it?

3

There are 3 answers

0
jww On

Operation between types "vector unsigned int" and "int" is not allowed

I think I tracked this down. xlC does not know the function __builtin_crypto_vcipher, so the compiler assumes the function accepts int's as arguments or returns an int (I'm not sure which at the moment). I believe the equivalent GCC message is something about a missing declaration and assuming an int return.

Later, the unknown function takes a vector instead of an int:

__builtin_crypto_vcipher(block, ...)

or, it assigns an int to a vector:

block = __builtin_crypto_vcipher(...)

When I switched to xlC's builtin __vcipher the issue went away.

I don't know why the docs state xlC accepts GCC builtin's.

4
Nicole Trudeau On

The redbook you linked to is about "Performance Optimization and Tuning Techniques for IBM Power Systems Processors Including IBM POWER8" and is not compiler specific. It includes information about compiler support on POWER8, including the XLC and GCC compilers.

In section 7.3.1, page 149 of the redbook (page 171 if you're using the PDF page advancer), the following support is stated:

  • GCC: vector unsigned long long __builtin_crypto_vcipher (vector unsigned long long, vector unsigned long long)
  • XL C/C++: vector unsigned char __vcipher (vector unsigned char, vector unsigned char)

If you're compiling with GCC, you should use __builtin_crypto_vcipher, and if you're compiling with XLC, you should use __vcipher.

0
Rafik Zurob On

On PPC64-LE, a lot of effort went into unifying the interface for the vector builtins between GCC and XL. The two teams worked together on adding a consistent interface to the ABI document. You can find it here:

HTML, PDF

The new vcipher function that's part of the ABI is vec_cipher_be, which xlC supports.

Note that part of the reason for the new function is that the types accepted by the some of the old GCC crypto functions would have endianess issues.