Skip to content

Commit 9e3bbbb

Browse files
authored
[X86][Clang] VectorExprEvaluator::VisitCallExpr / InterpretBuiltin - allow element extraction/insertion intrinsics to be used in constexpr #159753 (#161302)
FIXES: #159753 Enable constexpr evaluation for X86 vector element extract/insert builtins. and adds corresponding tests Index is masked with `(Idx & (NumElts - 1))`, matching existing CodeGen.
1 parent 6bdf2cb commit 9e3bbbb

File tree

8 files changed

+176
-14
lines changed

8 files changed

+176
-14
lines changed

clang/include/clang/Basic/BuiltinsX86.td

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def emms : X86Builtin<"void()"> {
5252
let Features = "mmx";
5353
}
5454

55-
let Attributes = [NoThrow, Const, RequiredVectorWidth<64>], Features = "sse" in {
55+
let Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<64>], Features = "sse" in {
5656
def vec_ext_v4hi : X86Builtin<"short(_Vector<4, short>, _Constant int)">;
5757
def vec_set_v4hi : X86Builtin<"_Vector<4, short>(_Vector<4, short>, short, _Constant int)">;
5858
}
@@ -92,13 +92,6 @@ let Attributes = [Const, NoThrow, RequiredVectorWidth<128>] in {
9292
def cmpsd : X86Builtin<"_Vector<2, double>(_Vector<2, double>, _Vector<2, double>, _Constant char)">;
9393
}
9494

95-
let Features = "sse2" in {
96-
def vec_ext_v2di : X86Builtin<"long long int(_Vector<2, long long int>, _Constant int)">;
97-
def vec_ext_v4si : X86Builtin<"int(_Vector<4, int>, _Constant int)">;
98-
def vec_ext_v4sf : X86Builtin<"float(_Vector<4, float>, _Constant int)">;
99-
def vec_ext_v8hi : X86Builtin<"short(_Vector<8, short>, _Constant int)">;
100-
def vec_set_v8hi : X86Builtin<"_Vector<8, short>(_Vector<8, short>, short, _Constant int)">;
101-
}
10295

10396
let Features = "sse2", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in {
10497
def pavgb128 : X86Builtin<"_Vector<16, unsigned char>(_Vector<16, unsigned char>, _Vector<16, unsigned char>)">;
@@ -108,6 +101,12 @@ let Attributes = [Const, NoThrow, RequiredVectorWidth<128>] in {
108101
def packsswb128 : X86Builtin<"_Vector<16, char>(_Vector<8, short>, _Vector<8, short>)">;
109102
def packssdw128 : X86Builtin<"_Vector<8, short>(_Vector<4, int>, _Vector<4, int>)">;
110103
def packuswb128 : X86Builtin<"_Vector<16, char>(_Vector<8, short>, _Vector<8, short>)">;
104+
105+
def vec_ext_v2di : X86Builtin<"long long int(_Vector<2, long long int>, _Constant int)">;
106+
def vec_ext_v4si : X86Builtin<"int(_Vector<4, int>, _Constant int)">;
107+
def vec_ext_v4sf : X86Builtin<"float(_Vector<4, float>, _Constant int)">;
108+
def vec_ext_v8hi : X86Builtin<"short(_Vector<8, short>, _Constant int)">;
109+
def vec_set_v8hi : X86Builtin<"_Vector<8, short>(_Vector<8, short>, short, _Constant int)">;
111110
}
112111

113112
let Features = "sse3" in {
@@ -323,9 +322,6 @@ let Features = "sse4.1", Attributes = [NoThrow, Const, RequiredVectorWidth<128>]
323322
def ptestnzc128 : X86Builtin<"int(_Vector<2, long long int>, _Vector<2, long long int>)">;
324323
def mpsadbw128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>, _Constant char)">;
325324
def phminposuw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>)">;
326-
def vec_ext_v16qi : X86Builtin<"char(_Vector<16, char>, _Constant int)">;
327-
def vec_set_v16qi : X86Builtin<"_Vector<16, char>(_Vector<16, char>, char, _Constant int)">;
328-
def vec_set_v4si : X86Builtin<"_Vector<4, int>(_Vector<4, int>, int, _Constant int)">;
329325
}
330326

