<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/129398>129398</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Clang's insistence on __attribute__((target(...))) makes it impossible to build SIMD abstractions
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          higher-performance
      </td>
    </tr>
</table>

<pre>
    Compiling the code
```
#include <immintrin.h>

template<class> struct Zero;

template<> struct Zero<__m256> {
        [[gnu::target("avx")]]
        [[gnu::always_inline]]
        inline __m256 operator()() const {
                return _mm256_setzero_ps();
        }
};

template<> struct Zero<__m256d> {
        [[gnu::target("avx2")]]
        [[gnu::always_inline]]
        inline __m256d operator()() const {
                return _mm256_setzero_pd();
        }
};

template<class T>
[[gnu::always_inline]]
static inline auto bar(T gen) {
        return gen();
}

[[gnu::target("avx")]]
void foo() {
        bar(Zero<__m256>());
}
```
fails with
```
<source>:29:2: error: AVX vector return of type '__m256' (vector of 8 'float' values) without 'avx' enabled changes the ABI
   29 |         bar(Zero<__m256>());
      | ^
<source>:24:9: error: always_inline function 'operator()' requires target feature 'avx', but would be inlined into function 'bar' that is compiled without support for 'avx'
   24 |         return gen();
      | ^
<source>:24:9: error: AVX vector return of type '__m256' (vector of 8 'float' values) without 'avx' enabled changes the ABI
```
but I don't see any reasonable annotation that could possibly be placed on `bar`, nor why this should be necessary at all.

Fundamentally, the `target` attribute is only required during codegen, for functions whose target cannot be inferred. But `bar` is `always_inline` with internal linkage, so unless its address is taken, it should not care what the target architecture is -- determining that is only concern of the first non-inline caller.

Moreover, I think the same could apply for _any_ function whose initial declaration is also a definition. When a function's body is always available, its `target` attribute could always be safely inferred as the union of the `target`s of all its callees, and thus making its specification mandatory only introduces friction.

I feel this is a severe design limitation -- every function, even a template, is being required to know the targets of its callees, but it has no reasonable way to tell what those might be. This makes it impossible to build abstractions over SIMD code without severe code duplication.

Could the insistence on `target` therefore be relaxed?
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzEVkGP4jgT_TXmUgKFBAg5cKDpaakPc_pG3672ggq7Qrzt2FnbgWF__aqcQNM9s6Np7UrbQg2yq-z3Xr2yjSHooyXaiOWDWD5OsI-N85tGHxvy04587XyLVtLk4NRls3Ntp422R4gNgXSKRLYVq2z8ZFuRF9pK0ysCUex022obvbazRhSfeDrbRmo7g5FEsZMGQxDFJwjR9zLCb-SdKB6-ifsmZLfft_lyxeOiHOKrRODhaHtRbEWxjeiPFEW-FnmOp68iz0VeieUjf74Xj-aMl7DX1mhL93HDCAw7guvIY3Q-LVwN_0E6G-IdkqzyFHtvYd9y0j5Q_JO823dhTCuukWXapHz8CGv1Adr5v8Rb_UPi6iPEky3gy-iYn4EbIkYtYYSMfXRwQIb6BY5kGekN4wgwDd9BGvB8s92PXXRyWkHt3KjGbY9h7_dWvSr3dsu73qlRmwBnHZv3TVXsguu9JF6l2PIK21wUWyDvnecf2___CieS0XkYCboa4qUjEHk5IshLEPl6jHI1rHmuNg4jT53Q9BSYBgNwfeTZRLkEsngwpEA2aI8UUu9vH55FtgWARHwH17-f4j6EcppYfvoOwYUottUbgm_qDnVvZdTOMsb3xizB0x-99owzVQ9qwth7eiUk8h0c-ghn1xsFBxqNo0Db6N4sntiUEBuMoAPIdPyRumkU-q5zPkLt_N3ygy6LN7p833cfF-K_qvS9H1m7Z1DOiryMEIgA7QU8YXApH9Baxy3p7CCdTEJ3LgR9MBdWvDMoSQGrvMpY5VXGVbHOw7m5QGx0gNBc62NJUgjoL4AR0JjZ0KxPvVXYko1ozIXTGa5YZWPXrjLAGL0-9JG4es6ay9UcClTv-R7jOywVZZeKeC1-gHPjAl0tJBOjwSo1eU9qBg-s3BU8ry9W2dvjaZUlidlW5C0aMNq-4JF4s-Cgt4ZCAB0DoFI-_WbTvgxwdLwqwFtL9ARnFpNJjrDQy0ZHksneOsB0Cooi-Vbb4Y4ebJuIS2cljXZpCGrtQwTr7HTsKYnGkB-V_ew8uRN5xvHM1bAvKStgS2M1sevMJWm2R3vZv7bNIJy2Omo0oEga9IMXdAA0wQGCojoFODuDXxqygLd8kZcB-LExhLOegCfUhp016BL-rsgjsiHpwHBrMpdbzQAHR_eW0YxC3C8VeBCNSXskQbhRdoBWQWz6AC2-sLA8HTqSutZyoNaiVXwKXQax-dXjVC8pQO114jUq-ww1kRkMzgQh0Ik8gSJ-iIHRrR47ZzoFnrrcKbPjERbrdluyHkyVUd2sHR28WHe-c0oi9o4Ud7GO0GAA6-6794wXXiKSMVfHcUVbfWy4BWbwhcG3-EJsXtDt2NjEWYdecwkOIXocO4mNBP97_vyYmu317ByIpzHVd2aUctRpl0rJDLQNOkSyksbj4rXysSFPtfPExfZk8CspUTxN1KZQVVHhhDbzcpGtl-syqybNZl1ma5mXVaHmRU2o6rpcZoeqKMtVOV9kcqI3eZYvsyKbz6vlfFHNVrik9RLzfIWLqp7XYpFRi9rMjDm1M-ePEx1CT5t5XhXVemLwQCakx3SeS4P2yE-G5ePEbzhheuiPQSwyo0MMr0tEHQ1tdkN4Gd4x3u9vBt_v0-Wxvj1LZrPZeK_m1Y8rkvS_L8uk92bTxNgFfurkTyJ_OurY9IeZdK3Inxjd-DXtvPudZBT5U2IbRP40Ej5t8r8CAAD__9Tj57Q">