Issue 203311
Summary [Clang] Allow Power9 and Power10 vector intrinsics in altivec.h in functions that have the extension enabled through the target attribute
Labels clang
Assignees
Reporter johnplatts
    The Clang altivec.h header should be updated to have POWER9-specific intrinsics to always be defined (but annotated with the `__attribute__((target="power9-vector"))` attribute), POWER10-specific intrinsics to always be defined (but annotated with the `__attribute__((target="power10-vector"))` attribute), similar to the attributes applied to SIMD intrinsics for SSSE3 or later on x86 or Arm SIMD intrinsics requiring extensions beyond the base NEON ISA extension.

In other words, it should be possible (with the required changes to the altivec.h), for this C snippet to work on 64-bit PowerPC targets (even without the `-mcpu=power9` or `-mcpu=power10` compiler options):
```
#pragma push_macro("vector")
#pragma push_macro("pixel")
#pragma push_macro("bool")

#undef vector
#undef pixel
#undef bool

#include <altivec.h>

#pragma pop_macro("vector")
#pragma pop_macro("pixel")
#pragma pop_macro("bool")

#include <stdint.h>

__vector signed int AltivecPromoteEvenI16ToI32(__vector signed short v) {
  const __vector unsigned int k16 = vec_splats((unsigned int)16);

  __vector signed int i32_v = (__vector signed int)v;

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
  i32_v = (__vector signed int)vec_sl((__vector unsigned int)i32_v, k16);
#endif

  return vec_sra(i32_v, k16);
}

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#pragma clang attribute push(__attribute__((target("power9-vector"))), apply_to = function)
__vector signed int Power9PromoteEvenI16ToI32(__vector signed short v) {
  return vec_signexti(v);
}
#pragma clang attribute pop
#endif

#pragma clang attribute push(__attribute__((target("power8-vector"))), apply_to = function)
uint64_t Power8VecToByteMask(__vector __bool char v) {
  const __vector unsigned char kBitShuffle = {120, 112, 104, 96, 88, 80, 72, 64,
 56,  48,  40,  32, 24, 16, 8, 0};
  const __vector unsigned long long extracted_bits =
    (__vector unsigned long long)vec_vbpermq((__vector unsigned char)v, kBitShuffle);
 return (uint64_t)extracted_bits[__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__];
}
#pragma clang attribute pop

#pragma clang attribute push(__attribute__((target("power10-vector"))), apply_to = function)
uint64_t Power10VecToByteMask(__vector __bool char v) {
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  v = (__vector __bool char)vec_reve((__vector unsigned char)v);
#endif

  return (unsigned)vec_extractm((__vector unsigned char)v);
}
#pragma clang attribute pop
```

_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to