331327
let Features = "sse4.1", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in {
@@ -338,6 +334,10 @@ let Features = "sse4.1", Attributes = [NoThrow, Const, Constexpr, RequiredVector
338334

339335
def pmuldq128 : X86Builtin<"_Vector<2, long long int>(_Vector<4, int>, _Vector<4, int>)">;
340336
def packusdw128 : X86Builtin<"_Vector<8, short>(_Vector<4, int>, _Vector<4, int>)">;
337+
338+
def vec_ext_v16qi : X86Builtin<"char(_Vector<16, char>, _Constant int)">;
339+
def vec_set_v16qi : X86Builtin<"_Vector<16, char>(_Vector<16, char>, char, _Constant int)">;
340+
def vec_set_v4si : X86Builtin<"_Vector<4, int>(_Vector<4, int>, int, _Constant int)">;
341341
}
342342

343343
let Features = "sse4.2", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
@@ -560,7 +560,7 @@ let Features = "avx", Attributes = [NoThrow, RequiredVectorWidth<128>] in {
560560
def maskstoreps : X86Builtin<"void(_Vector<4, float *>, _Vector<4, int>, _Vector<4, float>)">;
561561
}
562562

563-
let Features = "avx", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
563+
let Features = "avx", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in {
564564
def vec_ext_v32qi : X86Builtin<"char(_Vector<32, char>, _Constant int)">;
565565
def vec_ext_v16hi : X86Builtin<"short(_Vector<16, short>, _Constant int)">;
566566
def vec_ext_v8si : X86Builtin<"int(_Vector<8, int>, _Constant int)">;

clang/include/clang/Basic/BuiltinsX86_64.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,15 @@ let Features = "sse2", Attributes = [NoThrow] in {
5656
def movnti64 : X86Builtin<"void(long long int *, long long int)">;
5757
}
5858

59-
let Features = "sse4.1", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
59+
let Features = "sse4.1", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in {
6060
def vec_set_v2di : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>, long long int, _Constant int)">;
6161
}
6262

6363
let Features = "crc32", Attributes = [NoThrow, Const] in {
6464
def crc32di : X86Builtin<"unsigned long long int(unsigned long long int, unsigned long long int)">;
6565
}
6666

67-
let Features = "avx", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
67+
let Features = "avx", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in {
6868
def vec_ext_v4di : X86Builtin<"long long int(_Vector<4, long long int>, _Constant int)">;
6969
def vec_set_v4di : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, long long int, _Constant int)">;
7070
}

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2878,6 +2878,61 @@ static bool interp__builtin_x86_insert_subvector(InterpState &S, CodePtr OpPC,
28782878
return true;
28792879
}
28802880

