2

For writing SIMD code, I'd like to use templates to generate vector types with certain alignment. However, clang seems to ignore the alignment attribute when used with an alias template instead of a type alias.

Consider this code (godbolt):

#include <iostream>
#include <cstdint>

template <typename T=void>
using TemplatedT __attribute__((aligned(8))) = uint32_t;

using ManualT __attribute__((aligned(8))) = uint32_t;

int main() {
    std::cout << "alignof Template: " << alignof(TemplatedT<>) << std::endl;
    std::cout << "alignof Manual:   " << alignof(ManualT) << std::endl;
}

With gcc 12.2, both aliases have an alignment of 8, as I would expect. With clang 15 and trunk, the templated alias has an alignment of 4, ignoring the attribute.

Is this a bug? I looked through the open llvm issues but couldn't find a matching one.

Is there any workaround I can use?


Edit: As @HolyBlackCat proposed in the comments, extracting the templating to a wrapping struct seems to be a workaround:

template<typename ScalarT>
struct Vec {
    using T __attribute__((aligned(8))) = ScalarT;
};
// and then use Vec<uint32_t>::T

Edit2:

I've opened an issue with the LLVM project at https://github.com/llvm/llvm-project/issues/59788.

He3lixxx
  • 3,263
  • 1
  • 12
  • 31
  • 2
    Looks like a bug to me, please report. – HolyBlackCat Dec 23 '22 at 12:10
  • Try making a template struct with a non-template `using` inside. – HolyBlackCat Dec 23 '22 at 12:10
  • 1
    Interesting GCC 11.3 is 4 8 and GCC 12.1 is 8 8. – Richard Critten Dec 23 '22 at 12:12
  • Don't you actually want [std::alignas](https://en.cppreference.com/w/cpp/language/alignas)? – Jesper Juhl Dec 23 '22 at 12:13
  • 1
    @JesperJuhl `alignas` doesn't allow for some use edge-casy cases. In my particular case, I want to explicitly make the compiler generate unaligned load instructions, which GCC and clang do for types that have `__attribute__((aligned(1)))`, but `alignas(1)` would be ill-formed. – He3lixxx Dec 23 '22 at 12:21
  • Alignment attributes on a type alias are fundamentally broken in that there’s no new type to which they can apply. – Davis Herring Jan 02 '23 at 19:24
  • @DavisHerring can you explain in more detail why you think this is broken? Do you believe the current wording says this should not work or do we have a defect? – Shafik Yaghmour Mar 23 '23 at 03:40
  • *alignment-specifier*s can't be applied to a *typedef-name* ([dcl.align]/1), presumably because alignment must apply to a variable/member or type and a *typedef-name* **introduces** neither. What would it mean to have `std::vector`, for instance? Would it be a different type from `std::vector`? What would its `value_type` be? To make any of this work, you'd have to make these act like *cv-qualifier*s. – Davis Herring Mar 23 '23 at 04:14

0 Answers0