Skip to content

Commit 1cd73d9

Browse files
[SYCL] Switch to use plain array in sycl::vec in more cases (#17656)
The problem with using `std::array` in `sycl::vec` is that we cannot compile it in some environments (namely, Windows) because the former may use something that is illegal in SYCL device code. #17025 fixed that, but only did so under preview breaking changes mode, which does not satisfy some of our customers immediately. This PR introduces two main changes: - it allows to opt-in for new behavior through passing `-D__SYCL_USE_NEW_VEC_IMPL=1` macro without using `-fpreview-breaking-changes` flag. That allows for a more gradual opt-in from customers who are interested in this fix - it switches the imlpementation to use the new approach with C-style arrays if their size and alignment is the same as for the corresponding `std::array` - in that case their memory layout is expected to be absolutely the same and therefore it should be safe to use the new approach without fear of some ABI incompatibilities. This allows for customers to benefit from the fix without specifying any extra macro (which should be the case for the most common platforms out there)
1 parent 4568422 commit 1cd73d9

File tree

9 files changed

+144
-76
lines changed

9 files changed

+144
-76
lines changed

sycl/include/sycl/detail/type_traits/vec_marray_traits.hpp

-8
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,6 @@
88

99
#pragma once
1010

11-
#ifndef __SYCL_USE_NEW_VEC_IMPL
12-
#if defined(__INTEL_PREVIEW_BREAKING_CHANGES)
13-
#define __SYCL_USE_NEW_VEC_IMPL 1
14-
#else
15-
#define __SYCL_USE_NEW_VEC_IMPL 0
16-
#endif
17-
#endif
18-
1911
#include <cstddef>
2012
#include <type_traits>
2113

sycl/include/sycl/detail/vector_convert.hpp

-2
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,7 @@
5757
#include <sycl/detail/generic_type_traits.hpp> // for is_sigeninteger, is_s...
5858
#include <sycl/exception.hpp> // for errc
5959

60-
#ifdef __INTEL_PREVIEW_BREAKING_CHANGES
6160
#include <sycl/detail/memcpy.hpp>
62-
#endif
6361
#include <sycl/ext/oneapi/bfloat16.hpp> // bfloat16
6462
#include <sycl/vector.hpp>
6563

sycl/include/sycl/vector.hpp

+38-8
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@
2222
#endif
2323
#endif // __clang__
2424

25+
// See vec::DataType definitions for more details
26+
#ifndef __SYCL_USE_PLAIN_ARRAY_AS_VEC_STORAGE
27+
#if defined(__INTEL_PREVIEW_BREAKING_CHANGES)
28+
#define __SYCL_USE_PLAIN_ARRAY_AS_VEC_STORAGE 1
29+
#else
30+
#define __SYCL_USE_PLAIN_ARRAY_AS_VEC_STORAGE 0
31+
#endif
32+
#endif
33+
2534
#if !defined(__HAS_EXT_VECTOR_TYPE__) && defined(__SYCL_DEVICE_ONLY__)
2635
#error "SYCL device compiler is built without ext_vector_type support"
2736
#endif
@@ -86,6 +95,9 @@ struct elem {
8695
};
8796

8897
namespace detail {
98+
// To be defined in tests, trick to access vec's private methods
99+
template <typename T1, int T2> class vec_base_test;
100+
89101
template <typename VecT, typename OperationLeftT, typename OperationRightT,
90102
template <typename> class OperationCurrentT, int... Indexes>
91103
class SwizzleOp;
@@ -144,16 +156,34 @@ template <typename DataT, int NumElements> class vec_base {
144156
static constexpr size_t AdjustedNum = (NumElements == 3) ? 4 : NumElements;
145157
// This represent type of underlying value. There should be only one field
146158
// in the class, so vec<float, 16> should be equal to float16 in memory.
147-
#if defined(__INTEL_PREVIEW_BREAKING_CHANGES) && \
148-
defined(__SYCL_USE_NEW_VEC_IMPL)
149-
using DataType = DataT[AdjustedNum];
159+
//
160+
// In intel/llvm#14130 we incorrectly used std::array as an underlying storage
161+
// for vec data. The problem with std::array is that it comes from the C++
162+
// STL headers which we do not control and they may use something that is
163+
// illegal in SYCL device code. One of specific examples is use of debug
164+
// assertions in MSVC's STL implementation.
165+
//
166+
// The better approach is to use plain C++ array, but the problem here is that
167+
// C++ specification does not provide any guarantees about the memory layout
168+
// of std::array and therefore directly switching to it would technically be
169+
// an ABI-break, even though the practical chances of encountering the issue
170+
// are low.
171+
//
172+
// To play it safe, we only switch to use plain array if both its size and
173+
// alignment match those of std::array, or unless the new behavior is forced
174+
// via __SYCL_USE_PLAIN_ARRAY_AS_VEC_STORAGE or preview breaking changes mode.
175+
using DataType = std::conditional_t<
176+
#if __SYCL_USE_PLAIN_ARRAY_AS_VEC_STORAGE
177+
true,
150178
#else
151-
using DataType = std::array<DataT, AdjustedNum>;
152-
// Assuming that std::array has the same size as the underlying array.
153-
// C++ standard does not guarantee that, but it is true for most popular
154-
// implementations.
155-
static_assert(sizeof(DataType) == sizeof(DataT[AdjustedNum]));
179+
sizeof(std::array<DataT, AdjustedNum>) == sizeof(DataT[AdjustedNum]) &&
180+
alignof(std::array<DataT, AdjustedNum>) ==
181+
alignof(DataT[AdjustedNum]),
156182
#endif
183+
DataT[AdjustedNum], std::array<DataT, AdjustedNum>>;
184+
185+
// To allow testing of private methods
186+
template <typename T1, int T2> friend class detail::vec_base_test;
157187

158188
protected:
159189
// fields

sycl/test/abi/layout_vec.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ SYCL_EXTERNAL void foo(sycl::vec<int, 4>) {}
1212

1313
// CHECK: 0 | class sycl::vec<int, 4>
1414
// ignore empty base classes
15-
// CHECK: 0 | struct std::array<int, 4> m_Data
16-
// CHECK-NEXT: 0 | typename {{.+}}::_Type _M_elems
15+
// CHECK: 0 | DataType m_Data
1716
// CHECK-NEXT: | [sizeof=16, dsize=16, align=16,
1817
// CHECK-NEXT: | nvsize=16, nvalign=16]
1918

@@ -23,7 +22,6 @@ SYCL_EXTERNAL void foo(sycl::vec<bool, 16>) {}
2322

2423
// CHECK: 0 | class sycl::vec<_Bool, 16>
2524
// ignore empty base classes
26-
// CHECK: 0 | struct std::array<_Bool, 16> m_Data
27-
// CHECK-NEXT: 0 | typename {{.+}}::_Type _M_elems
25+
// CHECK: 0 | DataType m_Data
2826
// CHECK-NEXT: | [sizeof=16, dsize=16, align=16,
2927
// CHECK-NEXT: | nvsize=16, nvalign=16]
+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// RUN: %clangxx -fsycl -Xclang -verify %s -fsyntax-only
2+
// RUN: %clangxx -fsycl -Xclang -verify %s -fsyntax-only -fpreview-breaking-changes
3+
// RUN: %clangxx -fsycl -Xclang -verify %s -fsyntax-only -D__SYCL_USE_PLAIN_ARRAY_AS_VEC_STORAGE=1
4+
// expected-no-diagnostics
5+
6+
#include <sycl/vector.hpp>
7+
8+
#include <type_traits>
9+
10+
namespace sycl {
11+
namespace detail {
12+
template <typename T, int N> class vec_base_test {
13+
public:
14+
static void do_check() {
15+
constexpr bool uses_std_array =
16+
std::is_same_v<typename sycl::vec<T, N>::DataType, std::array<T, N>>;
17+
constexpr bool uses_plain_array =
18+
std::is_same_v<typename sycl::vec<T, N>::DataType, T[N]>;
19+
20+
constexpr bool std_array_and_plain_array_have_the_same_layout =
21+
sizeof(std::array<T, N>) == sizeof(T[N]) &&
22+
alignof(std::array<T, N>) == alignof(T[N]);
23+
24+
#if defined(__INTEL_PREVIEW_BREAKING_CHANGES) || \
25+
__SYCL_USE_PLAIN_ARRAY_AS_VEC_STORAGE
26+
static_assert(uses_plain_array,
27+
"We must use plain array regardless of "
28+
"layout, because user is opted-in for a potential ABI-break");
29+
#else
30+
static_assert(std_array_and_plain_array_have_the_same_layout ==
31+
uses_plain_array,
32+
"If layouts are the same, we must use safer plain array "
33+
"instead of std::array, or vice versa");
34+
static_assert(
35+
!std_array_and_plain_array_have_the_same_layout == uses_std_array,
36+
"If layouts are not the same, we must use std::array to preserve ABI");
37+
#endif
38+
}
39+
};
40+
} // namespace detail
41+
} // namespace sycl
42+
43+
int main() { sycl::detail::vec_base_test<int, 4>::do_check(); }

sycl/test/check_device_code/vector/bf16_builtins.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ SYCL_EXTERNAL auto TestFMin(vec<bfloat16, 2> a, vec<bfloat16, 2> b) {
6969
}
7070

7171
// CHECK-LABEL: define dso_local spir_func void @_Z8TestFMaxN4sycl3_V13vecINS0_3ext6oneapi8bfloat16ELi3EEES5_(
72-
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias writable writeonly sret(%"class.sycl::_V1::vec.71") align 8 captures(none) initializes((0, 8)) [[AGG_RESULT:%.*]], ptr noundef readonly byval(%"class.sycl::_V1::vec.71") align 8 captures(none) [[A:%.*]], ptr noundef readonly byval(%"class.sycl::_V1::vec.71") align 8 captures(none) [[B:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META24:![0-9]+]] !sycl_fixed_targets [[META7]] {
72+
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias writable writeonly sret(%"class.sycl::_V1::vec.70") align 8 captures(none) initializes((0, 8)) [[AGG_RESULT:%.*]], ptr noundef readonly byval(%"class.sycl::_V1::vec.70") align 8 captures(none) [[A:%.*]], ptr noundef readonly byval(%"class.sycl::_V1::vec.70") align 8 captures(none) [[B:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META24:![0-9]+]] !sycl_fixed_targets [[META7]] {
7373
// CHECK-NEXT: entry:
7474
// CHECK-NEXT: [[VEC_ADDR_I_I_I_I12_I:%.*]] = alloca <3 x float>, align 16
7575
// CHECK-NEXT: [[DST_I_I_I_I13_I:%.*]] = alloca [4 x %"class.sycl::_V1::ext::oneapi::bfloat16"], align 2
@@ -123,7 +123,7 @@ SYCL_EXTERNAL auto TestFMax(vec<bfloat16, 3> a, vec<bfloat16, 3> b) {
123123
}
124124

125125
// CHECK-LABEL: define dso_local spir_func void @_Z9TestIsNanN4sycl3_V13vecINS0_3ext6oneapi8bfloat16ELi4EEE(
126-
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias writable writeonly sret(%"class.sycl::_V1::vec.149") align 8 captures(none) initializes((0, 8)) [[AGG_RESULT:%.*]], ptr noundef readonly byval(%"class.sycl::_V1::vec.188") align 8 captures(none) [[A:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META38:![0-9]+]] !sycl_fixed_targets [[META7]] {
126+
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias writable writeonly sret(%"class.sycl::_V1::vec.146") align 8 captures(none) initializes((0, 8)) [[AGG_RESULT:%.*]], ptr noundef readonly byval(%"class.sycl::_V1::vec.184") align 8 captures(none) [[A:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META38:![0-9]+]] !sycl_fixed_targets [[META7]] {
127127
// CHECK-NEXT: entry:
128128
// CHECK-NEXT: [[VEC_ADDR_I_I_I_I_I:%.*]] = alloca <4 x i16>, align 8
129129
// CHECK-NEXT: [[DST_I_I_I_I_I:%.*]] = alloca [4 x float], align 4
@@ -149,7 +149,7 @@ SYCL_EXTERNAL auto TestIsNan(vec<bfloat16, 4> a) {
149149
}
150150

151151
// CHECK-LABEL: define dso_local spir_func void @_Z8TestFabsN4sycl3_V13vecINS0_3ext6oneapi8bfloat16ELi8EEE(
152-
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias writable writeonly sret(%"class.sycl::_V1::vec.342") align 16 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr noundef readonly byval(%"class.sycl::_V1::vec.342") align 16 captures(none) [[A:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META48:![0-9]+]] !sycl_fixed_targets [[META7]] {
152+
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias writable writeonly sret(%"class.sycl::_V1::vec.336") align 16 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr noundef readonly byval(%"class.sycl::_V1::vec.336") align 16 captures(none) [[A:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META48:![0-9]+]] !sycl_fixed_targets [[META7]] {
153153
// CHECK-NEXT: entry:
154154
// CHECK-NEXT: [[VEC_ADDR_I_I_I_I2_I:%.*]] = alloca <8 x float>, align 32
155155
// CHECK-NEXT: [[DST_I_I_I_I3_I:%.*]] = alloca [8 x %"class.sycl::_V1::ext::oneapi::bfloat16"], align 2
@@ -185,7 +185,7 @@ SYCL_EXTERNAL auto TestFabs(vec<bfloat16, 8> a) {
185185
}
186186

187187
// CHECK-LABEL: define dso_local spir_func void @_Z8TestCeilN4sycl3_V13vecINS0_3ext6oneapi8bfloat16ELi8EEE(
188-
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias writable writeonly sret(%"class.sycl::_V1::vec.342") align 16 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr noundef readonly byval(%"class.sycl::_V1::vec.342") align 16 captures(none) [[A:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META59:![0-9]+]] !sycl_fixed_targets [[META7]] {
188+
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias writable writeonly sret(%"class.sycl::_V1::vec.336") align 16 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr noundef readonly byval(%"class.sycl::_V1::vec.336") align 16 captures(none) [[A:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META59:![0-9]+]] !sycl_fixed_targets [[META7]] {
189189
// CHECK-NEXT: entry:
190190
// CHECK-NEXT: [[VEC_ADDR_I_I_I_I2_I:%.*]] = alloca <8 x float>, align 32
191191
// CHECK-NEXT: [[DST_I_I_I_I3_I:%.*]] = alloca [8 x %"class.sycl::_V1::ext::oneapi::bfloat16"], align 2
@@ -221,7 +221,7 @@ SYCL_EXTERNAL auto TestCeil(vec<bfloat16, 8> a) {
221221
}
222222

223223
// CHECK-LABEL: define dso_local spir_func void @_Z7TestFMAN4sycl3_V13vecINS0_3ext6oneapi8bfloat16ELi16EEES5_S5_(
224-
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias writable writeonly sret(%"class.sycl::_V1::vec.420") align 32 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly byval(%"class.sycl::_V1::vec.420") align 32 captures(none) [[A:%.*]], ptr noundef readonly byval(%"class.sycl::_V1::vec.420") align 32 captures(none) [[B:%.*]], ptr noundef readonly byval(%"class.sycl::_V1::vec.420") align 32 captures(none) [[C:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META70:![0-9]+]] !sycl_fixed_targets [[META7]] {
224+
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias writable writeonly sret(%"class.sycl::_V1::vec.412") align 32 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly byval(%"class.sycl::_V1::vec.412") align 32 captures(none) [[A:%.*]], ptr noundef readonly byval(%"class.sycl::_V1::vec.412") align 32 captures(none) [[B:%.*]], ptr noundef readonly byval(%"class.sycl::_V1::vec.412") align 32 captures(none) [[C:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META70:![0-9]+]] !sycl_fixed_targets [[META7]] {
225225
// CHECK-NEXT: entry:
226226
// CHECK-NEXT: [[VEC_ADDR_I_I_I_I14_I:%.*]] = alloca <16 x float>, align 64
227227
// CHECK-NEXT: [[DST_I_I_I_I15_I:%.*]] = alloca [16 x %"class.sycl::_V1::ext::oneapi::bfloat16"], align 2

sycl/test/check_device_code/vector/convert_bfloat.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ SYCL_EXTERNAL auto TestBFtoFDeviceRZ(vec<bfloat16, 3> &inp) {
6363
}
6464

6565
// CHECK-LABEL: define dso_local spir_func void @_Z19TestBFtointDeviceRZRN4sycl3_V13vecINS0_3ext6oneapi8bfloat16ELi3EEE(
66-
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias writable writeonly sret(%"class.sycl::_V1::vec.71") align 16 captures(none) [[AGG_RESULT:%.*]], ptr addrspace(4) noundef readonly align 8 captures(none) dereferenceable(8) [[INP:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META18:![0-9]+]] !sycl_fixed_targets [[META7]] {
66+
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias writable writeonly sret(%"class.sycl::_V1::vec.70") align 16 captures(none) [[AGG_RESULT:%.*]], ptr addrspace(4) noundef readonly align 8 captures(none) dereferenceable(8) [[INP:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META18:![0-9]+]] !sycl_fixed_targets [[META7]] {
6767
// CHECK-NEXT: entry:
6868
// CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META19:![0-9]+]])
6969
// CHECK-NEXT: [[LOADVECN_I_I:%.*]] = load <4 x i16>, ptr addrspace(4) [[INP]], align 8, !noalias [[META19]]
@@ -90,7 +90,7 @@ SYCL_EXTERNAL auto TestBFtointDeviceRZ(vec<bfloat16, 3> &inp) {
9090
}
9191

9292
// CHECK-LABEL: define dso_local spir_func void @_Z20TestBFtointDeviceRNERN4sycl3_V13vecINS0_3ext6oneapi8bfloat16ELi1EEE(
93-
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias writable writeonly sret(%"class.sycl::_V1::vec.110") align 4 captures(none) initializes((0, 4)) [[AGG_RESULT:%.*]], ptr addrspace(4) noundef readonly align 2 captures(none) dereferenceable(2) [[INP:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META24:![0-9]+]] !sycl_fixed_targets [[META7]] {
93+
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias writable writeonly sret(%"class.sycl::_V1::vec.108") align 4 captures(none) initializes((0, 4)) [[AGG_RESULT:%.*]], ptr addrspace(4) noundef readonly align 2 captures(none) dereferenceable(2) [[INP:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META24:![0-9]+]] !sycl_fixed_targets [[META7]] {
9494
// CHECK-NEXT: entry:
9595
// CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META25:![0-9]+]])
9696
// CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr addrspace(4) [[INP]], align 2, !tbaa [[TBAA11]], !noalias [[META25]]
@@ -182,7 +182,7 @@ SYCL_EXTERNAL auto TestInttoBFDeviceRZ(vec<int, 3> &inp) {
182182
}
183183

184184
// CHECK-LABEL: define dso_local spir_func void @_Z19TestLLtoBFDeviceRTPRN4sycl3_V13vecIxLi1EEE(
185-
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias writable writeonly sret(%"class.sycl::_V1::vec.149") align 2 captures(none) initializes((0, 2)) [[AGG_RESULT:%.*]], ptr addrspace(4) noundef readonly align 8 captures(none) dereferenceable(8) [[INP:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META42:![0-9]+]] !sycl_fixed_targets [[META7]] {
185+
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias writable writeonly sret(%"class.sycl::_V1::vec.146") align 2 captures(none) initializes((0, 2)) [[AGG_RESULT:%.*]], ptr addrspace(4) noundef readonly align 8 captures(none) dereferenceable(8) [[INP:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META42:![0-9]+]] !sycl_fixed_targets [[META7]] {
186186
// CHECK-NEXT: entry:
187187
// CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META43:![0-9]+]])
188188
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr addrspace(4) [[INP]], align 8, !tbaa [[TBAA46:![0-9]+]], !noalias [[META43]]
@@ -195,7 +195,7 @@ SYCL_EXTERNAL auto TestLLtoBFDeviceRTP(vec<long long, 1> &inp) {
195195
}
196196

197197
// CHECK-LABEL: define dso_local spir_func void @_Z22TestShorttoBFDeviceRTNRN4sycl3_V13vecIsLi2EEE(
198-
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias writable writeonly sret(%"class.sycl::_V1::vec.229") align 4 captures(none) [[AGG_RESULT:%.*]], ptr addrspace(4) noundef readonly align 4 captures(none) dereferenceable(4) [[INP:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META48:![0-9]+]] !sycl_fixed_targets [[META7]] {
198+
// CHECK-SAME: ptr addrspace(4) dead_on_unwind noalias writable writeonly sret(%"class.sycl::_V1::vec.224") align 4 captures(none) [[AGG_RESULT:%.*]], ptr addrspace(4) noundef readonly align 4 captures(none) dereferenceable(4) [[INP:%.*]]) local_unnamed_addr #[[ATTR0]] !srcloc [[META48:![0-9]+]] !sycl_fixed_targets [[META7]] {
199199
// CHECK-NEXT: entry:
200200
// CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META49:![0-9]+]])
201201
// CHECK-NEXT: [[TMP0:%.*]] = load <2 x i16>, ptr addrspace(4) [[INP]], align 4, !tbaa [[TBAA11]], !noalias [[META49]]

0 commit comments

Comments
 (0)