2881+
static bool interp__builtin_vec_ext(InterpState &S, CodePtr OpPC,
2882+
const CallExpr *Call, unsigned ID) {
2883+
assert(Call->getNumArgs() == 2);
2884+
2885+
APSInt ImmAPS = popToAPSInt(S, Call->getArg(1));
2886+
const Pointer &Vec = S.Stk.pop<Pointer>();
2887+
if (!Vec.getFieldDesc()->isPrimitiveArray())
2888+
return false;
2889+
2890+
unsigned NumElems = Vec.getNumElems();
2891+
unsigned Index =
2892+
static_cast<unsigned>(ImmAPS.getZExtValue() & (NumElems - 1));
2893+
2894+
PrimType ElemPT = Vec.getFieldDesc()->getPrimType();
2895+
// FIXME(#161685): Replace float+int split with a numeric-only type switch
2896+
if (ElemPT == PT_Float) {
2897+
S.Stk.push<Floating>(Vec.elem<Floating>(Index));
2898+
return true;
2899+
}
2900+
INT_TYPE_SWITCH_NO_BOOL(ElemPT, {
2901+
APSInt V = Vec.elem<T>(Index).toAPSInt();
2902+
pushInteger(S, V, Call->getType());
2903+
});
2904+
2905+
return true;
2906+
}
2907+
2908+
static bool interp__builtin_vec_set(InterpState &S, CodePtr OpPC,
2909+
const CallExpr *Call, unsigned ID) {
2910+
assert(Call->getNumArgs() == 3);
2911+
2912+
APSInt ImmAPS = popToAPSInt(S, Call->getArg(2));
2913+
APSInt ValAPS = popToAPSInt(S, Call->getArg(1));
2914+
2915+
const Pointer &Base = S.Stk.pop<Pointer>();
2916+
if (!Base.getFieldDesc()->isPrimitiveArray())
2917+
return false;
2918+
2919+
const Pointer &Dst = S.Stk.peek<Pointer>();
2920+
2921+
unsigned NumElems = Base.getNumElems();
2922+
unsigned Index =
2923+
static_cast<unsigned>(ImmAPS.getZExtValue() & (NumElems - 1));
2924+
2925+
PrimType ElemPT = Base.getFieldDesc()->getPrimType();
2926+
INT_TYPE_SWITCH_NO_BOOL(ElemPT, {
2927+
for (unsigned I = 0; I != NumElems; ++I)
2928+
Dst.elem<T>(I) = Base.elem<T>(I);
2929+
Dst.elem<T>(Index) = static_cast<T>(ValAPS);
2930+
});
2931+
2932+
Dst.initializeAllElements();
2933+
return true;
2934+
}
2935+
28812936
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
28822937
uint32_t BuiltinID) {
28832938
if (!S.getASTContext().BuiltinInfo.isConstantEvaluated(BuiltinID))
@@ -3686,6 +3741,29 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
36863741
case X86::BI__builtin_ia32_insert128i256:
36873742
return interp__builtin_x86_insert_subvector(S, OpPC, Call, BuiltinID);
36883743

3744+
case X86::BI__builtin_ia32_vec_ext_v4hi:
3745+
case X86::BI__builtin_ia32_vec_ext_v16qi:
3746+
case X86::BI__builtin_ia32_vec_ext_v8hi:
3747+
case X86::BI__builtin_ia32_vec_ext_v4si:
3748+
case X86::BI__builtin_ia32_vec_ext_v2di:
3749+
case X86::BI__builtin_ia32_vec_ext_v32qi:
3750+
case X86::BI__builtin_ia32_vec_ext_v16hi:
3751+
case X86::BI__builtin_ia32_vec_ext_v8si:
3752+
case X86::BI__builtin_ia32_vec_ext_v4di:
3753+
case X86::BI__builtin_ia32_vec_ext_v4sf:
3754+
return interp__builtin_vec_ext(S, OpPC, Call, BuiltinID);
3755+
3756+
case X86::BI__builtin_ia32_vec_set_v4hi:
3757+
case X86::BI__builtin_ia32_vec_set_v16qi:
3758+
case X86::BI__builtin_ia32_vec_set_v8hi:
3759+
case X86::BI__builtin_ia32_vec_set_v4si:
3760+
case X86::BI__builtin_ia32_vec_set_v2di:
3761+
case X86::BI__builtin_ia32_vec_set_v32qi:
3762+
case X86::BI__builtin_ia32_vec_set_v16hi:
3763+
case X86::BI__builtin_ia32_vec_set_v8si:
3764+
case X86::BI__builtin_ia32_vec_set_v4di:
3765+
return interp__builtin_vec_set(S, OpPC, Call, BuiltinID);
3766+
36893767
default:
36903768
S.FFDiag(S.Current->getLocation(OpPC),
36913769
diag::note_invalid_subexpr_in_const_expr)

clang/lib/AST/ExprConstant.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12235,6 +12235,41 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
1223512235

1223612236
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
1223712237
}
12238+
12239+
case clang::X86::BI__builtin_ia32_vec_set_v4hi:
12240+
case clang::X86::BI__builtin_ia32_vec_set_v16qi:
12241+
case clang::X86::BI__builtin_ia32_vec_set_v8hi:
12242+
case clang::X86::BI__builtin_ia32_vec_set_v4si:
12243+
case clang::X86::BI__builtin_ia32_vec_set_v2di:
12244+
case clang::X86::BI__builtin_ia32_vec_set_v32qi:
12245+
case clang::X86::BI__builtin_ia32_vec_set_v16hi:
12246+
case clang::X86::BI__builtin_ia32_vec_set_v8si:
12247+
case clang::X86::BI__builtin_ia32_vec_set_v4di: {
12248+
APValue VecVal;
12249+
APSInt Scalar, IndexAPS;
12250+
if (!EvaluateVector(E->getArg(0), VecVal, Info) ||
12251+
!EvaluateInteger(E->getArg(1), Scalar, Info) ||
12252+
!EvaluateInteger(E->getArg(2), IndexAPS, Info))
12253+
return false;
12254+
12255+
QualType ElemTy = E->getType()->castAs<VectorType>()->getElementType();
12256+
unsigned ElemWidth = Info.Ctx.getIntWidth(ElemTy);
12257+
bool ElemUnsigned = ElemTy->isUnsignedIntegerOrEnumerationType();
12258+
Scalar.setIsUnsigned(ElemUnsigned);
12259+
APSInt ElemAPS = Scalar.extOrTrunc(ElemWidth);
12260+
APValue ElemAV(ElemAPS);
12261+
12262+
unsigned NumElems = VecVal.getVectorLength();
12263+
unsigned Index =
12264+
static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1));
12265+
12266+
SmallVector<APValue, 4> Elems;
12267+
Elems.reserve(NumElems);
12268+
for (unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum)
12269+
Elems.push_back(ElemNum == Index ? ElemAV : VecVal.getVectorElt(ElemNum));
12270+
12271+
return Success(APValue(Elems.data(), NumElems), E);
12272+
}
1223812273
}
1223912274
}
1224012275

@@ -14822,6 +14857,25 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1482214857
return HandleMaskBinOp(
1482314858
[](const APSInt &LHS, const APSInt &RHS) { return LHS + RHS; });
1482414859
}
14860+
14861+
case clang::X86::BI__builtin_ia32_vec_ext_v4hi:
14862+
case clang::X86::BI__builtin_ia32_vec_ext_v16qi:
14863+
case clang::X86::BI__builtin_ia32_vec_ext_v8hi:
14864+
case clang::X86::BI__builtin_ia32_vec_ext_v4si:
14865+
case clang::X86::BI__builtin_ia32_vec_ext_v2di:
14866+
case clang::X86::BI__builtin_ia32_vec_ext_v32qi:
14867+
case clang::X86::BI__builtin_ia32_vec_ext_v16hi:
14868+
case clang::X86::BI__builtin_ia32_vec_ext_v8si:
14869+
case clang::X86::BI__builtin_ia32_vec_ext_v4di: {
14870+
APValue Vec;
14871+
APSInt IdxAPS;
14872+
if (!EvaluateVector(E->getArg(0), Vec, Info) ||
14873+
!EvaluateInteger(E->getArg(1), IdxAPS, Info))
14874+
return false;
14875+
unsigned N = Vec.getVectorLength();
14876+
unsigned Idx = static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
14877+
return Success(Vec.getVectorElt(Idx).getInt(), E);
14878+
}
1482514879
}
1482614880
}
1482714881

@@ -16638,6 +16692,17 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {
1663816692
(void)Result.fusedMultiplyAdd(SourceY, SourceZ, RM);
1663916693
return true;
1664016694
}
16695+
16696+
case clang::X86::BI__builtin_ia32_vec_ext_v4sf: {
16697+
APValue Vec;
16698+
APSInt IdxAPS;
16699+
if (!EvaluateVector(E->getArg(0), Vec, Info) ||
16700+
!EvaluateInteger(E->getArg(1), IdxAPS, Info))
16701+
return false;
16702+
unsigned N = Vec.getVectorLength();
16703+
unsigned Idx = static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1));
16704+
return Success(Vec.getVectorElt(Idx), E);
16705+
}
1664116706
}
1664216707
}
1664316708

clang/test/CodeGen/X86/avx-builtins.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,26 +1039,30 @@ int test_mm256_extract_epi8(__m256i A) {
10391039
// CHECK: zext i8 %{{.*}} to i32
10401040
return _mm256_extract_epi8(A, 31);
10411041
}
1042+
TEST_CONSTEXPR(_mm256_extract_epi8(((__m256i)(__v32qs){0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}), 45) == 13);
10421043

10431044
int test_mm256_extract_epi16(__m256i A) {
10441045
// CHECK-LABEL: test_mm256_extract_epi16
10451046
// CHECK: extractelement <16 x i16> %{{.*}}, {{i32|i64}} 15
10461047
// CHECK: zext i16 %{{.*}} to i32
10471048
return _mm256_extract_epi16(A, 15);
10481049
}
1050+
TEST_CONSTEXPR(_mm256_extract_epi16(((__m256i)(__v16hi){0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}), 50) == 4);
10491051

10501052
int test_mm256_extract_epi32(__m256i A) {
10511053
// CHECK-LABEL: test_mm256_extract_epi32
10521054
// CHECK: extractelement <8 x i32> %{{.*}}, {{i32|i64}} 7
10531055
return _mm256_extract_epi32(A, 7);
10541056
}
1057+
TEST_CONSTEXPR(_mm256_extract_epi32(((__m256i)(__v8si){0, 5, 10, 15, 20, 25, 30, 35}), 18) == 10);
10551058

10561059
#if __x86_64__
10571060
long long test_mm256_extract_epi64(__m256i A) {
10581061
// X64-LABEL: test_mm256_extract_epi64
10591062
// X64: extractelement <4 x i64> %{{.*}}, {{i32|i64}} 3
10601063
return _mm256_extract_epi64(A, 3);
10611064
}
1065+
TEST_CONSTEXPR(_mm256_extract_epi64(((__m256i)(__v4di){5, 15, 25, 35}), 14) == 25);
10621066
#endif
10631067

10641068
__m128d test_mm256_extractf128_pd(__m256d A) {
@@ -1120,25 +1124,29 @@ __m256i test_mm256_insert_epi8(__m256i x, char b) {
11201124
// CHECK: insertelement <32 x i8> %{{.*}}, i8 %{{.*}}, {{i32|i64}} 14
11211125
return _mm256_insert_epi8(x, b, 14);
11221126
}
1127+
TEST_CONSTEXPR(match_v32qi(_mm256_insert_epi8(((__m256i)(__v32qs){0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}), 77, 47), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 77, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31));
11231128

11241129
__m256i test_mm256_insert_epi16(__m256i x, int b) {
11251130
// CHECK-LABEL: test_mm256_insert_epi16
11261131
// CHECK: insertelement <16 x i16> %{{.*}}, i16 %{{.*}}, {{i32|i64}} 4
11271132
return _mm256_insert_epi16(x, b, 4);
11281133
}
1134+
TEST_CONSTEXPR(match_v16hi(_mm256_insert_epi16(((__m256i)(__v16hi){0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}), 909, 62), 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 909, 30));
11291135

11301136
__m256i test_mm256_insert_epi32(__m256i x, int b) {
11311137
// CHECK-LABEL: test_mm256_insert_epi32
11321138
// CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, {{i32|i64}} 5
11331139
return _mm256_insert_epi32(x, b, 5);
11341140
}
1141+
TEST_CONSTEXPR(match_v8si(_mm256_insert_epi32(((__m256i)(__v8si){ 0, 5, 10, 15, 20, 25, 30, 35}), 4321, 18), 0, 5, 4321, 15, 20, 25, 30, 35));
11351142

11361143
#if __x86_64__
11371144
__m256i test_mm256_insert_epi64(__m256i x, long long b) {
11381145
// X64-LABEL: test_mm256_insert_epi64
11391146
// X64: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, {{i32|i64}} 2
11401147
return _mm256_insert_epi64(x, b, 2);
11411148
}
1149+
TEST_CONSTEXPR(match_v4di(_mm256_insert_epi64(((__m256i)(__v4di){5, 15, 25, 35}), -123456789LL, 10), 5, 15, -123456789LL, 35));
11421150
#endif
11431151

11441152
__m256d test_mm256_insertf128_pd(__m256d A, __m128d B) {

clang/test/CodeGen/X86/mmx-builtins.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ int test_mm_extract_pi16(__m64 a) {
292292
// CHECK: extractelement <4 x i16> {{%.*}}, i64 2
293293
return _mm_extract_pi16(a, 2);
294294
}
295+
TEST_CONSTEXPR(_mm_extract_pi16(((__m64)(__v4hi){10, 20, 30, 40}), 7) == 40);
295296

296297
__m64 test_m_from_int(int a) {
297298
// CHECK-LABEL: test_m_from_int
@@ -347,6 +348,7 @@ __m64 test_mm_insert_pi16(__m64 a, int d) {
347348
// CHECK: insertelement <4 x i16>
348349
return _mm_insert_pi16(a, d, 2);
349350
}
351+
TEST_CONSTEXPR(match_v4hi(_mm_insert_pi16(((__m64)(__v4hi){0, 1, 2, 3}), 77, 10), 0, 1, 77, 3));
350352

351353
__m64 test_mm_madd_pi16(__m64 a, __m64 b) {
352354
// CHECK-LABEL: test_mm_madd_pi16

clang/test/CodeGen/X86/sse2-builtins.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,12 +723,14 @@ int test_mm_extract_epi16(__m128i A) {
723723
// CHECK: zext i16 %{{.*}} to i32
724724
return _mm_extract_epi16(A, 1);
725725
}
726+
TEST_CONSTEXPR(_mm_extract_epi16(((__m128i)(__v8hi){0, 10, 20, 30, 40, 50, 60, 70}), 25) == 10);
726727

727728
__m128i test_mm_insert_epi16(__m128i A, int B) {
728729
// CHECK-LABEL: test_mm_insert_epi16
729730
// CHECK: insertelement <8 x i16> %{{.*}}, {{i32|i64}} 0
730731
return _mm_insert_epi16(A, B, 0);
731732
}
733+
TEST_CONSTEXPR(match_v8hi(_mm_insert_epi16(((__m128i)(__v8hi){0, 10, 20, 30, 40, 50, 60, 70}), 555, 17), 0, 555, 20, 30, 40, 50, 60, 70));
732734

733735
void test_mm_lfence(void) {
734736
// CHECK-LABEL: test_mm_lfence

0 commit comments

Comments
 (0)