[clang] [llvm] [Clang] VectorExprEvaluator::VisitCallExpr / InterpretBuiltin - allow AVX/AVX512 subvector extraction intrinsics to be used in constexpr #157712 (PR #158853)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 8 10:13:44 PDT 2025
https://github.com/SeongjaeP updated https://github.com/llvm/llvm-project/pull/158853
>From fbe57aa1be29cc3172c70f2fccd1ad405c37feb1 Mon Sep 17 00:00:00 2001
From: seongjaep <psjj960507 at gmail.com>
Date: Fri, 12 Sep 2025 14:18:41 +0900
Subject: [PATCH 01/21] [WIP][Clang][ConstExpr] Add initial support for AVX
256->128 extract builtins
---
clang/lib/AST/ExprConstant.cpp | 31 +++++++++++++++++++
.../test/SemaCXX/constexpr-avx-intrinsics.cpp | 25 +++++++++++++++
2 files changed, 56 insertions(+)
create mode 100644 clang/test/SemaCXX/constexpr-avx-intrinsics.cpp
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index b706b14945b6d..92088fe428eef 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -11926,6 +11926,37 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
}
+
+ case X86::BI__builtin_ia32_vextracti128_si256:
+ case X86::BI__builtin_ia32_vextractf128_pd:
+ case X86::BI__builtin_ia32_vextractf128_ps:
+ case X86::BI__builtin_ia32_vextractf128_si256: {
+ APValue SourceHi, SourceLo, SourceAmt;
+ if (!EvaluateAsRValue(Info, E->getArg(0), SourceHi) ||
+ !EvaluateAsRValue(Info, E->getArg(1), SourceLo) ||
+ !EvaluateAsRValue(Info, E->getArg(2), SourceAmt))
+ return false;
+
+ QualType DestEltTy = E->getType()->castAs<VectorType>()->getElementType();
+ unsigned SourceLen = SourceHi.getVectorLength();
+ SmallVector<APValue, 32> ResultElements;
+ ResultElements.reserve(SourceLen);
+
+ APInt Amt = SourceAmt.getInt();
+ for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
+ APInt Hi = SourceHi.getVectorElt(EltNum).getInt();
+ APInt Lo = SourceLo.getVectorElt(EltNum).getInt();
+ APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
+ ResultElements.push_back(
+ APValue(APSInt(R, DestEltTy->isUnsignedIntegerOrEnumerationType())));
+ }
+
+ return Success(APValue(ResultElements.data(), ResultElements.size()), E);
+ }
+
+
+
+
case X86::BI__builtin_ia32_vpshldd128:
case X86::BI__builtin_ia32_vpshldd256:
case X86::BI__builtin_ia32_vpshldd512:
diff --git a/clang/test/SemaCXX/constexpr-avx-intrinsics.cpp b/clang/test/SemaCXX/constexpr-avx-intrinsics.cpp
new file mode 100644
index 0000000000000..30e1340601255
--- /dev/null
+++ b/clang/test/SemaCXX/constexpr-avx-intrinsics.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// expected-no-diagnostics
+
+#include <immintrin.h> // AVX/AVX512 헤더
+
+// // 테스트하려는 AVX/AVX512 내장 함수를 사용하는 constexpr 함수
+// constexpr int test_avx_subvector_extraction() {
+// __m256i a = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0);
+
+// // 이슈의 핵심: 이 내장 함수 호출이 constexpr 문맥에서 가능해야 함
+// __m128i sub = _mm256_extracti128_si256(a, 0);
+
+// return _mm_cvtsi128_si32(sub); // 결과를 int로 변환하여 리턴
+// }
+
+// // 이 상수는 컴파일 시간에 평가되어야 함
+// constexpr int result = test_avx_subvector_extraction();
+
+// static_assert(result == 0, "Incorrect result");
+
+#include <immintrin.h>
+
+constexpr __m128 test(__m256 a) {
+ return _mm256_extractf128_ps(a, 1);
+}
\ No newline at end of file
>From 20da92729da6f1079056cdd743a8c0160de15401 Mon Sep 17 00:00:00 2001
From: SeongjaeP <psjj960507 at gmail.com>
Date: Fri, 12 Sep 2025 21:00:28 +0900
Subject: [PATCH 02/21] [clang] Support constexpr evaluation for AVX/AVX2
extract intrinsics
Implements constexpr evaluation for:
- _mm256_extracti128_si256 (AVX2, VEXTRACTI128)
- _mm256_extractf128_ps
- _mm256_extractf128_pd
- _mm256_extractf128_si256
These now work correctly in constant expressions by extracting
the appropriate 128-bit lane from a 256-bit vector.
---
clang/lib/AST/ExprConstant.cpp | 43 +++++++++++++++-------------------
1 file changed, 19 insertions(+), 24 deletions(-)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 92088fe428eef..a1b33549c2168 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -11927,35 +11927,30 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
}
- case X86::BI__builtin_ia32_vextracti128_si256:
- case X86::BI__builtin_ia32_vextractf128_pd:
- case X86::BI__builtin_ia32_vextractf128_ps:
+ case X86::BI__builtin_ia32_extract128i256:
+ case X86::BI__builtin_ia32_vextractf128_pd256:
+ case X86::BI__builtin_ia32_vextractf128_ps256:
case X86::BI__builtin_ia32_vextractf128_si256: {
- APValue SourceHi, SourceLo, SourceAmt;
- if (!EvaluateAsRValue(Info, E->getArg(0), SourceHi) ||
- !EvaluateAsRValue(Info, E->getArg(1), SourceLo) ||
- !EvaluateAsRValue(Info, E->getArg(2), SourceAmt))
+ APValue SourceVec, SourceImm;
+ if (!EvaluateAsRValue(Info, E->getArg(0), SourceVec) ||
+ !EvaluateAsRValue(Info, E->getArg(1), SourceImm))
return false;
- QualType DestEltTy = E->getType()->castAs<VectorType>()->getElementType();
- unsigned SourceLen = SourceHi.getVectorLength();
- SmallVector<APValue, 32> ResultElements;
- ResultElements.reserve(SourceLen);
-
- APInt Amt = SourceAmt.getInt();
- for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
- APInt Hi = SourceHi.getVectorElt(EltNum).getInt();
- APInt Lo = SourceLo.getVectorElt(EltNum).getInt();
- APInt R = llvm::APIntOps::fshl(Hi, Lo, Amt);
- ResultElements.push_back(
- APValue(APSInt(R, DestEltTy->isUnsignedIntegerOrEnumerationType())));
- }
+ unsigned idx = SourceImm.getInt().getZExtValue() & 1;
+ const auto *RetVT = E->getType()->castAs<VectorType>();
+ unsigned RetLen = RetVT->getNumElements();
+ unsigned SrcLen = SourceVec.getVectorLength();
+ if (SrcLen != RetLen * 2)
+ return false;
+
+ SmallVector<APValue, 16> ResultElements;
+ ResultElements.reserve(RetLen);
- return Success(APValue(ResultElements.data(), ResultElements.size()), E);
+ for (unsigned i = 0; i < RetLen; i++)
+ ResultElements.push_back(SourceVec.getVectorElt(idx * RetLen + i));
+
+ return Success(APValue(ResultElements.data(), RetLen), E);
}
-
-
-
case X86::BI__builtin_ia32_vpshldd128:
case X86::BI__builtin_ia32_vpshldd256:
>From ef1877e71c54c1b2c2eed15695efdd8525598ce5 Mon Sep 17 00:00:00 2001
From: SeongjaeP <psjj960507 at gmail.com>
Date: Tue, 16 Sep 2025 18:14:57 +0900
Subject: [PATCH 03/21] [clang] Implement constant evaluation for AVX extract
intrinsics (part)
---
clang/lib/AST/ExprConstant.cpp | 111 ++++++++++++++++++++++++++++++++-
1 file changed, 109 insertions(+), 2 deletions(-)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index a1b33549c2168..b18fcb6505ce9 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -11927,7 +11927,114 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
}
- case X86::BI__builtin_ia32_extract128i256:
+ case X86::BI__builtin_ia32_extracti32x4_256_mask: // _mm256_extracti32x4_epi32
+ case X86::BI__builtin_ia32_extracti32x4_mask: // _mm512_extracti32x4_epi32
+ case X86::BI__builtin_ia32_extracti32x8_mask: // _mm512_extracti32x8_epi32
+ case X86::BI__builtin_ia32_extracti64x2_256_mask: // _mm256_extracti64x2_epi64
+ case X86::BI__builtin_ia32_extracti64x2_512_mask: // _mm512_extracti64x2_epi64
+ case X86::BI__builtin_ia32_extracti64x4_mask: { // _mm512_extracti64x4_epi64
+ APValue SourceVec, SourceImm, SourceMerge, SourceKmask;
+ if (!EvaluateAsRValue(Info, E->getArg(0), SourceVec) ||
+ !EvaluateAsRValue(Info, E->getArg(1), SourceImm) ||
+ !EvaluateAsRValue(Info, E->getArg(2), SourceMerge) ||
+ !EvaluateAsRValue(Info, E->getArg(3), SourceKmask))
+ return false;
+
+ const auto *RetVT = E->getType()->castAs<VectorType>();
+ QualType EltTy = RetVT->getElementType();
+ unsigned RetLen = RetVT->getNumElements();
+
+ if (!SourceVec.isVector())
+ return false;
+ unsigned SrcLen = SourceVec.getVectorLength();
+ if (SrcLen % RetLen != 0)
+ return false;
+
+ unsigned NumLanes = SrcLen / RetLen;
+ unsigned idx = SourceImm.getInt().getZExtValue() & (NumLanes - 1);
+
+ // Step 2) Apply kmask (covers plain/mask/maskz):
+ // - plain : headers pass kmask=all-ones; merge is undef → always take Extracted.
+ // - mask : merge=dst; take? Extracted[i] : dst[i]
+ // - maskz : merge=zero; take? Extracted[i] : 0
+ uint64_t KmaskBits = SourceKmask.getInt().getZExtValue();
+
+ auto makeZeroInt = [&]() -> APValue {
+ bool Uns = EltTy->isUnsignedIntegerOrEnumerationType();
+ unsigned BW = Info.Ctx.getIntWidth(EltTy);
+ return APValue(APSInt(APInt(BW, 0), Uns));
+ };
+
+ SmallVector<APValue, 32> ResultElements;
+ ResultElements.reserve(RetLen);
+ for (unsigned i = 0; i < RetLen; i++) {
+ bool Take = (KmaskBits >> i) & 1;
+ if (Take) {
+ ResultElements.push_back(SourceVec.getVectorElt(idx * RetLen + i));
+ } else {
+ // For plain (all-ones) this path is never taken.
+ // For mask : merge is the original dst element.
+ // For maskz : headers pass zero vector as merge.
+ const APValue &MergeElt =
+ SourceMerge.isVector() ? SourceMerge.getVectorElt(i) : makeZeroInt();
+ ResultElements.push_back(MergeElt);
+ }
+ }
+ return Success(APValue(ResultElements.data(), RetLen), E);
+ }
+
+ case X86::BI__builtin_ia32_extractf32x4_256_mask: // _mm256_extractf32x4_ps _mm256_mask_extractf32x4_ps _mm256_maskz_extractf32x4_ps
+ case X86::BI__builtin_ia32_extractf32x4_mask: // _mm512_extractf32x4_ps _mm512_mask_extractf32x4_ps _mm512_maskz_extractf32x4_ps
+ case X86::BI__builtin_ia32_extractf32x8_mask: // _mm512_extractf32x8_ps _mm512_mask_extractf32x8_ps _mm512_maskz_extractf32x8_ps
+
+ case X86::BI__builtin_ia32_extractf64x2_256_mask: // _mm256_extractf64x2_pd _mm256_mask_extractf64x2_pd _mm256_maskz_extractf64x2_pd
+ case X86::BI__builtin_ia32_extractf64x2_512_mask: // _mm512_extractf64x2_pd _mm512_mask_extractf64x2_pd _mm512_maskz_extractf64x2_pd
+ case X86::BI__builtin_ia32_extractf64x4_mask: { // _mm512_extractf64x4_pd _mm512_mask_extractf64x4_pd _mm512_maskz_extractf64x4_pd
+ APValue SourceVec, SourceImm, SourceMerge, SourceKmask;
+ if (!EvaluateAsRValue(Info, E->getArg(0), SourceVec) ||
+ !EvaluateAsRValue(Info, E->getArg(1), SourceImm) ||
+ !EvaluateAsRValue(Info, E->getArg(2), SourceMerge) ||
+ !EvaluateAsRValue(Info, E->getArg(3), SourceKmask))
+ return false;
+
+ const auto *RetVT = E->getType()->castAs<VectorType>();
+ QualType EltTy = RetVT->getElementType();
+ unsigned RetLen = RetVT->getNumElements();
+
+ if (!SourceVec.isVector())
+ return false;
+ unsigned SrcLen = SourceVec.getVectorLength();
+ if (SrcLen % RetLen != 0)
+ return false;
+
+ unsigned NumLanes = SrcLen / RetLen;
+ unsigned idx = SourceImm.getInt().getZExtValue() & (NumLanes - 1);
+
+ uint64_t KmaskBits = SourceKmask.getInt().getZExtValue();
+
+ auto makeZeroFP = [&]() -> APValue {
+ const llvm::fltSemantics &Sem =
+ Info.Ctx.getFloatTypeSemantics(EltTy);
+ return APValue(llvm::APFloat::getZero(Sem));
+ };
+
+ SmallVector<APValue, 32> ResultElements;
+ ResultElements.reserve(RetLen);
+ for (unsigned i = 0; i < RetLen; i++) {
+ bool Take = (KmaskBits >> i) & 1;
+ if (Take) {
+ ResultElements.push_back(SourceVec.getVectorElt(idx * RetLen + i));
+ } else {
+ const APValue &MergeElt =
+ SourceMerge.isVector() ? SourceMerge.getVectorElt(i) : makeZeroInt();
+ ResultElements.push_back(MergeElt);
+ }
+ }
+ return Success(APValue(ResultElements.data(), RetLen), E);
+ }
+
+ // vector extract
+ case X86::BI__builtin_ia32_extract128i256: // avx2
case X86::BI__builtin_ia32_vextractf128_pd256:
case X86::BI__builtin_ia32_vextractf128_ps256:
case X86::BI__builtin_ia32_vextractf128_si256: {
@@ -11943,7 +12050,7 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
if (SrcLen != RetLen * 2)
return false;
- SmallVector<APValue, 16> ResultElements;
+ SmallVector<APValue, 32> ResultElements;
ResultElements.reserve(RetLen);
for (unsigned i = 0; i < RetLen; i++)
>From 20b912b8cfb1ac1299a4668b327e67b6ff1d5de3 Mon Sep 17 00:00:00 2001
From: Yuriy Chernyshov <thegeorg at yandex-team.com>
Date: Mon, 22 Sep 2025 15:58:27 +0300
Subject: [PATCH 04/21] Add missing #include <cstdlib> (#157840)
std::realloc is declared there
>From ec1ecba3e6dc983af7bcee8a444392d765b5f17d Mon Sep 17 00:00:00 2001
From: SeongjaeP <psjj960507 at gmail.com>
Date: Tue, 23 Sep 2025 15:26:23 +0900
Subject: [PATCH 05/21] WIP: in-progress changes
---
clang/lib/AST/ByteCode/InterpBuiltin.cpp | 5 ++
clang/lib/AST/ExprConstant.cpp | 61 ++++++++++--------
.../test/SemaCXX/constexpr-avx-intrinsics.cpp | 61 +++++++++++++-----
.../InstCombine/\bfold-nested-max.ll" | 12 ++++
test.o | Bin 0 -> 528 bytes
5 files changed, 96 insertions(+), 43 deletions(-)
create mode 100644 "llvm/test/Transforms/InstCombine/\bfold-nested-max.ll"
create mode 100644 test.o
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index a2e97fcafdfef..47461e2b90f00 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -736,6 +736,11 @@ static bool interp__builtin_expect(InterpState &S, CodePtr OpPC,
return true;
}
+// __builtin_extract
+static bool interp__builtin_x86_extract_vector(Inter)
+
+
+
/// rotateleft(value, amount)
static bool interp__builtin_rotate(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index b18fcb6505ce9..0869e09e50f00 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -11927,6 +11927,39 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
}
+ // vector extract
+ case X86::BI__builtin_ia32_extract128i256:
+ case X86::BI__builtin_ia32_vextractf128_pd256:
+ case X86::BI__builtin_ia32_vextractf128_ps256:
+ case X86::BI__builtin_ia32_vextractf128_si256: {
+ APValue SourceVec, SourceImm;
+ if (!EvaluateAsRValue(Info, E->getArg(0), SourceVec) ||
+ !EvaluateAsRValue(Info, E->getArg(1), SourceImm))
+ return false;
+
+ if (!SourceVec.isVector())
+ return false;
+
+ const auto *RetVT = E->getType()->castAs<VectorType>();
+ if (!RetVT) return false;
+
+ unsigned RetLen = RetVT->getNumElements();
+ unsigned SrcLen = SourceVec.getVectorLength();
+ if (SrcLen != RetLen * 2)
+ return false;
+
+ unsigned idx = SourceImm.getInt().getZExtValue() & 1;
+
+ SmallVector<APValue, 32> ResultElements;
+ ResultElements.reserve(RetLen);
+
+ for (unsigned i = 0; i < RetLen; i++)
+ ResultElements.push_back(SourceVec.getVectorElt(idx * RetLen + i));
+
+ return Success(APValue(ResultElements.data(), RetLen), E);
+ }
+
+ // masked extract (ex: mm512_mask_extract32x4_epi32 / 512 -> 128)
case X86::BI__builtin_ia32_extracti32x4_256_mask: // _mm256_extracti32x4_epi32
case X86::BI__builtin_ia32_extracti32x4_mask: // _mm512_extracti32x4_epi32
case X86::BI__builtin_ia32_extracti32x8_mask: // _mm512_extracti32x8_epi32
@@ -12026,39 +12059,13 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
ResultElements.push_back(SourceVec.getVectorElt(idx * RetLen + i));
} else {
const APValue &MergeElt =
- SourceMerge.isVector() ? SourceMerge.getVectorElt(i) : makeZeroInt();
+ SourceMerge.isVector() ? SourceMerge.getVectorElt(i) : makeZeroFP();
ResultElements.push_back(MergeElt);
}
}
return Success(APValue(ResultElements.data(), RetLen), E);
}
- // vector extract
- case X86::BI__builtin_ia32_extract128i256: // avx2
- case X86::BI__builtin_ia32_vextractf128_pd256:
- case X86::BI__builtin_ia32_vextractf128_ps256:
- case X86::BI__builtin_ia32_vextractf128_si256: {
- APValue SourceVec, SourceImm;
- if (!EvaluateAsRValue(Info, E->getArg(0), SourceVec) ||
- !EvaluateAsRValue(Info, E->getArg(1), SourceImm))
- return false;
-
- unsigned idx = SourceImm.getInt().getZExtValue() & 1;
- const auto *RetVT = E->getType()->castAs<VectorType>();
- unsigned RetLen = RetVT->getNumElements();
- unsigned SrcLen = SourceVec.getVectorLength();
- if (SrcLen != RetLen * 2)
- return false;
-
- SmallVector<APValue, 32> ResultElements;
- ResultElements.reserve(RetLen);
-
- for (unsigned i = 0; i < RetLen; i++)
- ResultElements.push_back(SourceVec.getVectorElt(idx * RetLen + i));
-
- return Success(APValue(ResultElements.data(), RetLen), E);
- }
-
case X86::BI__builtin_ia32_vpshldd128:
case X86::BI__builtin_ia32_vpshldd256:
case X86::BI__builtin_ia32_vpshldd512:
diff --git a/clang/test/SemaCXX/constexpr-avx-intrinsics.cpp b/clang/test/SemaCXX/constexpr-avx-intrinsics.cpp
index 30e1340601255..0f2554a2f5d18 100644
--- a/clang/test/SemaCXX/constexpr-avx-intrinsics.cpp
+++ b/clang/test/SemaCXX/constexpr-avx-intrinsics.cpp
@@ -1,25 +1,54 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 \
+// RUN: -target-feature +avx -target-feature +avx2 \
+// RUN: -fsyntax-only -verify %s
// expected-no-diagnostics
-#include <immintrin.h> // AVX/AVX512 헤더
+// 128/256bit vector type
-// // 테스트하려는 AVX/AVX512 내장 함수를 사용하는 constexpr 함수
-// constexpr int test_avx_subvector_extraction() {
-// __m256i a = _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0);
+using v2i64 = long long __attribute__((vector_size(16))); // 2 x i64 = 128b
+using v4i64 = long long __attribute__((vector_size(32))); // 4 x i64 = 256b
+using v4f32 = float __attribute__((vector_size(16))); // 4 x f32 = 128b
+using v8f32 = float __attribute__((vector_size(32))); // 8 x f32 = 256b
+using v2f64 = double __attribute__((vector_size(16))); // 2 x f64 = 128b
+using v4f64 = double __attribute__((vector_size(32))); // 4 x f64 = 256b
+using v4i32 = int __attribute__((vector_size(16))); // 4 x i32 = 128b
+using v8i32 = int __attribute__((vector_size(32))); // 8 x i32 = 256b
-// // 이슈의 핵심: 이 내장 함수 호출이 constexpr 문맥에서 가능해야 함
-// __m128i sub = _mm256_extracti128_si256(a, 0);
-// return _mm_cvtsi128_si32(sub); // 결과를 int로 변환하여 리턴
-// }
+// source vectors (constexpr)
+constexpr v4i64 SRC_I64_256 = {10, 20, 30, 40};
+constexpr v8f32 SRC_F32_256 = {0, 1, 2, 3, 4, 5, 6, 7};
+constexpr v4f64 SRC_F64_256 = {1.1, 2.2, 3.3, 4.4};
+constexpr v8i32 SRC_I32_256 = {10, 20, 30, 40, 50, 60, 70, 80};
-// // 이 상수는 컴파일 시간에 평가되어야 함
-// constexpr int result = test_avx_subvector_extraction();
+// 1) __builtin_ia32_extract128i256 : 256비트 i64 벡터 -> 하위/상위 128비트 추출
+constexpr v2i64 R_EXTRACT_I128_0 = __builtin_ia32_extract128i256(SRC_I64_256, 0);
+static_assert(R_EXTRACT_I128_0[0] == 10 && R_EXTRACT_I128_0[1] == 20);
-// static_assert(result == 0, "Incorrect result");
+constexpr v2i64 R_EXTRACT_I128_1 = __builtin_ia32_extract128i256(SRC_I64_256, 1);
+static_assert(R_EXTRACT_I128_1[0] == 30 && R_EXTRACT_I128_1[1] == 40);
-#include <immintrin.h>
+// // 2) __builtin_ia32_vextractf128_ps256 : 256비트 f32 -> 128비트 f32
+// constexpr v4f32 R_EXTRACT_F128_PS_0 = __builtin_ia32_vextractf128_ps256(SRC_F32_256, 0);
+// static_assert(R_EXTRACT_F128_PS_0[0] == 0 && R_EXTRACT_F128_PS_0[1] == 1 &&
+// R_EXTRACT_F128_PS_0[2] == 2 && R_EXTRACT_F128_PS_0[3] == 3);
-constexpr __m128 test(__m256 a) {
- return _mm256_extractf128_ps(a, 1);
-}
\ No newline at end of file
+// constexpr v4f32 R_EXTRACT_F128_PS_1 = __builtin_ia32_vextractf128_ps256(SRC_F32_256, 1);
+// static_assert(R_EXTRACT_F128_PS_1[0] == 4 && R_EXTRACT_F128_PS_1[1] == 5 &&
+// R_EXTRACT_F128_PS_1[2] == 6 && R_EXTRACT_F128_PS_1[3] == 7);
+
+// // 3) __builtin_ia32_vextractf128_pd256 : 256비트 f64 -> 128비트 f64
+// constexpr v2f64 R_EXTRACT_F128_PD_0 = __builtin_ia32_vextractf128_pd256(SRC_F64_256, 0);
+// static_assert(R_EXTRACT_F128_PD_0[0] == 1.1 && R_EXTRACT_F128_PD_0[1] == 2.2);
+
+// constexpr v2f64 R_EXTRACT_F128_PD_1 = __builtin_ia32_vextractf128_pd256(SRC_F64_256, 1);
+// static_assert(R_EXTRACT_F128_PD_1[0] == 3.3 && R_EXTRACT_F128_PD_1[1] == 4.4);
+
+// // 4) __builtin_ia32_vextractf128_si256 : 256비트 i32 -> 128비트 i32
+// constexpr v4i32 R_EXTRACT_F128_SI256_0 = __builtin_ia32_vextractf128_si256(SRC_I32_256, 0);
+// static_assert(R_EXTRACT_F128_SI256_0[0] == 10 && R_EXTRACT_F128_SI256_0[1] == 20 &&
+// R_EXTRACT_F128_SI256_0[2] == 30 && R_EXTRACT_F128_SI256_0[3] == 40);
+
+// constexpr v4i32 R_EXTRACT_F128_SI256_1 = __builtin_ia32_vextractf128_si256(SRC_I32_256, 1);
+// static_assert(R_EXTRACT_F128_SI256_1[0] == 50 && R_EXTRACT_F128_SI256_1[1] == 60 &&
+// R_EXTRACT_F128_SI256_1[2] == 70 && R_EXTRACT_F128_SI256_1[3] == 80);
\ No newline at end of file
diff --git "a/llvm/test/Transforms/InstCombine/\bfold-nested-max.ll" "b/llvm/test/Transforms/InstCombine/\bfold-nested-max.ll"
new file mode 100644
index 0000000000000..448365b64a169
--- /dev/null
+++ "b/llvm/test/Transforms/InstCombine/\bfold-nested-max.ll"
@@ -0,0 +1,12 @@
+; RUN: opt -passes=instcombine -S < %s | FileCheck %s
+
+define i64 @test1(i64 %x) {
+ %1 = call i64 @llvm.umax.i64(i64 %x, i64 4)
+ %2 = shl i64 %1, 1
+ %3 = call i64 @llvm.umax.i64(i64 %2, i64 16)
+ ret i64 %3
+}
+
+; CHECK-LABEL: @test1
+; CHECK: shl i64 %x, 1
+; CHECK: call i64 @llvm.umax.i64(i64 {{.*}}, i64 16)
\ No newline at end of file
diff --git a/test.o b/test.o
new file mode 100644
index 0000000000000000000000000000000000000000..7198521f709c0b5851464db5012b25e0642d6660
GIT binary patch
literal 528
zcmX^A>+L at t1_nk3AOI08K%4<$C;%}KNCNQ-Fbg|j0Tu25o4~*T<Ff<BL6`|DA0J<m
zT2TV!0IB%+5Z8zh1Rur{fighm!SsTKSQr{$YCv>+d~$wnL1J=Ad}&^JW?o8sypIdA
zyabe^0HqfI&0_|#4*+SXQ&EgJ0?L8(K;-xt7+8TA2tbNJ;wPZ`e*kF^pBsn+fEWZo
zYCssI7i0%H;BWQ*m4BHTCjR^XfBN6*gDVa&$6rG>2O2J*=)nL$d)WklqI at 6+Kmiw!
i<^wtk77idOek6Hd07e<7<>!|%<dozV7=lRypc()lI4qC=
literal 0
HcmV?d00001
>From 99475b848a7fa0f33bc5af5a97411ca682b505c0 Mon Sep 17 00:00:00 2001
From: SeongjaeP <psjj960507 at gmail.com>
Date: Wed, 24 Sep 2025 02:09:42 +0900
Subject: [PATCH 06/21] [clang][ByteCode] constexpr-enable X86 AVX/AVX512
subvector extract builtins in InterpBuiltin
- Route AVX/AVX2 vextractf128/ extract128i256 to 2-arg extract helper.
- Route all AVX-512(VL/DQ) extract builtins to unified 4-arg masked helper:
* extractf32x4_{256,_}
* extractf32x8_
* extractf64x2_{256,512}
* extractf64x4_
* extracti32x4_{256,_}
* extracti32x8_
* extracti64x2_{256,512}
* extracti64x4_
- Implement mask/merge/all-ones(mask=plain)/maskz semantics.
- Initialize all elements in the destination vector.
NOTE:
Tests are not included yet. This patch wires up InterpBuiltin support only.
A follow-up patch will add constexpr tests under clang/test/AST/Interp/.
---
clang/lib/AST/ByteCode/InterpBuiltin.cpp | 147 ++++++++++++++++++++++-
1 file changed, 143 insertions(+), 4 deletions(-)
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 47461e2b90f00..733ea2478fc98 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -736,10 +736,6 @@ static bool interp__builtin_expect(InterpState &S, CodePtr OpPC,
return true;
}
-// __builtin_extract
-static bool interp__builtin_x86_extract_vector(Inter)
-
-
/// rotateleft(value, amount)
static bool interp__builtin_rotate(InterpState &S, CodePtr OpPC,
@@ -2841,6 +2837,127 @@ static bool interp__builtin_elementwise_triop(
return true;
}
+//_builtin_extract
+static bool interp__builtin_x86_extract_vector(InterpState &S, CodePtr OpPC,
+ const CallExpr *Call,
+ unsigned ID) {
+ assert(Call->getNumArgs() == 2);
+
+ // srcimm
+ APSInt ImmAPS = popToAPSInt(S, Call->getArg(1));
+ uint64_t Index = ImmAPS.getZExtValue();
+
+ // srcvec
+ const Pointer &Src = S.Stk.pop<Pointer>();
+ if (!Src.getFieldDesc()->isPrimitiveArray())
+ return false;
+
+ // destination (return value)
+ const Pointer &Dst = S.Stk.peek<Pointer>();
+ if (!Dst.getFieldDesc()->isPrimitiveArray())
+ return false;
+
+ unsigned SrcElems = Src.getNumElems();
+ unsigned DstElems = Dst.getNumElems();
+
+ if (SrcElems == 0 || DstElems == 0 || (SrcElems % DstElems) != 0)
+ return false;
+
+ unsigned NumLanes = SrcElems / DstElems;
+ unsigned Lane = static_cast<unsigned>(Index % NumLanes);
+ unsigned ExtractPos = Lane * DstElems;
+
+ // element type
+ PrimType ElemPT = Src.getFieldDesc()->getPrimType();
+ if (ElemPT != Dst.getFieldDesc()->getPrimType())
+ return false;
+
+ TYPE_SWITCH(ElemPT, {
+ for (unsigned I = 0; I != DstElems; ++I) {
+ Dst.elem<T>(I) = Src.elem<T>(ExtractPos + I);
+ }
+ });
+
+ Dst.initializeAllElements();
+ return true;
+}
+
+// __builtin_extract_masked
+static bool interp__builtin_x86_extract_vector_masked(InterpState &S, CodePtr OpPC,
+ const CallExpr *Call,
+ unsigned ID) {
+ assert(Call->getNumArgs() == 4);
+
+ // kmask
+ APSInt KmaskAPS = popToAPSInt(S, Call->getArg(3));
+ uint64_t Kmask = KmaskAPS.getZExtValue();
+
+ // merge
+ const Pointer &Merge = S.Stk.pop<Pointer>();
+ bool HasMergeVec = Merge.isLive() && Merge.getFieldDesc() &&
+ Merge.getFieldDesc()->isPrimitiveArray();
+
+ // srcimm
+ APSInt ImmAPS = popToAPSInt(S, Call->getArg(1));
+ uint64_t Index = ImmAPS.getZExtValue();
+
+ // srcvec
+ const Pointer &Src = S.Stk.pop<Pointer>();
+ if (!Src.getFieldDesc()->isPrimitiveArray())
+ return false;
+
+ // dst (return)
+ const Pointer &Dst = S.Stk.peek<Pointer>();
+ if (!Dst.getFieldDesc()->isPrimitiveArray())
+ return false;
+
+ unsigned SrcElems = Src.getNumElems();
+ unsigned DstElems = Dst.getNumElems();
+ if (SrcElems == 0 || DstElems == 0 || (SrcElems % DstElems) != 0)
+ return false;
+
+ unsigned NumLanes = SrcElems / DstElems;
+ unsigned Lane = static_cast<unsigned>(Index % NumLanes);
+ unsigned ExtractPos = Lane * DstElems;
+
+ PrimType ElemPT = Src.getFieldDesc()->getPrimType();
+ if (ElemPT != Dst.getFieldDesc()->getPrimType())
+ return false;
+
+ // Merge vector type/len check(if)
+ if (HasMergeVec) {
+ if (Merge.getFieldDesc()->getPrimType() != ElemPT ||
+ Merge.getNumElems() != DstElems)
+ return false;
+ }
+
+ // generate 0 value
+ auto storeZeroAt = [&](unsigned I) {
+ TYPE_SWITCH(ElemPT, {
+ Dst.elem<T>(I) = T{};
+ });
+ };
+
+ TYPE_SWITCH(ElemPT, {
+ for (unsigned I = 0; I != DstElems; ++I) {
+ bool Take = ((Kmask >> I) & 1) != 0;
+ if (Take) {
+ Dst.elem<T>(I) = Src.elem<T>(ExtractPos + I);
+ } else {
+ if (HasMergeVec) {
+ Dst.elem<T>(I) = Merge.elem<T>(I);
+ } else {
+ storeZeroAt(I);
+ }
+ }
+ }
+ });
+
+ Dst.initializeAllElements();
+ return true;
+}
+
+
static bool interp__builtin_x86_insert_subvector(InterpState &S, CodePtr OpPC,
const CallExpr *Call,
unsigned ID) {
@@ -3360,6 +3477,28 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
});
+ case X86::BI__builtin_ia32_extract128i256: // _mm256_extracti128
+ case X86::BI__builtin_ia32_vextractf128_pd256: // _mm256_extractf128_ps
+ case X86::BI__builtin_ia32_vextractf128_ps256: // _mm256_extractf128_pd
+ case X86::BI__builtin_ia32_vextractf128_si256: // _mm256_extracti128_si256
+ return interp__builtin_x86_extract_vector(S, OpPC, Call, BuiltinID);
+
+ // AVX-512 / AVX-512VL / AVX-512DQ
+ case X86::BI__builtin_ia32_extractf32x4_256_mask:
+ case X86::BI__builtin_ia32_extractf32x4_mask:
+ case X86::BI__builtin_ia32_extractf32x8_mask:
+ case X86::BI__builtin_ia32_extractf64x2_256_mask:
+ case X86::BI__builtin_ia32_extractf64x2_512_mask:
+ case X86::BI__builtin_ia32_extractf64x4_mask:
+ case X86::BI__builtin_ia32_extracti32x4_256_mask:
+ case X86::BI__builtin_ia32_extracti32x4_mask:
+ case X86::BI__builtin_ia32_extracti32x8_mask:
+ case X86::BI__builtin_ia32_extracti64x2_256_mask:
+ case X86::BI__builtin_ia32_extracti64x2_512_mask:
+ case X86::BI__builtin_ia32_extracti64x4_mask:
+ return interp__builtin_x86_extract_vector_masked(S, OpPC, Call, BuiltinID);
+
+
case clang::X86::BI__builtin_ia32_pavgb128:
case clang::X86::BI__builtin_ia32_pavgw128:
case clang::X86::BI__builtin_ia32_pavgb256:
>From e60793985ab48f445297b509f76c565cdb57ebf7 Mon Sep 17 00:00:00 2001
From: SeongjaeP <psjj960507 at gmail.com>
Date: Wed, 24 Sep 2025 21:16:11 +0900
Subject: [PATCH 07/21] Remove commented code
---
clang/lib/AST/ExprConstant.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 0869e09e50f00..4ac56448af950 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -11928,7 +11928,7 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
}
// vector extract
- case X86::BI__builtin_ia32_extract128i256:
+ case X86::BI__builtin_ia32_extract128i256: // avx2
case X86::BI__builtin_ia32_vextractf128_pd256:
case X86::BI__builtin_ia32_vextractf128_ps256:
case X86::BI__builtin_ia32_vextractf128_si256: {
@@ -11959,12 +11959,11 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
return Success(APValue(ResultElements.data(), RetLen), E);
}
- // masked extract (ex: mm512_mask_extract32x4_epi32 / 512 -> 128)
case X86::BI__builtin_ia32_extracti32x4_256_mask: // _mm256_extracti32x4_epi32
case X86::BI__builtin_ia32_extracti32x4_mask: // _mm512_extracti32x4_epi32
case X86::BI__builtin_ia32_extracti32x8_mask: // _mm512_extracti32x8_epi32
case X86::BI__builtin_ia32_extracti64x2_256_mask: // _mm256_extracti64x2_epi64
- case X86::BI__builtin_ia32_extracti64x2_512_mask: // _mm512_extracti64x2_epi64
+ case X86::BI__builtin_ia32_extracti64x2_512_mask: // _mm512_extracti64x2_epi64
case X86::BI__builtin_ia32_extracti64x4_mask: { // _mm512_extracti64x4_epi64
APValue SourceVec, SourceImm, SourceMerge, SourceKmask;
if (!EvaluateAsRValue(Info, E->getArg(0), SourceVec) ||
>From 4d663c950931ffbf0bdc3a6c313404da0a4b6562 Mon Sep 17 00:00:00 2001
From: SeongjaeP <psjj960507 at gmail.com>
Date: Wed, 24 Sep 2025 21:20:45 +0900
Subject: [PATCH 08/21] Add constexpr tests for AVX/AVX2/AVX-512 extract
intrinsics
---
clang/test/CodeGen/X86/avx-builtins.c | 9 +++
clang/test/CodeGen/X86/avx2-builtins.c | 2 +
clang/test/CodeGen/X86/avx512dq-builtins.c | 68 ++++++++++++++++++++
clang/test/CodeGen/X86/avx512f-builtins.c | 67 +++++++++++++++++++
clang/test/CodeGen/X86/avx512vl-builtins.c | 30 +++++++++
clang/test/CodeGen/X86/avx512vldq-builtins.c | 26 ++++++++
6 files changed, 202 insertions(+)
diff --git a/clang/test/CodeGen/X86/avx-builtins.c b/clang/test/CodeGen/X86/avx-builtins.c
index 3018bb9719b89..758fb5ef8204d 100644
--- a/clang/test/CodeGen/X86/avx-builtins.c
+++ b/clang/test/CodeGen/X86/avx-builtins.c
@@ -1067,18 +1067,27 @@ __m128d test_mm256_extractf128_pd(__m256d A) {
return _mm256_extractf128_pd(A, 1);
}
+TEST_CONSTEXPR(match_m128d(_mm256_extractf128_pd(((__m256d){0.0, 1.0, 2.0, 3.0}), 1),
+ 2.0, 3.0));
+
__m128 test_mm256_extractf128_ps(__m256 A) {
// CHECK-LABEL: test_mm256_extractf128_ps
// CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
return _mm256_extractf128_ps(A, 1);
}
+TEST_CONSTEXPR(match_m128(_mm256_extractf128_ps(((__m256){0,1,2,3,4,5,6,7}), 1),
+ 4.0f, 5.0f, 6.0f, 7.0f));
+
__m128i test_mm256_extractf128_si256(__m256i A) {
// CHECK-LABEL: test_mm256_extractf128_si256
// CHECK: shufflevector <8 x i32> %{{.*}}, <8 x i32> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
return _mm256_extractf128_si256(A, 1);
}
+TEST_CONSTEXPR(match_m128i(_mm256_extractf128_si256(((__m256i){0,1,2,3,4,5,6,7}), 1),
+ 4, 5, 6, 7));
+
__m256d test_mm256_floor_pd(__m256d x) {
// CHECK-LABEL: test_mm256_floor_pd
// CHECK: call {{.*}}<4 x double> @llvm.x86.avx.round.pd.256(<4 x double> %{{.*}}, i32 1)
diff --git a/clang/test/CodeGen/X86/avx2-builtins.c b/clang/test/CodeGen/X86/avx2-builtins.c
index eff2797e87c75..a815f96ab9468 100644
--- a/clang/test/CodeGen/X86/avx2-builtins.c
+++ b/clang/test/CodeGen/X86/avx2-builtins.c
@@ -479,6 +479,8 @@ __m128i test2_mm256_extracti128_si256(__m256i a) {
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> poison, <2 x i32> <i32 0, i32 1>
return _mm256_extracti128_si256(a, 0);
}
+TEST_CONSTEXPR(match_m128i(_mm256_extracti128_si256(((__m256i){1ULL, 2ULL, 3ULL, 4ULL}), 0),
+ 1ULL, 2ULL));
__m256i test_mm256_hadd_epi16(__m256i a, __m256i b) {
// CHECK-LABEL: test_mm256_hadd_epi16
diff --git a/clang/test/CodeGen/X86/avx512dq-builtins.c b/clang/test/CodeGen/X86/avx512dq-builtins.c
index 4112561216af8..08013705875d0 100644
--- a/clang/test/CodeGen/X86/avx512dq-builtins.c
+++ b/clang/test/CodeGen/X86/avx512dq-builtins.c
@@ -1402,6 +1402,11 @@ __m256 test_mm512_extractf32x8_ps(__m512 __A) {
// CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> poison, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
return _mm512_extractf32x8_ps(__A, 1);
}
+TEST_CONSTEXPR(match_m256(_mm512_extractf32x8_ps(((__m512){
+ 0.0f,1.0f,2.0f,3.0f, 4.0f,5.0f,6.0f,7.0f,
+ 8.0f,9.0f,10.0f,11.0f, 12.0f,13.0f,14.0f,15.0f
+ }), 1),
+ 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f));
__m256 test_mm512_mask_extractf32x8_ps(__m256 __W, __mmask8 __U, __m512 __A) {
// CHECK-LABEL: test_mm512_mask_extractf32x8_ps
@@ -1409,6 +1414,15 @@ __m256 test_mm512_mask_extractf32x8_ps(__m256 __W, __mmask8 __U, __m512 __A) {
// CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
return _mm512_mask_extractf32x8_ps(__W, __U, __A, 1);
}
+TEST_CONSTEXPR(match_m256(_mm512_mask_extractf32x8_ps(
+ (__m256){0,0,0,0,0,0,0,0}, // W
+ ((__mmask8)0xFF), // U = all ones (plain)
+ (__m512){
+ 0.0f,1.0f,2.0f,3.0f,4.0f,5.0f,6.0f,7.0f,
+ 8.0f,9.0f,10.0f,11.0f,12.0f,13.0f,14.0f,15.0f
+ },
+ 1),
+ 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f));
__m256 test_mm512_maskz_extractf32x8_ps(__mmask8 __U, __m512 __A) {
// CHECK-LABEL: test_mm512_maskz_extractf32x8_ps
@@ -1416,12 +1430,24 @@ __m256 test_mm512_maskz_extractf32x8_ps(__mmask8 __U, __m512 __A) {
// CHECK: select <8 x i1> %{{.*}}, <8 x float> %{{.*}}, <8 x float> %{{.*}}
return _mm512_maskz_extractf32x8_ps(__U, __A, 1);
}
+TEST_CONSTEXPR(match_m256(_mm512_maskz_extractf32x8_ps(
+ ((__mmask8)0x0F),
+ (__m512){
+ 0.0f,1.0f,2.0f,3.0f,4.0f,5.0f,6.0f,7.0f,
+ 8.0f,9.0f,10.0f,11.0f,12.0f,13.0f,14.0f,15.0f
+ },
+ 1),
+ 8.0f, 9.0f, 10.0f, 11.0f, 0.0f, 0.0f, 0.0f, 0.0f));
__m128d test_mm512_extractf64x2_pd(__m512d __A) {
// CHECK-LABEL: test_mm512_extractf64x2_pd
// CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> poison, <2 x i32> <i32 6, i32 7>
return _mm512_extractf64x2_pd(__A, 3);
}
+TEST_CONSTEXPR(match_m128d(_mm512_extractf64x2_pd(((__m512d){
+ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0
+ }), 3),
+ 6.0, 7.0));
__m128d test_mm512_mask_extractf64x2_pd(__m128d __W, __mmask8 __U, __m512d __A) {
// CHECK-LABEL: test_mm512_mask_extractf64x2_pd
@@ -1429,6 +1455,12 @@ __m128d test_mm512_mask_extractf64x2_pd(__m128d __W, __mmask8 __U, __m512d __A)
// CHECK: select <2 x i1> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}
return _mm512_mask_extractf64x2_pd(__W, __U, __A, 3);
}
+TEST_CONSTEXPR(match_m128d(_mm512_mask_extractf64x2_pd(
+ (__m128d){100.0, 101.0}, // W(merge)
+ (__mmask8)0x1, // 0000 0001b
+ (__m512d){0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0},
+ 3),
+ 6.0, 101.0));
__m128d test_mm512_maskz_extractf64x2_pd(__mmask8 __U, __m512d __A) {
// CHECK-LABEL: test_mm512_maskz_extractf64x2_pd
@@ -1436,12 +1468,21 @@ __m128d test_mm512_maskz_extractf64x2_pd(__mmask8 __U, __m512d __A) {
// CHECK: select <2 x i1> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}
return _mm512_maskz_extractf64x2_pd(__U, __A, 3);
}
+TEST_CONSTEXPR(match_m128d(_mm512_maskz_extractf64x2_pd(
+ (__mmask8)0x2, // 0000 0010b
+ (__m512d){0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0},
+ 3),
+ 0.0, 7.0));
__m256i test_mm512_extracti32x8_epi32(__m512i __A) {
// CHECK-LABEL: test_mm512_extracti32x8_epi32
// CHECK: shufflevector <16 x i32> %{{.*}}, <16 x i32> poison, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
return _mm512_extracti32x8_epi32(__A, 1);
}
+TEST_CONSTEXPR(match_m256i(_mm512_extracti32x8_epi32(((__m512i){
+ 0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15
+ }), 1),
+ 8, 9,10,11,12,13,14,15));
__m256i test_mm512_mask_extracti32x8_epi32(__m256i __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: test_mm512_mask_extracti32x8_epi32
@@ -1449,6 +1490,13 @@ __m256i test_mm512_mask_extracti32x8_epi32(__m256i __W, __mmask8 __U, __m512i __
// CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm512_mask_extracti32x8_epi32(__W, __U, __A, 1);
}
+TEST_CONSTEXPR(match_m256i(_mm512_mask_extracti32x8_epi32(
+ (__m256i){100,101,102,103,104,105,106,107}, // W(merge)
+ (__mmask8)0xAA, // 1010 1010b → only odd lanetake
+ (__m512i){ 0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15 },
+ 1),
+ // lane0..7: 8,9,10,11,12,13,14,15
+ 100, 9, 102, 11, 104, 13, 106, 15));
__m256i test_mm512_maskz_extracti32x8_epi32(__mmask8 __U, __m512i __A) {
// CHECK-LABEL: test_mm512_maskz_extracti32x8_epi32
@@ -1456,12 +1504,21 @@ __m256i test_mm512_maskz_extracti32x8_epi32(__mmask8 __U, __m512i __A) {
// CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm512_maskz_extracti32x8_epi32(__U, __A, 1);
}
+TEST_CONSTEXPR(match_m256i(_mm512_maskz_extracti32x8_epi32(
+ (__mmask8)0x0F,
+ (__m512i){ 0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15 },
+ 1),
+ 8, 9, 10, 11, 0, 0, 0, 0));
__m128i test_mm512_extracti64x2_epi64(__m512i __A) {
// CHECK-LABEL: test_mm512_extracti64x2_epi64
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> poison, <2 x i32> <i32 6, i32 7>
return _mm512_extracti64x2_epi64(__A, 3);
}
+TEST_CONSTEXPR(match_m128i_64(_mm512_extracti64x2_epi64(((__m512i){
+ 0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL
+ }), 3),
+ 6ULL, 7ULL));
__m128i test_mm512_mask_extracti64x2_epi64(__m128i __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: test_mm512_mask_extracti64x2_epi64
@@ -1469,6 +1526,12 @@ __m128i test_mm512_mask_extracti64x2_epi64(__m128i __W, __mmask8 __U, __m512i __
// CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
return _mm512_mask_extracti64x2_epi64(__W, __U, __A, 3);
}
+TEST_CONSTEXPR(match_m128i_64(_mm512_mask_extracti64x2_epi64(
+ (__m128i){100ULL, 101ULL}, // W(merge)
+ (__mmask8)0x1, // lane0만 take
+ (__m512i){0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL},
+ 3),
+ 6ULL, 101ULL));
__m128i test_mm512_maskz_extracti64x2_epi64(__mmask8 __U, __m512i __A) {
// CHECK-LABEL: test_mm512_maskz_extracti64x2_epi64
@@ -1476,6 +1539,11 @@ __m128i test_mm512_maskz_extracti64x2_epi64(__mmask8 __U, __m512i __A) {
// CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
return _mm512_maskz_extracti64x2_epi64(__U, __A, 3);
}
+TEST_CONSTEXPR(match_m128i_64(_mm512_maskz_extracti64x2_epi64(
+ (__mmask8)0x2, // lane1 take, lane0 0
+ (__m512i){0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL},
+ 3),
+ 0ULL, 7ULL));
__m512 test_mm512_insertf32x8(__m512 __A, __m256 __B) {
// CHECK-LABEL: test_mm512_insertf32x8
diff --git a/clang/test/CodeGen/X86/avx512f-builtins.c b/clang/test/CodeGen/X86/avx512f-builtins.c
index 84eaad8d99e61..26dcc0b35d0cb 100644
--- a/clang/test/CodeGen/X86/avx512f-builtins.c
+++ b/clang/test/CodeGen/X86/avx512f-builtins.c
@@ -2452,6 +2452,11 @@ __m256d test_mm512_extractf64x4_pd(__m512d a)
// CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
return _mm512_extractf64x4_pd(a, 1);
}
+TEST_CONSTEXPR(match_m256d(_mm512_extractf64x4_pd(((__m512d){
+ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0
+ }), 1),
+ 4.0, 5.0, 6.0, 7.0));
+
__m256d test_mm512_mask_extractf64x4_pd(__m256d __W,__mmask8 __U,__m512d __A){
// CHECK-LABEL: test_mm512_mask_extractf64x4_pd
@@ -2459,6 +2464,12 @@ __m256d test_mm512_mask_extractf64x4_pd(__m256d __W,__mmask8 __U,__m512d __A){
// CHECK: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
return _mm512_mask_extractf64x4_pd( __W, __U, __A, 1);
}
+TEST_CONSTEXPR(match_m256d(_mm512_mask_extractf64x4_pd(
+ (__m256d){100.0,101.0,102.0,103.0}, // W(merge)
+ (__mmask8)0x5, // 0101b
+ (__m512d){0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0},
+ 1),
+ 4.0, 101.0, 6.0, 103.0));
__m256d test_mm512_maskz_extractf64x4_pd(__mmask8 __U,__m512d __A){
// CHECK-LABEL: test_mm512_maskz_extractf64x4_pd
@@ -2466,6 +2477,11 @@ __m256d test_mm512_maskz_extractf64x4_pd(__mmask8 __U,__m512d __A){
// CHECK: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
return _mm512_maskz_extractf64x4_pd( __U, __A, 1);
}
+TEST_CONSTEXPR(match_m256d(_mm512_maskz_extractf64x4_pd(
+ (__mmask8)0x3,
+ (__m512d){0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0},
+ 1),
+ 4.0, 5.0, 0.0, 0.0));
__m128 test_mm512_extractf32x4_ps(__m512 a)
{
@@ -2473,6 +2489,10 @@ __m128 test_mm512_extractf32x4_ps(__m512 a)
// CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
return _mm512_extractf32x4_ps(a, 1);
}
+TEST_CONSTEXPR(match_m128(_mm512_extractf32x4_ps(((__m512){
+ 0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15
+ }), 1),
+ 4.0f, 5.0f, 6.0f, 7.0f));
__m128 test_mm512_mask_extractf32x4_ps(__m128 __W, __mmask8 __U,__m512 __A){
// CHECK-LABEL: test_mm512_mask_extractf32x4_ps
@@ -2480,6 +2500,12 @@ __m128 test_mm512_mask_extractf32x4_ps(__m128 __W, __mmask8 __U,__m512 __A){
// CHECK: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
return _mm512_mask_extractf32x4_ps( __W, __U, __A, 1);
}
+TEST_CONSTEXPR(match_m128(_mm512_mask_extractf32x4_ps(
+ (__m128){100,101,102,103}, // W(merge)
+ (__mmask8)0x5, // 0101b
+ (__m512){0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15},
+ 1),
+ 4.0f, 101.0f, 6.0f, 103.0f));
__m128 test_mm512_maskz_extractf32x4_ps( __mmask8 __U,__m512 __A){
// CHECK-LABEL: test_mm512_maskz_extractf32x4_ps
@@ -2487,6 +2513,11 @@ __m128 test_mm512_maskz_extractf32x4_ps( __mmask8 __U,__m512 __A){
// CHECK: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
return _mm512_maskz_extractf32x4_ps(__U, __A, 1);
}
+TEST_CONSTEXPR(match_m128(_mm512_maskz_extractf32x4_ps(
+ (__mmask8)0x3,
+ (__m512){0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15},
+ 1),
+ 4.0f, 5.0f, 0.0f, 0.0f));
__mmask16 test_mm512_cmpeq_epu32_mask(__m512i __a, __m512i __b) {
// CHECK-LABEL: test_mm512_cmpeq_epu32_mask
@@ -7047,6 +7078,10 @@ __m128i test_mm512_extracti32x4_epi32(__m512i __A) {
// CHECK: shufflevector <16 x i32> %{{.*}}, <16 x i32> poison, <4 x i32> <i32 12, i32 13, i32 14, i32 15>
return _mm512_extracti32x4_epi32(__A, 3);
}
+TEST_CONSTEXPR(match_m128i(_mm512_extracti32x4_epi32(((__m512i){
+ 0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15
+ }), 3),
+ 12, 13, 14, 15));
__m128i test_mm512_mask_extracti32x4_epi32(__m128i __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: test_mm512_mask_extracti32x4_epi32
@@ -7054,6 +7089,15 @@ __m128i test_mm512_mask_extracti32x4_epi32(__m128i __W, __mmask8 __U, __m512i __
// CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm512_mask_extracti32x4_epi32(__W, __U, __A, 3);
}
+TEST_CONSTEXPR(match_m128i(_mm512_mask_extracti32x4_epi32(
+ (__m128i){100,101,102,103}, // merge=W
+ (__mmask8)0x5, // 0101b
+ (__m512i){
+ 0,1,2,3, 4,5,6,7,
+ 8,9,10,11, 12,13,14,15
+ },
+ 3),
+ 12, 101, 14, 103));
__m128i test_mm512_maskz_extracti32x4_epi32(__mmask8 __U, __m512i __A) {
// CHECK-LABEL: test_mm512_maskz_extracti32x4_epi32
@@ -7061,12 +7105,24 @@ __m128i test_mm512_maskz_extracti32x4_epi32(__mmask8 __U, __m512i __A) {
// CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm512_maskz_extracti32x4_epi32(__U, __A, 3);
}
+TEST_CONSTEXPR(match_m128i(_mm512_maskz_extracti32x4_epi32(
+ (__mmask8)0x3,
+ (__m512i){
+ 0,1,2,3, 4,5,6,7,
+ 8,9,10,11, 12,13,14,15
+ },
+ 3),
+12, 13, 0, 0));
__m256i test_mm512_extracti64x4_epi64(__m512i __A) {
// CHECK-LABEL: test_mm512_extracti64x4_epi64
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
return _mm512_extracti64x4_epi64(__A, 1);
}
+TEST_CONSTEXPR(match_m256i(_mm512_extracti64x4_epi64(((__m512i){
+ 0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL
+ }), 1),
+ 4ULL, 5ULL, 6ULL, 7ULL));
__m256i test_mm512_mask_extracti64x4_epi64(__m256i __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: test_mm512_mask_extracti64x4_epi64
@@ -7074,6 +7130,12 @@ __m256i test_mm512_mask_extracti64x4_epi64(__m256i __W, __mmask8 __U, __m512i __
// CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
return _mm512_mask_extracti64x4_epi64(__W, __U, __A, 1);
}
+TEST_CONSTEXPR(match_m256i_64(_mm512_mask_extracti64x4_epi64(
+ (__m256i){100ULL,101ULL,102ULL,103ULL},
+ (__mmask8)0x5,
+ (__m512i){0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL},
+ 1),
+ 4ULL, 101ULL, 6ULL, 103ULL));
__m256i test_mm512_maskz_extracti64x4_epi64(__mmask8 __U, __m512i __A) {
// CHECK-LABEL: test_mm512_maskz_extracti64x4_epi64
@@ -7081,6 +7143,11 @@ __m256i test_mm512_maskz_extracti64x4_epi64(__mmask8 __U, __m512i __A) {
// CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
return _mm512_maskz_extracti64x4_epi64(__U, __A, 1);
}
+TEST_CONSTEXPR(match_m256i(_mm512_maskz_extracti64x4_epi64(
+ (__mmask8)0x3,
+ (__m512i){0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL},
+ 1),
+ 4ULL, 5ULL, 0ULL, 0ULL));
__m512d test_mm512_insertf64x4(__m512d __A, __m256d __B) {
// CHECK-LABEL: test_mm512_insertf64x4
diff --git a/clang/test/CodeGen/X86/avx512vl-builtins.c b/clang/test/CodeGen/X86/avx512vl-builtins.c
index 5282c7ab06dea..b2de0d660b786 100644
--- a/clang/test/CodeGen/X86/avx512vl-builtins.c
+++ b/clang/test/CodeGen/X86/avx512vl-builtins.c
@@ -9520,6 +9520,10 @@ __m128 test_mm256_extractf32x4_ps(__m256 __A) {
// CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
return _mm256_extractf32x4_ps(__A, 1);
}
+TEST_CONSTEXPR(match_m128(_mm256_extractf32x4_ps(((__m256){
+ 0,1,2,3, 4,5,6,7
+ }), 1),
+ 4.0f, 5.0f, 6.0f, 7.0f));
__m128 test_mm256_mask_extractf32x4_ps(__m128 __W, __mmask8 __U, __m256 __A) {
// CHECK-LABEL: test_mm256_mask_extractf32x4_ps
@@ -9527,6 +9531,12 @@ __m128 test_mm256_mask_extractf32x4_ps(__m128 __W, __mmask8 __U, __m256 __A) {
// CHECK: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
return _mm256_mask_extractf32x4_ps(__W, __U, __A, 1);
}
+TEST_CONSTEXPR( match_m128(_mm256_mask_extractf32x4_ps(
+ (__m128){100,101,102,103}, // W (merge)
+ (__mmask8)0x5, // 0101b
+ (__m256){0,1,2,3, 4,5,6,7},
+ 1),
+ 4.0f, 101.0f, 6.0f, 103.0f));
__m128 test_mm256_maskz_extractf32x4_ps(__mmask8 __U, __m256 __A) {
// CHECK-LABEL: test_mm256_maskz_extractf32x4_ps
@@ -9534,12 +9544,21 @@ __m128 test_mm256_maskz_extractf32x4_ps(__mmask8 __U, __m256 __A) {
// CHECK: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
return _mm256_maskz_extractf32x4_ps(__U, __A, 1);
}
+TEST_CONSTEXPR(match_m128(_mm256_maskz_extractf32x4_ps(
+ (__mmask8)0x3,
+ (__m256){0,1,2,3, 4,5,6,7},
+ 1),
+ 4.0f, 5.0f, 0.0f, 0.0f));
__m128i test_mm256_extracti32x4_epi32(__m256i __A) {
// CHECK-LABEL: test_mm256_extracti32x4_epi32
// CHECK: shufflevector <8 x i32> %{{.*}}, <8 x i32> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
return _mm256_extracti32x4_epi32(__A, 1);
}
+TEST_CONSTEXPR(match_m128i(_mm256_extracti32x4_epi32(((__m256i){
+ 0,1,2,3, 4,5,6,7
+ }), 1),
+ 4, 5, 6, 7));
__m128i test_mm256_mask_extracti32x4_epi32(__m128i __W, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: test_mm256_mask_extracti32x4_epi32
@@ -9547,6 +9566,12 @@ __m128i test_mm256_mask_extracti32x4_epi32(__m128i __W, __mmask8 __U, __m256i __
// CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm256_mask_extracti32x4_epi32(__W, __U, __A, 1);
}
+TEST_CONSTEXPR(match_m128i(_mm256_mask_extracti32x4_epi32(
+ (__m128i){100,101,102,103}, // W (merge)
+ (__mmask8)0xA, // 1010b
+ (__m256i){0,1,2,3, 4,5,6,7},
+ 1),
+ 100, 5, 102, 7));
__m128i test_mm256_maskz_extracti32x4_epi32(__mmask8 __U, __m256i __A) {
// CHECK-LABEL: test_mm256_maskz_extracti32x4_epi32
@@ -9554,6 +9579,11 @@ __m128i test_mm256_maskz_extracti32x4_epi32(__mmask8 __U, __m256i __A) {
// CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm256_maskz_extracti32x4_epi32(__U, __A, 1);
}
+TEST_CONSTEXPR(match_m128i(_mm256_maskz_extracti32x4_epi32(
+ (__mmask8)0x3,
+ (__m256i){0,1,2,3, 4,5,6,7},
+ 1),
+ 4, 5, 0, 0));
__m256 test_mm256_insertf32x4(__m256 __A, __m128 __B) {
// CHECK-LABEL: test_mm256_insertf32x4
diff --git a/clang/test/CodeGen/X86/avx512vldq-builtins.c b/clang/test/CodeGen/X86/avx512vldq-builtins.c
index 938845799acf5..9cfcfea3dafc7 100644
--- a/clang/test/CodeGen/X86/avx512vldq-builtins.c
+++ b/clang/test/CodeGen/X86/avx512vldq-builtins.c
@@ -1083,6 +1083,8 @@ __m128d test_mm256_extractf64x2_pd(__m256d __A) {
// CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> poison, <2 x i32> <i32 2, i32 3>
return _mm256_extractf64x2_pd(__A, 1);
}
+TEST_CONSTEXPR(match_m128d(_mm256_extractf64x2_pd(((__m256d){0.0,1.0,2.0,3.0}), 1),
+ 2.0, 3.0));
__m128d test_mm256_mask_extractf64x2_pd(__m128d __W, __mmask8 __U, __m256d __A) {
// CHECK-LABEL: test_mm256_mask_extractf64x2_pd
@@ -1090,6 +1092,12 @@ __m128d test_mm256_mask_extractf64x2_pd(__m128d __W, __mmask8 __U, __m256d __A)
// CHECK: select <2 x i1> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}
return _mm256_mask_extractf64x2_pd(__W, __U, __A, 1);
}
+TEST_CONSTEXPR(match_m128d(_mm256_mask_extractf64x2_pd(
+ (__m128d){100.0, 101.0}, // W(merge)
+ (__mmask8)0x1,
+ (__m256d){0.0,1.0,2.0,3.0},
+ 1),
+ 2.0, 101.0));
__m128d test_mm256_maskz_extractf64x2_pd(__mmask8 __U, __m256d __A) {
// CHECK-LABEL: test_mm256_maskz_extractf64x2_pd
@@ -1097,12 +1105,19 @@ __m128d test_mm256_maskz_extractf64x2_pd(__mmask8 __U, __m256d __A) {
// CHECK: select <2 x i1> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}
return _mm256_maskz_extractf64x2_pd(__U, __A, 1);
}
+TEST_CONSTEXPR(match_m128d(_mm256_maskz_extractf64x2_pd(
+ (__mmask8)0x2,
+ (__m256d){0.0,1.0,2.0,3.0},
+ 1),
+ 0.0, 3.0));
__m128i test_mm256_extracti64x2_epi64(__m256i __A) {
// CHECK-LABEL: test_mm256_extracti64x2_epi64
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> poison, <2 x i32> <i32 2, i32 3>
return _mm256_extracti64x2_epi64(__A, 1);
}
+TEST_CONSTEXPR(match_m128i_64(_mm256_extracti64x2_epi64(((__m256i){0ULL,1ULL,2ULL,3ULL}), 1),
+ 2ULL, 3ULL));
__m128i test_mm256_mask_extracti64x2_epi64(__m128i __W, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: test_mm256_mask_extracti64x2_epi64
@@ -1110,6 +1125,12 @@ __m128i test_mm256_mask_extracti64x2_epi64(__m128i __W, __mmask8 __U, __m256i __
// CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
return _mm256_mask_extracti64x2_epi64(__W, __U, __A, 1);
}
+TEST_CONSTEXPR(match_m128i_64(_mm256_mask_extracti64x2_epi64(
+ (__m128i){100ULL, 101ULL}, // W(merge)
+ (__mmask8)0x1,
+ (__m256i){0ULL,1ULL,2ULL,3ULL},
+ 1),
+ 2ULL, 101ULL));
__m128i test_mm256_maskz_extracti64x2_epi64(__mmask8 __U, __m256i __A) {
// CHECK-LABEL: test_mm256_maskz_extracti64x2_epi64
@@ -1117,6 +1138,11 @@ __m128i test_mm256_maskz_extracti64x2_epi64(__mmask8 __U, __m256i __A) {
// CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
return _mm256_maskz_extracti64x2_epi64(__U, __A, 1);
}
+TEST_CONSTEXPR(match_m128i_64(_mm256_maskz_extracti64x2_epi64(
+ (__mmask8)0x2,
+ (__m256i){0ULL,1ULL,2ULL,3ULL},
+ 1),
+ 0ULL, 3ULL));
__m256d test_mm256_insertf64x2(__m256d __A, __m128d __B) {
// CHECK-LABEL: test_mm256_insertf64x2
>From b432c64ebbb176b28f1aa5b3568deaa8bea458af Mon Sep 17 00:00:00 2001
From: SeongjaeP <psjj960507 at gmail.com>
Date: Fri, 26 Sep 2025 11:17:39 +0900
Subject: [PATCH 09/21] Refactoring
---
clang/include/clang/Basic/BuiltinsX86.td | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/clang/include/clang/Basic/BuiltinsX86.td b/clang/include/clang/Basic/BuiltinsX86.td
index 77e599587edc3..7ff9f4864bb0a 100644
--- a/clang/include/clang/Basic/BuiltinsX86.td
+++ b/clang/include/clang/Basic/BuiltinsX86.td
@@ -474,9 +474,6 @@ let Features = "avx", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in
def dpps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, float>, _Constant char)">;
def cmppd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Vector<4, double>, _Constant char)">;
def cmpps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, float>, _Constant char)">;
- def vextractf128_pd256 : X86Builtin<"_Vector<2, double>(_Vector<4, double>, _Constant int)">;
- def vextractf128_ps256 : X86Builtin<"_Vector<4, float>(_Vector<8, float>, _Constant int)">;
- def vextractf128_si256 : X86Builtin<"_Vector<4, int>(_Vector<8, int>, _Constant int)">;
def cvtpd2ps256 : X86Builtin<"_Vector<4, float>(_Vector<4, double>)">;
def cvtps2dq256 : X86Builtin<"_Vector<8, int>(_Vector<8, float>)">;
def cvttpd2dq256 : X86Builtin<"_Vector<4, int>(_Vector<4, double>)">;
@@ -497,6 +494,9 @@ let Features = "avx", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWid
def blendps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, float>, _Constant int)">;
def blendvpd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Vector<4, double>, _Vector<4, double>)">;
def blendvps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, float>, _Vector<8, float>)">;
+ def vextractf128_pd256 : X86Builtin<"_Vector<2, double>(_Vector<4, double>, _Constant int)">;
+ def vextractf128_ps256 : X86Builtin<"_Vector<4, float>(_Vector<8, float>, _Constant int)">;
+ def vextractf128_si256 : X86Builtin<"_Vector<4, int>(_Vector<8, int>, _Constant int)">;
def vinsertf128_pd256 : X86Builtin<"_Vector<4, double>(_Vector<4, double>, _Vector<2, double>, _Constant int)">;
def vinsertf128_ps256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<4, float>, _Constant int)">;
def vinsertf128_si256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<4, int>, _Constant int)">;
@@ -605,7 +605,6 @@ let Features = "avx2", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] i
def permvarsf256 : X86Builtin<"_Vector<8, float>(_Vector<8, float>, _Vector<8, int>)">;
def permti256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<4, long long int>, _Constant int)">;
def permdi256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Constant int)">;
- def extract128i256 : X86Builtin<"_Vector<2, long long int>(_Vector<4, long long int>, _Constant int)">;
}
@@ -647,6 +646,7 @@ let Features = "avx2", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWi
def packsswb256 : X86Builtin<"_Vector<32, char>(_Vector<16, short>, _Vector<16, short>)">;
def packssdw256 : X86Builtin<"_Vector<16, short>(_Vector<8, int>, _Vector<8, int>)">;
def packuswb256 : X86Builtin<"_Vector<32, char>(_Vector<16, short>, _Vector<16, short>)">;
+ def extract128i256 : X86Builtin<"_Vector<2, long long int>(_Vector<4, long long int>, _Constant int)">;
}
let Features = "avx2", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in {
@@ -1055,7 +1055,7 @@ let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256
def alignq256 : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<4, long long int>, _Constant int)">;
}
-let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in {
+let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in {
def extractf64x4_mask : X86Builtin<"_Vector<4, double>(_Vector<8, double>, _Constant int, _Vector<4, double>, unsigned char)">;
def extractf32x4_mask : X86Builtin<"_Vector<4, float>(_Vector<16, float>, _Constant int, _Vector<4, float>, unsigned char)">;
}
@@ -2929,24 +2929,24 @@ let Features = "avx512vl", Attributes = [NoThrow, RequiredVectorWidth<256>] in {
def pmovqw256mem_mask : X86Builtin<"void(_Vector<8, short *>, _Vector<4, long long int>, unsigned char)">;
}
-let Features = "avx512dq", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in {
+let Features = "avx512dq", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in {
def extractf32x8_mask : X86Builtin<"_Vector<8, float>(_Vector<16, float>, _Constant int, _Vector<8, float>, unsigned char)">;
def extractf64x2_512_mask : X86Builtin<"_Vector<2, double>(_Vector<8, double>, _Constant int, _Vector<2, double>, unsigned char)">;
def extracti32x8_mask : X86Builtin<"_Vector<8, int>(_Vector<16, int>, _Constant int, _Vector<8, int>, unsigned char)">;
def extracti64x2_512_mask : X86Builtin<"_Vector<2, long long int>(_Vector<8, long long int>, _Constant int, _Vector<2, long long int>, unsigned char)">;
}
-let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in {
+let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in {
def extracti32x4_mask : X86Builtin<"_Vector<4, int>(_Vector<16, int>, _Constant int, _Vector<4, int>, unsigned char)">;
def extracti64x4_mask : X86Builtin<"_Vector<4, long long int>(_Vector<8, long long int>, _Constant int, _Vector<4, long long int>, unsigned char)">;
}
-let Features = "avx512dq,avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
+let Features = "avx512dq,avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in {
def extractf64x2_256_mask : X86Builtin<"_Vector<2, double>(_Vector<4, double>, _Constant int, _Vector<2, double>, unsigned char)">;
def extracti64x2_256_mask : X86Builtin<"_Vector<2, long long int>(_Vector<4, long long int>, _Constant int, _Vector<2, long long int>, unsigned char)">;
}
-let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
+let Features = "avx512vl", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in {
def extractf32x4_256_mask : X86Builtin<"_Vector<4, float>(_Vector<8, float>, _Constant int, _Vector<4, float>, unsigned char)">;
def extracti32x4_256_mask : X86Builtin<"_Vector<4, int>(_Vector<8, int>, _Constant int, _Vector<4, int>, unsigned char)">;
}
>From 7abcb91eeb441b94825a208dc6926e24182acea3 Mon Sep 17 00:00:00 2001
From: SeongjaeP <psjj960507 at gmail.com>
Date: Fri, 26 Sep 2025 11:20:04 +0900
Subject: [PATCH 10/21] Refactoring and Test Pass
---
clang/test/CodeGen/X86/avx2-builtins.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/test/CodeGen/X86/avx2-builtins.c b/clang/test/CodeGen/X86/avx2-builtins.c
index a815f96ab9468..52e2812e9d144 100644
--- a/clang/test/CodeGen/X86/avx2-builtins.c
+++ b/clang/test/CodeGen/X86/avx2-builtins.c
@@ -466,6 +466,8 @@ __m128i test0_mm256_extracti128_si256_0(__m256i a) {
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> poison, <2 x i32> <i32 0, i32 1>
return _mm256_extracti128_si256(a, 0);
}
+TEST_CONSTEXPR(match_m128i(_mm256_extracti128_si256(((__m256i){1ULL, 2ULL, 3ULL, 4ULL}), 0),
+ 1ULL, 2ULL));
__m128i test1_mm256_extracti128_si256_1(__m256i a) {
// CHECK-LABEL: test1_mm256_extracti128_si256
@@ -479,8 +481,6 @@ __m128i test2_mm256_extracti128_si256(__m256i a) {
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> poison, <2 x i32> <i32 0, i32 1>
return _mm256_extracti128_si256(a, 0);
}
-TEST_CONSTEXPR(match_m128i(_mm256_extracti128_si256(((__m256i){1ULL, 2ULL, 3ULL, 4ULL}), 0),
- 1ULL, 2ULL));
__m256i test_mm256_hadd_epi16(__m256i a, __m256i b) {
// CHECK-LABEL: test_mm256_hadd_epi16
>From 9acd08a23c36733d92a982da9f6a481c1ca49f28 Mon Sep 17 00:00:00 2001
From: SeongjaeP <psjj960507 at gmail.com>
Date: Fri, 26 Sep 2025 11:20:56 +0900
Subject: [PATCH 11/21] Refactoring and Test Pass
---
clang/test/CodeGen/X86/avx-builtins.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/clang/test/CodeGen/X86/avx-builtins.c b/clang/test/CodeGen/X86/avx-builtins.c
index 758fb5ef8204d..995666baf6050 100644
--- a/clang/test/CodeGen/X86/avx-builtins.c
+++ b/clang/test/CodeGen/X86/avx-builtins.c
@@ -1066,7 +1066,6 @@ __m128d test_mm256_extractf128_pd(__m256d A) {
// CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> poison, <2 x i32> <i32 2, i32 3>
return _mm256_extractf128_pd(A, 1);
}
-
TEST_CONSTEXPR(match_m128d(_mm256_extractf128_pd(((__m256d){0.0, 1.0, 2.0, 3.0}), 1),
2.0, 3.0));
@@ -1075,7 +1074,6 @@ __m128 test_mm256_extractf128_ps(__m256 A) {
// CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
return _mm256_extractf128_ps(A, 1);
}
-
TEST_CONSTEXPR(match_m128(_mm256_extractf128_ps(((__m256){0,1,2,3,4,5,6,7}), 1),
4.0f, 5.0f, 6.0f, 7.0f));
@@ -1084,9 +1082,8 @@ __m128i test_mm256_extractf128_si256(__m256i A) {
// CHECK: shufflevector <8 x i32> %{{.*}}, <8 x i32> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
return _mm256_extractf128_si256(A, 1);
}
-
-TEST_CONSTEXPR(match_m128i(_mm256_extractf128_si256(((__m256i){0,1,2,3,4,5,6,7}), 1),
- 4, 5, 6, 7));
+TEST_CONSTEXPR(match_m128i(_mm256_extractf128_si256(((__m256i){0ULL, 1ULL, 2ULL, 3ULL}), 1),
+ 2ULL, 3ULL));
__m256d test_mm256_floor_pd(__m256d x) {
// CHECK-LABEL: test_mm256_floor_pd
>From bf92d73f8c10dfa140d58f409a3209109cd923aa Mon Sep 17 00:00:00 2001
From: SeongjaeP <psjj960507 at gmail.com>
Date: Sat, 27 Sep 2025 15:11:00 +0900
Subject: [PATCH 12/21] Refactoring and add avx512dq test
---
clang/lib/AST/ByteCode/InterpBuiltin.cpp | 99 +++++++++++++---------
clang/lib/AST/ExprConstant.cpp | 75 +++-------------
clang/test/CodeGen/X86/avx512dq-builtins.c | 70 ++++++++-------
3 files changed, 106 insertions(+), 138 deletions(-)
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 733ea2478fc98..876868960a58c 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -2884,71 +2884,94 @@ static bool interp__builtin_x86_extract_vector(InterpState &S, CodePtr OpPC,
// __builtin_extract_masked
static bool interp__builtin_x86_extract_vector_masked(InterpState &S, CodePtr OpPC,
- const CallExpr *Call,
- unsigned ID) {
- assert(Call->getNumArgs() == 4);
+ const CallExpr *Call,
+ unsigned ID) {
+ unsigned NumArgs = Call->getNumArgs();
- // kmask
- APSInt KmaskAPS = popToAPSInt(S, Call->getArg(3));
- uint64_t Kmask = KmaskAPS.getZExtValue();
+ const Pointer &Dst = S.Stk.peek<Pointer>();
+ if (!Dst.getFieldDesc()->isPrimitiveArray())
+ return false;
- // merge
- const Pointer &Merge = S.Stk.pop<Pointer>();
- bool HasMergeVec = Merge.isLive() && Merge.getFieldDesc() &&
- Merge.getFieldDesc()->isPrimitiveArray();
-
- // srcimm
- APSInt ImmAPS = popToAPSInt(S, Call->getArg(1));
- uint64_t Index = ImmAPS.getZExtValue();
+ const Pointer *Merge = nullptr;
+ uint64_t Kmask = 0;
+ uint64_t Imm = 0;
+ const Pointer *Src = nullptr;
- // srcvec
- const Pointer &Src = S.Stk.pop<Pointer>();
- if (!Src.getFieldDesc()->isPrimitiveArray())
+ if (NumArgs == 4) {
+ // __m256 _mm512_mask_extractf32x8_ps(W, U, A, imm)
+ APSInt ImmAPS = popToAPSInt(S, Call->getArg(3));
+ Imm = ImmAPS.getZExtValue();
+
+ const Pointer &SrcP = S.Stk.pop<Pointer>();
+ Src = &SrcP;
+
+ APSInt KmaskAPS = popToAPSInt(S, Call->getArg(1));
+ Kmask = KmaskAPS.getZExtValue();
+
+ const Pointer &MergeP = S.Stk.pop<Pointer>();
+ Merge = &MergeP;
+
+ } else if (NumArgs == 3) {
+ // __m256 _mm512_maskz_extractf32x8_ps(U, A, imm)
+ APSInt ImmAPS = popToAPSInt(S, Call->getArg(2));
+ Imm = ImmAPS.getZExtValue();
+
+ const Pointer &SrcP = S.Stk.pop<Pointer>();
+ Src = &SrcP;
+
+ APSInt KmaskAPS = popToAPSInt(S, Call->getArg(0));
+ Kmask = KmaskAPS.getZExtValue();
+
+ Merge = nullptr; // maskz → zero fill
+ } else {
return false;
+ }
- // dst (return)
- const Pointer &Dst = S.Stk.peek<Pointer>();
- if (!Dst.getFieldDesc()->isPrimitiveArray())
+ if (!Src->getFieldDesc()->isPrimitiveArray())
return false;
- unsigned SrcElems = Src.getNumElems();
+ unsigned SrcElems = Src->getNumElems();
unsigned DstElems = Dst.getNumElems();
if (SrcElems == 0 || DstElems == 0 || (SrcElems % DstElems) != 0)
return false;
unsigned NumLanes = SrcElems / DstElems;
- unsigned Lane = static_cast<unsigned>(Index % NumLanes);
+ unsigned Lane = static_cast<unsigned>(Imm % NumLanes);
unsigned ExtractPos = Lane * DstElems;
- PrimType ElemPT = Src.getFieldDesc()->getPrimType();
+ PrimType ElemPT = Src->getFieldDesc()->getPrimType();
if (ElemPT != Dst.getFieldDesc()->getPrimType())
return false;
- // Merge vector type/len check(if)
- if (HasMergeVec) {
- if (Merge.getFieldDesc()->getPrimType() != ElemPT ||
- Merge.getNumElems() != DstElems)
- return false;
- }
+ // --- 여기서 fast-path 추가 ---
+ unsigned UsedBits = std::min<unsigned>(DstElems, 64); // mask 폭 제한
+ uint64_t AllOnes = (UsedBits == 64 ? ~0ull : ((1ull << UsedBits) - 1));
+ bool MaskAll = (Kmask & AllOnes) == AllOnes;
- // generate 0 value
- auto storeZeroAt = [&](unsigned I) {
+ if (MaskAll) {
+ // merge는 무시, src에서 그대로 복사
TYPE_SWITCH(ElemPT, {
- Dst.elem<T>(I) = T{};
+ for (unsigned I = 0; I != DstElems; ++I)
+ Dst.elem<T>(I) = Src->elem<T>(ExtractPos + I);
});
+ Dst.initializeAllElements();
+ return true;
+ }
+ // --- fast-path 끝 ---
+
+ auto storeZeroAt = [&](unsigned I) {
+ TYPE_SWITCH(ElemPT, { Dst.elem<T>(I) = T{}; });
};
TYPE_SWITCH(ElemPT, {
for (unsigned I = 0; I != DstElems; ++I) {
bool Take = ((Kmask >> I) & 1) != 0;
if (Take) {
- Dst.elem<T>(I) = Src.elem<T>(ExtractPos + I);
+ Dst.elem<T>(I) = Src->elem<T>(ExtractPos + I);
+ } else if (Merge) {
+ Dst.elem<T>(I) = Merge->elem<T>(I);
} else {
- if (HasMergeVec) {
- Dst.elem<T>(I) = Merge.elem<T>(I);
- } else {
- storeZeroAt(I);
- }
+ storeZeroAt(I);
}
}
});
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 4ac56448af950..ae559de42eada 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -11959,12 +11959,16 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
return Success(APValue(ResultElements.data(), RetLen), E);
}
- case X86::BI__builtin_ia32_extracti32x4_256_mask: // _mm256_extracti32x4_epi32
- case X86::BI__builtin_ia32_extracti32x4_mask: // _mm512_extracti32x4_epi32
- case X86::BI__builtin_ia32_extracti32x8_mask: // _mm512_extracti32x8_epi32
- case X86::BI__builtin_ia32_extracti64x2_256_mask: // _mm256_extracti64x2_epi64
- case X86::BI__builtin_ia32_extracti64x2_512_mask: // _mm512_extracti64x2_epi64
- case X86::BI__builtin_ia32_extracti64x4_mask: { // _mm512_extracti64x4_epi64
+ case X86::BI__builtin_ia32_extracti32x4_256_mask:
+ case X86::BI__builtin_ia32_extractf32x4_256_mask:
+ case X86::BI__builtin_ia32_extracti32x4_mask:
+ case X86::BI__builtin_ia32_extractf32x4_mask:
+ case X86::BI__builtin_ia32_extracti32x8_mask:
+ case X86::BI__builtin_ia32_extractf32x8_mask:
+ case X86::BI__builtin_ia32_extracti64x2_256_mask:
+ case X86::BI__builtin_ia32_extractf64x2_256_mask:
+ case X86::BI__builtin_ia32_extracti64x2_512_mask:
+ case X86::BI__builtin_ia32_extractf64x2_512_mask: {
APValue SourceVec, SourceImm, SourceMerge, SourceKmask;
if (!EvaluateAsRValue(Info, E->getArg(0), SourceVec) ||
!EvaluateAsRValue(Info, E->getArg(1), SourceImm) ||
@@ -11984,11 +11988,7 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
unsigned NumLanes = SrcLen / RetLen;
unsigned idx = SourceImm.getInt().getZExtValue() & (NumLanes - 1);
-
- // Step 2) Apply kmask (covers plain/mask/maskz):
- // - plain : headers pass kmask=all-ones; merge is undef → always take Extracted.
- // - mask : merge=dst; take? Extracted[i] : dst[i]
- // - maskz : merge=zero; take? Extracted[i] : 0
+
uint64_t KmaskBits = SourceKmask.getInt().getZExtValue();
auto makeZeroInt = [&]() -> APValue {
@@ -12004,9 +12004,7 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
if (Take) {
ResultElements.push_back(SourceVec.getVectorElt(idx * RetLen + i));
} else {
- // For plain (all-ones) this path is never taken.
- // For mask : merge is the original dst element.
- // For maskz : headers pass zero vector as merge.
+
const APValue &MergeElt =
SourceMerge.isVector() ? SourceMerge.getVectorElt(i) : makeZeroInt();
ResultElements.push_back(MergeElt);
@@ -12015,55 +12013,6 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
return Success(APValue(ResultElements.data(), RetLen), E);
}
- case X86::BI__builtin_ia32_extractf32x4_256_mask: // _mm256_extractf32x4_ps _mm256_mask_extractf32x4_ps _mm256_maskz_extractf32x4_ps
- case X86::BI__builtin_ia32_extractf32x4_mask: // _mm512_extractf32x4_ps _mm512_mask_extractf32x4_ps _mm512_maskz_extractf32x4_ps
- case X86::BI__builtin_ia32_extractf32x8_mask: // _mm512_extractf32x8_ps _mm512_mask_extractf32x8_ps _mm512_maskz_extractf32x8_ps
-
- case X86::BI__builtin_ia32_extractf64x2_256_mask: // _mm256_extractf64x2_pd _mm256_mask_extractf64x2_pd _mm256_maskz_extractf64x2_pd
- case X86::BI__builtin_ia32_extractf64x2_512_mask: // _mm512_extractf64x2_pd _mm512_mask_extractf64x2_pd _mm512_maskz_extractf64x2_pd
- case X86::BI__builtin_ia32_extractf64x4_mask: { // _mm512_extractf64x4_pd _mm512_mask_extractf64x4_pd _mm512_maskz_extractf64x4_pd
- APValue SourceVec, SourceImm, SourceMerge, SourceKmask;
- if (!EvaluateAsRValue(Info, E->getArg(0), SourceVec) ||
- !EvaluateAsRValue(Info, E->getArg(1), SourceImm) ||
- !EvaluateAsRValue(Info, E->getArg(2), SourceMerge) ||
- !EvaluateAsRValue(Info, E->getArg(3), SourceKmask))
- return false;
-
- const auto *RetVT = E->getType()->castAs<VectorType>();
- QualType EltTy = RetVT->getElementType();
- unsigned RetLen = RetVT->getNumElements();
-
- if (!SourceVec.isVector())
- return false;
- unsigned SrcLen = SourceVec.getVectorLength();
- if (SrcLen % RetLen != 0)
- return false;
-
- unsigned NumLanes = SrcLen / RetLen;
- unsigned idx = SourceImm.getInt().getZExtValue() & (NumLanes - 1);
-
- uint64_t KmaskBits = SourceKmask.getInt().getZExtValue();
-
- auto makeZeroFP = [&]() -> APValue {
- const llvm::fltSemantics &Sem =
- Info.Ctx.getFloatTypeSemantics(EltTy);
- return APValue(llvm::APFloat::getZero(Sem));
- };
-
- SmallVector<APValue, 32> ResultElements;
- ResultElements.reserve(RetLen);
- for (unsigned i = 0; i < RetLen; i++) {
- bool Take = (KmaskBits >> i) & 1;
- if (Take) {
- ResultElements.push_back(SourceVec.getVectorElt(idx * RetLen + i));
- } else {
- const APValue &MergeElt =
- SourceMerge.isVector() ? SourceMerge.getVectorElt(i) : makeZeroFP();
- ResultElements.push_back(MergeElt);
- }
- }
- return Success(APValue(ResultElements.data(), RetLen), E);
- }
case X86::BI__builtin_ia32_vpshldd128:
case X86::BI__builtin_ia32_vpshldd256:
diff --git a/clang/test/CodeGen/X86/avx512dq-builtins.c b/clang/test/CodeGen/X86/avx512dq-builtins.c
index 08013705875d0..5a61040db9ef3 100644
--- a/clang/test/CodeGen/X86/avx512dq-builtins.c
+++ b/clang/test/CodeGen/X86/avx512dq-builtins.c
@@ -1415,12 +1415,12 @@ __m256 test_mm512_mask_extractf32x8_ps(__m256 __W, __mmask8 __U, __m512 __A) {
return _mm512_mask_extractf32x8_ps(__W, __U, __A, 1);
}
TEST_CONSTEXPR(match_m256(_mm512_mask_extractf32x8_ps(
- (__m256){0,0,0,0,0,0,0,0}, // W
- ((__mmask8)0xFF), // U = all ones (plain)
- (__m512){
+ ((__m256)(__v8sf){0,0,0,0,0,0,0,0}), // W
+ (__mmask8)0xFF,
+ ((__m512)(__v16sf){
0.0f,1.0f,2.0f,3.0f,4.0f,5.0f,6.0f,7.0f,
8.0f,9.0f,10.0f,11.0f,12.0f,13.0f,14.0f,15.0f
- },
+ }),
1),
8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f));
@@ -1431,11 +1431,11 @@ __m256 test_mm512_maskz_extractf32x8_ps(__mmask8 __U, __m512 __A) {
return _mm512_maskz_extractf32x8_ps(__U, __A, 1);
}
TEST_CONSTEXPR(match_m256(_mm512_maskz_extractf32x8_ps(
- ((__mmask8)0x0F),
- (__m512){
+ (__mmask8)0x0F,
+ ((__m512)(__v16sf){
0.0f,1.0f,2.0f,3.0f,4.0f,5.0f,6.0f,7.0f,
8.0f,9.0f,10.0f,11.0f,12.0f,13.0f,14.0f,15.0f
- },
+ }),
1),
8.0f, 9.0f, 10.0f, 11.0f, 0.0f, 0.0f, 0.0f, 0.0f));
@@ -1444,9 +1444,8 @@ __m128d test_mm512_extractf64x2_pd(__m512d __A) {
// CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> poison, <2 x i32> <i32 6, i32 7>
return _mm512_extractf64x2_pd(__A, 3);
}
-TEST_CONSTEXPR(match_m128d(_mm512_extractf64x2_pd(((__m512d){
- 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0
- }), 3),
+TEST_CONSTEXPR(match_m128d(_mm512_extractf64x2_pd(
+ ((__m512d){0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0}), 3),
6.0, 7.0));
__m128d test_mm512_mask_extractf64x2_pd(__m128d __W, __mmask8 __U, __m512d __A) {
@@ -1456,9 +1455,9 @@ __m128d test_mm512_mask_extractf64x2_pd(__m128d __W, __mmask8 __U, __m512d __A)
return _mm512_mask_extractf64x2_pd(__W, __U, __A, 3);
}
TEST_CONSTEXPR(match_m128d(_mm512_mask_extractf64x2_pd(
- (__m128d){100.0, 101.0}, // W(merge)
- (__mmask8)0x1, // 0000 0001b
- (__m512d){0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0},
+ ((__m128d)(__v2df){100.0, 101.0}), // W(merge)
+ (__mmask8)0x1,
+ ((__m512d)(__v8df){0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0}),
3),
6.0, 101.0));
@@ -1469,8 +1468,8 @@ __m128d test_mm512_maskz_extractf64x2_pd(__mmask8 __U, __m512d __A) {
return _mm512_maskz_extractf64x2_pd(__U, __A, 3);
}
TEST_CONSTEXPR(match_m128d(_mm512_maskz_extractf64x2_pd(
- (__mmask8)0x2, // 0000 0010b
- (__m512d){0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0},
+ (__mmask8)0x2,
+ ((__m512d){0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0}),
3),
0.0, 7.0));
@@ -1479,9 +1478,8 @@ __m256i test_mm512_extracti32x8_epi32(__m512i __A) {
// CHECK: shufflevector <16 x i32> %{{.*}}, <16 x i32> poison, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
return _mm512_extracti32x8_epi32(__A, 1);
}
-TEST_CONSTEXPR(match_m256i(_mm512_extracti32x8_epi32(((__m512i){
- 0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15
- }), 1),
+TEST_CONSTEXPR(match_v8si(_mm512_extracti32x8_epi32(
+ ((__m512i)(__v16si){0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}), 1),
8, 9,10,11,12,13,14,15));
__m256i test_mm512_mask_extracti32x8_epi32(__m256i __W, __mmask8 __U, __m512i __A) {
@@ -1490,12 +1488,11 @@ __m256i test_mm512_mask_extracti32x8_epi32(__m256i __W, __mmask8 __U, __m512i __
// CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm512_mask_extracti32x8_epi32(__W, __U, __A, 1);
}
-TEST_CONSTEXPR(match_m256i(_mm512_mask_extracti32x8_epi32(
- (__m256i){100,101,102,103,104,105,106,107}, // W(merge)
- (__mmask8)0xAA, // 1010 1010b → only odd lanetake
- (__m512i){ 0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15 },
+TEST_CONSTEXPR(match_v8si(_mm512_mask_extracti32x8_epi32(
+ ((__m256i)(__v8si){100,101,102,103,104,105,106,107}),
+ (__mmask8)0xAA,
+ ((__m512i)(__v16si){0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}),
1),
- // lane0..7: 8,9,10,11,12,13,14,15
100, 9, 102, 11, 104, 13, 106, 15));
__m256i test_mm512_maskz_extracti32x8_epi32(__mmask8 __U, __m512i __A) {
@@ -1504,9 +1501,9 @@ __m256i test_mm512_maskz_extracti32x8_epi32(__mmask8 __U, __m512i __A) {
// CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm512_maskz_extracti32x8_epi32(__U, __A, 1);
}
-TEST_CONSTEXPR(match_m256i(_mm512_maskz_extracti32x8_epi32(
- (__mmask8)0x0F,
- (__m512i){ 0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15 },
+TEST_CONSTEXPR(match_v8si(_mm512_maskz_extracti32x8_epi32(
+ (__mmask8)0x0F,
+ ((__m512i)(__v16si){0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}),
1),
8, 9, 10, 11, 0, 0, 0, 0));
@@ -1515,9 +1512,8 @@ __m128i test_mm512_extracti64x2_epi64(__m512i __A) {
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> poison, <2 x i32> <i32 6, i32 7>
return _mm512_extracti64x2_epi64(__A, 3);
}
-TEST_CONSTEXPR(match_m128i_64(_mm512_extracti64x2_epi64(((__m512i){
- 0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL
- }), 3),
+TEST_CONSTEXPR(match_m128i(_mm512_extracti64x2_epi64(
+ ((__m512i)(__v8di){0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL}), 3),
6ULL, 7ULL));
__m128i test_mm512_mask_extracti64x2_epi64(__m128i __W, __mmask8 __U, __m512i __A) {
@@ -1526,10 +1522,10 @@ __m128i test_mm512_mask_extracti64x2_epi64(__m128i __W, __mmask8 __U, __m512i __
// CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
return _mm512_mask_extracti64x2_epi64(__W, __U, __A, 3);
}
-TEST_CONSTEXPR(match_m128i_64(_mm512_mask_extracti64x2_epi64(
- (__m128i){100ULL, 101ULL}, // W(merge)
- (__mmask8)0x1, // lane0만 take
- (__m512i){0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL},
+TEST_CONSTEXPR(match_m128i(_mm512_mask_extracti64x2_epi64(
+ ((__m128i)(__v2di){100ULL, 101ULL}),
+ (__mmask8)0x1,
+ ((__m512i)(__v8di){0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL}),
3),
6ULL, 101ULL));
@@ -1539,11 +1535,11 @@ __m128i test_mm512_maskz_extracti64x2_epi64(__mmask8 __U, __m512i __A) {
// CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
return _mm512_maskz_extracti64x2_epi64(__U, __A, 3);
}
-TEST_CONSTEXPR(match_m128i_64(_mm512_maskz_extracti64x2_epi64(
- (__mmask8)0x2, // lane1 take, lane0 0
- (__m512i){0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL},
+TEST_CONSTEXPR(match_m128i(_mm512_maskz_extracti64x2_epi64(
+ (__mmask8)0x2,
+ ((__m512i)(__v8di){0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL}),
3),
- 0ULL, 7ULL));
+ 0ULL, 7ULL))
__m512 test_mm512_insertf32x8(__m512 __A, __m256 __B) {
// CHECK-LABEL: test_mm512_insertf32x8
>From a62a91fc6a1983afcddbb74cf69312f121a1d99f Mon Sep 17 00:00:00 2001
From: seongjaep <psjj960507 at gmail.com>
Date: Sun, 28 Sep 2025 18:53:45 +0900
Subject: [PATCH 13/21] no mask version test
---
clang/test/CodeGen/X86/avx512dq-builtins.c | 40 +++++++++++-----------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/clang/test/CodeGen/X86/avx512dq-builtins.c b/clang/test/CodeGen/X86/avx512dq-builtins.c
index 5a61040db9ef3..e9f344b240329 100644
--- a/clang/test/CodeGen/X86/avx512dq-builtins.c
+++ b/clang/test/CodeGen/X86/avx512dq-builtins.c
@@ -1402,11 +1402,11 @@ __m256 test_mm512_extractf32x8_ps(__m512 __A) {
// CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> poison, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
return _mm512_extractf32x8_ps(__A, 1);
}
-TEST_CONSTEXPR(match_m256(_mm512_extractf32x8_ps(((__m512){
- 0.0f,1.0f,2.0f,3.0f, 4.0f,5.0f,6.0f,7.0f,
- 8.0f,9.0f,10.0f,11.0f, 12.0f,13.0f,14.0f,15.0f
- }), 1),
- 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f));
+// TEST_CONSTEXPR(match_m256(_mm512_extractf32x8_ps(((__m512){
+// 0.0f,1.0f,2.0f,3.0f, 4.0f,5.0f,6.0f,7.0f,
+// 8.0f,9.0f,10.0f,11.0f, 12.0f,13.0f,14.0f,15.0f
+// }), 1),
+// 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f));
__m256 test_mm512_mask_extractf32x8_ps(__m256 __W, __mmask8 __U, __m512 __A) {
// CHECK-LABEL: test_mm512_mask_extractf32x8_ps
@@ -1444,9 +1444,9 @@ __m128d test_mm512_extractf64x2_pd(__m512d __A) {
// CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> poison, <2 x i32> <i32 6, i32 7>
return _mm512_extractf64x2_pd(__A, 3);
}
-TEST_CONSTEXPR(match_m128d(_mm512_extractf64x2_pd(
- ((__m512d){0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0}), 3),
- 6.0, 7.0));
+// TEST_CONSTEXPR(match_m128d(_mm512_extractf64x2_pd(
+// ((__m512d){0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0}), 3),
+// 6.0, 7.0));
__m128d test_mm512_mask_extractf64x2_pd(__m128d __W, __mmask8 __U, __m512d __A) {
// CHECK-LABEL: test_mm512_mask_extractf64x2_pd
@@ -1478,9 +1478,9 @@ __m256i test_mm512_extracti32x8_epi32(__m512i __A) {
// CHECK: shufflevector <16 x i32> %{{.*}}, <16 x i32> poison, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
return _mm512_extracti32x8_epi32(__A, 1);
}
-TEST_CONSTEXPR(match_v8si(_mm512_extracti32x8_epi32(
- ((__m512i)(__v16si){0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}), 1),
- 8, 9,10,11,12,13,14,15));
+// TEST_CONSTEXPR(match_v8si(_mm512_extracti32x8_epi32(
+// ((__m512i)(__v16si){0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}), 1),
+// 8, 9,10,11,12,13,14,15));
__m256i test_mm512_mask_extracti32x8_epi32(__m256i __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: test_mm512_mask_extracti32x8_epi32
@@ -1501,20 +1501,20 @@ __m256i test_mm512_maskz_extracti32x8_epi32(__mmask8 __U, __m512i __A) {
// CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm512_maskz_extracti32x8_epi32(__U, __A, 1);
}
-TEST_CONSTEXPR(match_v8si(_mm512_maskz_extracti32x8_epi32(
- (__mmask8)0x0F,
- ((__m512i)(__v16si){0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}),
- 1),
- 8, 9, 10, 11, 0, 0, 0, 0));
+// TEST_CONSTEXPR(match_v8si(_mm512_maskz_extracti32x8_epi32(
+// (__mmask8)0x0F,
+// ((__m512i)(__v16si){0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}),
+// 1),
+// 8, 9, 10, 11, 0, 0, 0, 0));
__m128i test_mm512_extracti64x2_epi64(__m512i __A) {
// CHECK-LABEL: test_mm512_extracti64x2_epi64
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> poison, <2 x i32> <i32 6, i32 7>
return _mm512_extracti64x2_epi64(__A, 3);
}
-TEST_CONSTEXPR(match_m128i(_mm512_extracti64x2_epi64(
- ((__m512i)(__v8di){0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL}), 3),
- 6ULL, 7ULL));
+// TEST_CONSTEXPR(match_m128i(_mm512_extracti64x2_epi64(
+// ((__m512i)(__v8di){0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL}), 3),
+// 6ULL, 7ULL));
__m128i test_mm512_mask_extracti64x2_epi64(__m128i __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: test_mm512_mask_extracti64x2_epi64
@@ -1539,7 +1539,7 @@ TEST_CONSTEXPR(match_m128i(_mm512_maskz_extracti64x2_epi64(
(__mmask8)0x2,
((__m512i)(__v8di){0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL}),
3),
- 0ULL, 7ULL))
+ 0ULL, 7ULL));
__m512 test_mm512_insertf32x8(__m512 __A, __m256 __B) {
// CHECK-LABEL: test_mm512_insertf32x8
>From 757c65027154b7487bf2efe67943cf67163588a2 Mon Sep 17 00:00:00 2001
From: SeongjaeP <psjj960507 at gmail.com>
Date: Mon, 29 Sep 2025 15:54:18 +0900
Subject: [PATCH 14/21] fix for test undefined -> setzero
---
clang/lib/Headers/avx512dqintrin.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Headers/avx512dqintrin.h b/clang/lib/Headers/avx512dqintrin.h
index fb65bf933b8ad..0ff776b36436e 100644
--- a/clang/lib/Headers/avx512dqintrin.h
+++ b/clang/lib/Headers/avx512dqintrin.h
@@ -1214,7 +1214,7 @@ _mm512_maskz_broadcast_i64x2(__mmask8 __M, __m128i __A)
#define _mm512_extractf32x8_ps(A, imm) \
((__m256)__builtin_ia32_extractf32x8_mask((__v16sf)(__m512)(A), (int)(imm), \
- (__v8sf)_mm256_undefined_ps(), \
+ (__v8sf)_mm256_setzero_ps(), \
(__mmask8)-1))
#define _mm512_mask_extractf32x8_ps(W, U, A, imm) \
@@ -1230,7 +1230,7 @@ _mm512_maskz_broadcast_i64x2(__mmask8 __M, __m128i __A)
#define _mm512_extractf64x2_pd(A, imm) \
((__m128d)__builtin_ia32_extractf64x2_512_mask((__v8df)(__m512d)(A), \
(int)(imm), \
- (__v2df)_mm_undefined_pd(), \
+ (__v2df)_mm_setzero_pd(), \
(__mmask8)-1))
#define _mm512_mask_extractf64x2_pd(W, U, A, imm) \
@@ -1247,7 +1247,7 @@ _mm512_maskz_broadcast_i64x2(__mmask8 __M, __m128i __A)
#define _mm512_extracti32x8_epi32(A, imm) \
((__m256i)__builtin_ia32_extracti32x8_mask((__v16si)(__m512i)(A), (int)(imm), \
- (__v8si)_mm256_undefined_si256(), \
+ (__v8si)_mm256_setzero_si256(), \
(__mmask8)-1))
#define _mm512_mask_extracti32x8_epi32(W, U, A, imm) \
@@ -1263,7 +1263,7 @@ _mm512_maskz_broadcast_i64x2(__mmask8 __M, __m128i __A)
#define _mm512_extracti64x2_epi64(A, imm) \
((__m128i)__builtin_ia32_extracti64x2_512_mask((__v8di)(__m512i)(A), \
(int)(imm), \
- (__v2di)_mm_undefined_si128(), \
+ (__v2di)_mm_setzero_si128(), \
(__mmask8)-1))
#define _mm512_mask_extracti64x2_epi64(W, U, A, imm) \
>From c9c36720fc1b6e87e5f61d665465c3c00d1ac7c0 Mon Sep 17 00:00:00 2001
From: SeongjaeP <psjj960507 at gmail.com>
Date: Mon, 29 Sep 2025 23:35:06 +0900
Subject: [PATCH 15/21] refactoring
---
clang/lib/AST/ByteCode/InterpBuiltin.cpp | 99 ++++++----------------
clang/lib/AST/ExprConstant.cpp | 60 ++++++-------
clang/test/CodeGen/X86/avx512dq-builtins.c | 38 ++++-----
3 files changed, 68 insertions(+), 129 deletions(-)
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 876868960a58c..fb909c678268f 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -2882,97 +2882,46 @@ static bool interp__builtin_x86_extract_vector(InterpState &S, CodePtr OpPC,
return true;
}
-// __builtin_extract_masked
static bool interp__builtin_x86_extract_vector_masked(InterpState &S, CodePtr OpPC,
const CallExpr *Call,
unsigned ID) {
- unsigned NumArgs = Call->getNumArgs();
-
- const Pointer &Dst = S.Stk.peek<Pointer>();
- if (!Dst.getFieldDesc()->isPrimitiveArray())
- return false;
-
- const Pointer *Merge = nullptr;
- uint64_t Kmask = 0;
- uint64_t Imm = 0;
- const Pointer *Src = nullptr;
-
- if (NumArgs == 4) {
- // __m256 _mm512_mask_extractf32x8_ps(W, U, A, imm)
- APSInt ImmAPS = popToAPSInt(S, Call->getArg(3));
- Imm = ImmAPS.getZExtValue();
-
- const Pointer &SrcP = S.Stk.pop<Pointer>();
- Src = &SrcP;
-
- APSInt KmaskAPS = popToAPSInt(S, Call->getArg(1));
- Kmask = KmaskAPS.getZExtValue();
+ assert(Call->getNumArgs() == 4);
- const Pointer &MergeP = S.Stk.pop<Pointer>();
- Merge = &MergeP;
-
- } else if (NumArgs == 3) {
- // __m256 _mm512_maskz_extractf32x8_ps(U, A, imm)
- APSInt ImmAPS = popToAPSInt(S, Call->getArg(2));
- Imm = ImmAPS.getZExtValue();
-
- const Pointer &SrcP = S.Stk.pop<Pointer>();
- Src = &SrcP;
-
- APSInt KmaskAPS = popToAPSInt(S, Call->getArg(0));
- Kmask = KmaskAPS.getZExtValue();
+ APSInt UAPS = popToAPSInt(S, Call->getArg(3));
+ const Pointer &W = S.Stk.pop<Pointer>();
+ APSInt ImmAPS = popToAPSInt(S, Call->getArg(1));
+ const Pointer &A = S.Stk.pop<Pointer>();
- Merge = nullptr; // maskz → zero fill
- } else {
+ if (!A.getFieldDesc()->isPrimitiveArray() || !W.getFieldDesc()->isPrimitiveArray())
return false;
- }
- if (!Src->getFieldDesc()->isPrimitiveArray())
+ const Pointer &Dst = S.Stk.peek<Pointer>();
+ if (!Dst.getFieldDesc()->isPrimitiveArray())
return false;
- unsigned SrcElems = Src->getNumElems();
+ unsigned SrcElems = A.getNumElems();
unsigned DstElems = Dst.getNumElems();
- if (SrcElems == 0 || DstElems == 0 || (SrcElems % DstElems) != 0)
+ if (!SrcElems || !DstElems || (SrcElems % DstElems) != 0)
return false;
- unsigned NumLanes = SrcElems / DstElems;
- unsigned Lane = static_cast<unsigned>(Imm % NumLanes);
- unsigned ExtractPos = Lane * DstElems;
-
- PrimType ElemPT = Src->getFieldDesc()->getPrimType();
- if (ElemPT != Dst.getFieldDesc()->getPrimType())
+ // 타입 일치 체크
+ PrimType PT = A.getFieldDesc()->getPrimType();
+ if (PT != Dst.getFieldDesc()->getPrimType() ||
+ PT != W.getFieldDesc()->getPrimType())
return false;
- // --- 여기서 fast-path 추가 ---
- unsigned UsedBits = std::min<unsigned>(DstElems, 64); // mask 폭 제한
- uint64_t AllOnes = (UsedBits == 64 ? ~0ull : ((1ull << UsedBits) - 1));
- bool MaskAll = (Kmask & AllOnes) == AllOnes;
+ unsigned numLanes = SrcElems / DstElems;
+ unsigned lane = static_cast<unsigned>(ImmAPS.getZExtValue() % numLanes);
+ unsigned base = lane * DstElems;
- if (MaskAll) {
- // merge는 무시, src에서 그대로 복사
- TYPE_SWITCH(ElemPT, {
- for (unsigned I = 0; I != DstElems; ++I)
- Dst.elem<T>(I) = Src->elem<T>(ExtractPos + I);
- });
- Dst.initializeAllElements();
- return true;
- }
- // --- fast-path 끝 ---
-
- auto storeZeroAt = [&](unsigned I) {
- TYPE_SWITCH(ElemPT, { Dst.elem<T>(I) = T{}; });
- };
+ uint64_t U = UAPS.getZExtValue();
- TYPE_SWITCH(ElemPT, {
- for (unsigned I = 0; I != DstElems; ++I) {
- bool Take = ((Kmask >> I) & 1) != 0;
- if (Take) {
- Dst.elem<T>(I) = Src->elem<T>(ExtractPos + I);
- } else if (Merge) {
- Dst.elem<T>(I) = Merge->elem<T>(I);
- } else {
- storeZeroAt(I);
- }
+ TYPE_SWITCH(PT, {
+ for (unsigned i = 0; i < DstElems; ++i) {
+ if ((U >> i) & 1)
+ Dst.elem<T>(i) = A.elem<T>(base + i);
+ else
+ Dst.elem<T>(i) = W.elem<T>(i);
}
});
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index ae559de42eada..36484fc8a2bcd 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -11968,49 +11968,39 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
case X86::BI__builtin_ia32_extracti64x2_256_mask:
case X86::BI__builtin_ia32_extractf64x2_256_mask:
case X86::BI__builtin_ia32_extracti64x2_512_mask:
- case X86::BI__builtin_ia32_extractf64x2_512_mask: {
- APValue SourceVec, SourceImm, SourceMerge, SourceKmask;
- if (!EvaluateAsRValue(Info, E->getArg(0), SourceVec) ||
- !EvaluateAsRValue(Info, E->getArg(1), SourceImm) ||
- !EvaluateAsRValue(Info, E->getArg(2), SourceMerge) ||
- !EvaluateAsRValue(Info, E->getArg(3), SourceKmask))
- return false;
+ case X86::BI__builtin_ia32_extractf64x2_512_mask:
+ case X86::BI__builtin_ia32_extractf64x4_mask:{
+ APValue A, W;
+ APSInt Imm, U;
+
+ if (!EvaluateAsRValue(Info, E->getArg(0), A) || // A
+ !EvaluateInteger(E->getArg(1), Imm, Info) || // imm
+ !EvaluateAsRValue(Info, E->getArg(2), W) || // W (merge)
+ !EvaluateInteger(E->getArg(3), U, Info)) // U (mask)
+ return false;
const auto *RetVT = E->getType()->castAs<VectorType>();
- QualType EltTy = RetVT->getElementType();
+ // QualType EltTy = RetVT->getElementType();
unsigned RetLen = RetVT->getNumElements();
- if (!SourceVec.isVector())
- return false;
- unsigned SrcLen = SourceVec.getVectorLength();
- if (SrcLen % RetLen != 0)
- return false;
-
- unsigned NumLanes = SrcLen / RetLen;
- unsigned idx = SourceImm.getInt().getZExtValue() & (NumLanes - 1);
-
- uint64_t KmaskBits = SourceKmask.getInt().getZExtValue();
-
- auto makeZeroInt = [&]() -> APValue {
- bool Uns = EltTy->isUnsignedIntegerOrEnumerationType();
- unsigned BW = Info.Ctx.getIntWidth(EltTy);
- return APValue(APSInt(APInt(BW, 0), Uns));
- };
+ if (!A.isVector() || !W.isVector()) return false;
+ unsigned SrcLen = A.getVectorLength();
+ if (!SrcLen || !RetLen || (SrcLen % RetLen) != 0) return false;
+
+ unsigned lanes = SrcLen / RetLen;
+ unsigned lane = static_cast<unsigned>(Imm.getZExtValue() % lanes);
+ unsigned base = lane * RetLen;
+ uint64_t K = U.getZExtValue();
SmallVector<APValue, 32> ResultElements;
ResultElements.reserve(RetLen);
- for (unsigned i = 0; i < RetLen; i++) {
- bool Take = (KmaskBits >> i) & 1;
- if (Take) {
- ResultElements.push_back(SourceVec.getVectorElt(idx * RetLen + i));
- } else {
-
- const APValue &MergeElt =
- SourceMerge.isVector() ? SourceMerge.getVectorElt(i) : makeZeroInt();
- ResultElements.push_back(MergeElt);
- }
+ for (unsigned i = 0; i < RetLen; ++i) {
+ if ((K >> i) & 1)
+ ResultElements.push_back(A.getVectorElt(base + i));
+ else
+ ResultElements.push_back(W.getVectorElt(i)); // maskz/unmasked 모두 헤더에서 맞춰줌
}
- return Success(APValue(ResultElements.data(), RetLen), E);
+ return Success(APValue(ResultElements.data(), ResultElements.size()), E);
}
diff --git a/clang/test/CodeGen/X86/avx512dq-builtins.c b/clang/test/CodeGen/X86/avx512dq-builtins.c
index e9f344b240329..f6ff1828cb41d 100644
--- a/clang/test/CodeGen/X86/avx512dq-builtins.c
+++ b/clang/test/CodeGen/X86/avx512dq-builtins.c
@@ -1402,11 +1402,11 @@ __m256 test_mm512_extractf32x8_ps(__m512 __A) {
// CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> poison, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
return _mm512_extractf32x8_ps(__A, 1);
}
-// TEST_CONSTEXPR(match_m256(_mm512_extractf32x8_ps(((__m512){
-// 0.0f,1.0f,2.0f,3.0f, 4.0f,5.0f,6.0f,7.0f,
-// 8.0f,9.0f,10.0f,11.0f, 12.0f,13.0f,14.0f,15.0f
-// }), 1),
-// 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f));
+TEST_CONSTEXPR(match_m256(_mm512_extractf32x8_ps(((__m512){
+ 0.0f,1.0f,2.0f,3.0f, 4.0f,5.0f,6.0f,7.0f,
+ 8.0f,9.0f,10.0f,11.0f, 12.0f,13.0f,14.0f,15.0f
+ }), 1),
+ 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f));
__m256 test_mm512_mask_extractf32x8_ps(__m256 __W, __mmask8 __U, __m512 __A) {
// CHECK-LABEL: test_mm512_mask_extractf32x8_ps
@@ -1444,9 +1444,9 @@ __m128d test_mm512_extractf64x2_pd(__m512d __A) {
// CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> poison, <2 x i32> <i32 6, i32 7>
return _mm512_extractf64x2_pd(__A, 3);
}
-// TEST_CONSTEXPR(match_m128d(_mm512_extractf64x2_pd(
-// ((__m512d){0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0}), 3),
-// 6.0, 7.0));
+TEST_CONSTEXPR(match_m128d(_mm512_extractf64x2_pd(
+ ((__m512d){0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0}), 3),
+ 6.0, 7.0));
__m128d test_mm512_mask_extractf64x2_pd(__m128d __W, __mmask8 __U, __m512d __A) {
// CHECK-LABEL: test_mm512_mask_extractf64x2_pd
@@ -1478,9 +1478,9 @@ __m256i test_mm512_extracti32x8_epi32(__m512i __A) {
// CHECK: shufflevector <16 x i32> %{{.*}}, <16 x i32> poison, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
return _mm512_extracti32x8_epi32(__A, 1);
}
-// TEST_CONSTEXPR(match_v8si(_mm512_extracti32x8_epi32(
-// ((__m512i)(__v16si){0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}), 1),
-// 8, 9,10,11,12,13,14,15));
+TEST_CONSTEXPR(match_v8si(_mm512_extracti32x8_epi32(
+ ((__m512i)(__v16si){0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}), 1),
+ 8, 9,10,11,12,13,14,15));
__m256i test_mm512_mask_extracti32x8_epi32(__m256i __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: test_mm512_mask_extracti32x8_epi32
@@ -1501,20 +1501,20 @@ __m256i test_mm512_maskz_extracti32x8_epi32(__mmask8 __U, __m512i __A) {
// CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}}
return _mm512_maskz_extracti32x8_epi32(__U, __A, 1);
}
-// TEST_CONSTEXPR(match_v8si(_mm512_maskz_extracti32x8_epi32(
-// (__mmask8)0x0F,
-// ((__m512i)(__v16si){0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}),
-// 1),
-// 8, 9, 10, 11, 0, 0, 0, 0));
+TEST_CONSTEXPR(match_v8si(_mm512_maskz_extracti32x8_epi32(
+ (__mmask8)0x0F,
+ ((__m512i)(__v16si){0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}),
+ 1),
+ 8, 9, 10, 11, 0, 0, 0, 0));
__m128i test_mm512_extracti64x2_epi64(__m512i __A) {
// CHECK-LABEL: test_mm512_extracti64x2_epi64
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> poison, <2 x i32> <i32 6, i32 7>
return _mm512_extracti64x2_epi64(__A, 3);
}
-// TEST_CONSTEXPR(match_m128i(_mm512_extracti64x2_epi64(
-// ((__m512i)(__v8di){0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL}), 3),
-// 6ULL, 7ULL));
+TEST_CONSTEXPR(match_m128i(_mm512_extracti64x2_epi64(
+ ((__m512i)(__v8di){0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL}), 3),
+ 6ULL, 7ULL));
__m128i test_mm512_mask_extracti64x2_epi64(__m128i __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: test_mm512_mask_extracti64x2_epi64
>From 69bf326ee3b64e0b8ca86ef79fca831ec3a1ea22 Mon Sep 17 00:00:00 2001
From: SeongjaeP <psjj960507 at gmail.com>
Date: Mon, 29 Sep 2025 23:51:58 +0900
Subject: [PATCH 16/21] Add _extracti64x4_mask
---
clang/lib/AST/ExprConstant.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 36484fc8a2bcd..a558a03589f9d 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -11969,6 +11969,7 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
case X86::BI__builtin_ia32_extractf64x2_256_mask:
case X86::BI__builtin_ia32_extracti64x2_512_mask:
case X86::BI__builtin_ia32_extractf64x2_512_mask:
+ case X86::BI__builtin_ia32_extracti64x4_mask:
case X86::BI__builtin_ia32_extractf64x4_mask:{
APValue A, W;
APSInt Imm, U;
>From 63c95b48ae865b7647ee945788b3875b16d96301 Mon Sep 17 00:00:00 2001
From: SeongjaeP <psjj960507 at gmail.com>
Date: Mon, 29 Sep 2025 23:52:50 +0900
Subject: [PATCH 17/21] refactoring and add test code
---
clang/lib/Headers/avx512fintrin.h | 8 +--
clang/test/CodeGen/X86/avx512f-builtins.c | 87 ++++++++++++-----------
2 files changed, 48 insertions(+), 47 deletions(-)
diff --git a/clang/lib/Headers/avx512fintrin.h b/clang/lib/Headers/avx512fintrin.h
index 80e58425cdd71..2768a5bae887d 100644
--- a/clang/lib/Headers/avx512fintrin.h
+++ b/clang/lib/Headers/avx512fintrin.h
@@ -3166,7 +3166,7 @@ _mm512_maskz_permutex2var_epi64(__mmask8 __U, __m512i __A, __m512i __I,
#define _mm512_extractf64x4_pd(A, I) \
((__m256d)__builtin_ia32_extractf64x4_mask((__v8df)(__m512d)(A), (int)(I), \
- (__v4df)_mm256_undefined_pd(), \
+ (__v4df)_mm256_setzero_pd(), \
(__mmask8)-1))
#define _mm512_mask_extractf64x4_pd(W, U, A, imm) \
@@ -3181,7 +3181,7 @@ _mm512_maskz_permutex2var_epi64(__mmask8 __U, __m512i __A, __m512i __I,
#define _mm512_extractf32x4_ps(A, I) \
((__m128)__builtin_ia32_extractf32x4_mask((__v16sf)(__m512)(A), (int)(I), \
- (__v4sf)_mm_undefined_ps(), \
+ (__v4sf)_mm_setzero_ps(), \
(__mmask8)-1))
#define _mm512_mask_extractf32x4_ps(W, U, A, imm) \
@@ -7107,7 +7107,7 @@ _mm512_mask_cvtepi64_storeu_epi16 (void *__P, __mmask8 __M, __m512i __A)
#define _mm512_extracti32x4_epi32(A, imm) \
((__m128i)__builtin_ia32_extracti32x4_mask((__v16si)(__m512i)(A), (int)(imm), \
- (__v4si)_mm_undefined_si128(), \
+ (__v4si)_mm_setzero_si128(), \
(__mmask8)-1))
#define _mm512_mask_extracti32x4_epi32(W, U, A, imm) \
@@ -7122,7 +7122,7 @@ _mm512_mask_cvtepi64_storeu_epi16 (void *__P, __mmask8 __M, __m512i __A)
#define _mm512_extracti64x4_epi64(A, imm) \
((__m256i)__builtin_ia32_extracti64x4_mask((__v8di)(__m512i)(A), (int)(imm), \
- (__v4di)_mm256_undefined_si256(), \
+ (__v4di)_mm256_setzero_si256(), \
(__mmask8)-1))
#define _mm512_mask_extracti64x4_epi64(W, U, A, imm) \
diff --git a/clang/test/CodeGen/X86/avx512f-builtins.c b/clang/test/CodeGen/X86/avx512f-builtins.c
index 26dcc0b35d0cb..e39ea5e962e5e 100644
--- a/clang/test/CodeGen/X86/avx512f-builtins.c
+++ b/clang/test/CodeGen/X86/avx512f-builtins.c
@@ -2452,11 +2452,9 @@ __m256d test_mm512_extractf64x4_pd(__m512d a)
// CHECK: shufflevector <8 x double> %{{.*}}, <8 x double> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
return _mm512_extractf64x4_pd(a, 1);
}
-TEST_CONSTEXPR(match_m256d(_mm512_extractf64x4_pd(((__m512d){
- 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0
- }), 1),
- 4.0, 5.0, 6.0, 7.0));
-
+TEST_CONSTEXPR(match_m256d(_mm512_extractf64x4_pd(((__m512d)
+{0.0,1.0,2.0,3.0, 4.0,5.0,6.0,7.0}),1),
+ 4.0, 5.0, 6.0, 7.0));
__m256d test_mm512_mask_extractf64x4_pd(__m256d __W,__mmask8 __U,__m512d __A){
// CHECK-LABEL: test_mm512_mask_extractf64x4_pd
@@ -2464,12 +2462,13 @@ __m256d test_mm512_mask_extractf64x4_pd(__m256d __W,__mmask8 __U,__m512d __A){
// CHECK: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
return _mm512_mask_extractf64x4_pd( __W, __U, __A, 1);
}
-TEST_CONSTEXPR(match_m256d(_mm512_mask_extractf64x4_pd(
- (__m256d){100.0,101.0,102.0,103.0}, // W(merge)
- (__mmask8)0x5, // 0101b
- (__m512d){0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0},
- 1),
- 4.0, 101.0, 6.0, 103.0));
+TEST_CONSTEXPR(match_m256d(
+ _mm512_mask_extractf64x4_pd(
+ ((__m256d){100.0,101.0,102.0,103.0}), // W (merge)
+ (__mmask8)0x5,
+ ((__m512d){0.0,1.0,2.0,3.0, 4.0,5.0,6.0,7.0}),
+ 1),
+ 4.0, 101.0, 6.0, 103.0));
__m256d test_mm512_maskz_extractf64x4_pd(__mmask8 __U,__m512d __A){
// CHECK-LABEL: test_mm512_maskz_extractf64x4_pd
@@ -2477,11 +2476,12 @@ __m256d test_mm512_maskz_extractf64x4_pd(__mmask8 __U,__m512d __A){
// CHECK: select <4 x i1> %{{.*}}, <4 x double> %{{.*}}, <4 x double> %{{.*}}
return _mm512_maskz_extractf64x4_pd( __U, __A, 1);
}
-TEST_CONSTEXPR(match_m256d(_mm512_maskz_extractf64x4_pd(
- (__mmask8)0x3,
- (__m512d){0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0},
- 1),
- 4.0, 5.0, 0.0, 0.0));
+TEST_CONSTEXPR(match_m256d(
+ _mm512_maskz_extractf64x4_pd(
+ (__mmask8)0x3,
+ ((__m512d){0.0,1.0,2.0,3.0, 4.0,5.0,6.0,7.0}),
+ 1),
+ 4.0, 5.0, 0.0, 0.0));
__m128 test_mm512_extractf32x4_ps(__m512 a)
{
@@ -2489,9 +2489,9 @@ __m128 test_mm512_extractf32x4_ps(__m512 a)
// CHECK: shufflevector <16 x float> %{{.*}}, <16 x float> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
return _mm512_extractf32x4_ps(a, 1);
}
-TEST_CONSTEXPR(match_m128(_mm512_extractf32x4_ps(((__m512){
- 0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15
- }), 1),
+TEST_CONSTEXPR(match_m128(_mm512_extractf32x4_ps(
+ ((__m512){0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}),
+ 1),
4.0f, 5.0f, 6.0f, 7.0f));
__m128 test_mm512_mask_extractf32x4_ps(__m128 __W, __mmask8 __U,__m512 __A){
@@ -2501,9 +2501,9 @@ __m128 test_mm512_mask_extractf32x4_ps(__m128 __W, __mmask8 __U,__m512 __A){
return _mm512_mask_extractf32x4_ps( __W, __U, __A, 1);
}
TEST_CONSTEXPR(match_m128(_mm512_mask_extractf32x4_ps(
- (__m128){100,101,102,103}, // W(merge)
- (__mmask8)0x5, // 0101b
- (__m512){0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15},
+ ((__m128){100,101,102,103}),
+ (__mmask8)0x5,
+ ((__m512){0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}),
1),
4.0f, 101.0f, 6.0f, 103.0f));
@@ -2515,7 +2515,7 @@ __m128 test_mm512_maskz_extractf32x4_ps( __mmask8 __U,__m512 __A){
}
TEST_CONSTEXPR(match_m128(_mm512_maskz_extractf32x4_ps(
(__mmask8)0x3,
- (__m512){0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15},
+ ((__m512){0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}),
1),
4.0f, 5.0f, 0.0f, 0.0f));
@@ -7078,10 +7078,11 @@ __m128i test_mm512_extracti32x4_epi32(__m512i __A) {
// CHECK: shufflevector <16 x i32> %{{.*}}, <16 x i32> poison, <4 x i32> <i32 12, i32 13, i32 14, i32 15>
return _mm512_extracti32x4_epi32(__A, 3);
}
-TEST_CONSTEXPR(match_m128i(_mm512_extracti32x4_epi32(((__m512i){
- 0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15
- }), 3),
- 12, 13, 14, 15));
+TEST_CONSTEXPR(match_m128i(_mm512_extracti32x4_epi32(((__m512i)(__v16si)
+ {0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15}), 3),
+ 0x0000000D0000000CULL, // (13<<32)|12
+ 0x0000000F0000000EULL
+ ));
__m128i test_mm512_mask_extracti32x4_epi32(__m128i __W, __mmask8 __U, __m512i __A) {
// CHECK-LABEL: test_mm512_mask_extracti32x4_epi32
@@ -7090,14 +7091,16 @@ __m128i test_mm512_mask_extracti32x4_epi32(__m128i __W, __mmask8 __U, __m512i __
return _mm512_mask_extracti32x4_epi32(__W, __U, __A, 3);
}
TEST_CONSTEXPR(match_m128i(_mm512_mask_extracti32x4_epi32(
- (__m128i){100,101,102,103}, // merge=W
+ ((__m128i)(__v4si){100,101,102,103}), // merge=W
(__mmask8)0x5, // 0101b
- (__m512i){
+ ((__m512i)(__v16si){
0,1,2,3, 4,5,6,7,
8,9,10,11, 12,13,14,15
- },
+ }),
3),
- 12, 101, 14, 103));
+ 0x000000650000000CULL, // (101<<32)|12
+ 0x000000670000000EULL // (103<<32)|14
+ ));
__m128i test_mm512_maskz_extracti32x4_epi32(__mmask8 __U, __m512i __A) {
// CHECK-LABEL: test_mm512_maskz_extracti32x4_epi32
@@ -7107,21 +7110,19 @@ __m128i test_mm512_maskz_extracti32x4_epi32(__mmask8 __U, __m512i __A) {
}
TEST_CONSTEXPR(match_m128i(_mm512_maskz_extracti32x4_epi32(
(__mmask8)0x3,
- (__m512i){
- 0,1,2,3, 4,5,6,7,
- 8,9,10,11, 12,13,14,15
- },
+ ((__m512i)(__v16si){0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}),
3),
-12, 13, 0, 0));
+ 0x0000000D0000000CULL, // (13<<32)|12
+ 0x0000000000000000ULL
+ ));
__m256i test_mm512_extracti64x4_epi64(__m512i __A) {
// CHECK-LABEL: test_mm512_extracti64x4_epi64
// CHECK: shufflevector <8 x i64> %{{.*}}, <8 x i64> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
return _mm512_extracti64x4_epi64(__A, 1);
}
-TEST_CONSTEXPR(match_m256i(_mm512_extracti64x4_epi64(((__m512i){
- 0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL
- }), 1),
+TEST_CONSTEXPR(match_m256i(
+ _mm512_extracti64x4_epi64(((__m512i)(__v8di){0,1,2,3,4,5,6,7}), 1),
4ULL, 5ULL, 6ULL, 7ULL));
__m256i test_mm512_mask_extracti64x4_epi64(__m256i __W, __mmask8 __U, __m512i __A) {
@@ -7130,10 +7131,10 @@ __m256i test_mm512_mask_extracti64x4_epi64(__m256i __W, __mmask8 __U, __m512i __
// CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}}
return _mm512_mask_extracti64x4_epi64(__W, __U, __A, 1);
}
-TEST_CONSTEXPR(match_m256i_64(_mm512_mask_extracti64x4_epi64(
- (__m256i){100ULL,101ULL,102ULL,103ULL},
+TEST_CONSTEXPR(match_m256i(_mm512_mask_extracti64x4_epi64(
+ ((__m256i)(__v4di){100ULL,101ULL,102ULL,103ULL}), // W
(__mmask8)0x5,
- (__m512i){0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL},
+ (((__m512i)(__v8di){0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL})),
1),
4ULL, 101ULL, 6ULL, 103ULL));
@@ -7145,7 +7146,7 @@ __m256i test_mm512_maskz_extracti64x4_epi64(__mmask8 __U, __m512i __A) {
}
TEST_CONSTEXPR(match_m256i(_mm512_maskz_extracti64x4_epi64(
(__mmask8)0x3,
- (__m512i){0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL},
+ (((__m512i)(__v8di){0ULL,1ULL,2ULL,3ULL, 4ULL,5ULL,6ULL,7ULL})),
1),
4ULL, 5ULL, 0ULL, 0ULL));
>From 3028c5fa2577d600feff43109330a49939168bbe Mon Sep 17 00:00:00 2001
From: SeongjaeP <psjj960507 at gmail.com>
Date: Tue, 30 Sep 2025 00:20:27 +0900
Subject: [PATCH 18/21] Add test and refactoring
---
clang/lib/Headers/avx512vldqintrin.h | 4 +-
clang/lib/Headers/avx512vlintrin.h | 4 +-
clang/test/CodeGen/X86/avx512vl-builtins.c | 64 +++++++++++---------
clang/test/CodeGen/X86/avx512vldq-builtins.c | 18 +++---
4 files changed, 48 insertions(+), 42 deletions(-)
diff --git a/clang/lib/Headers/avx512vldqintrin.h b/clang/lib/Headers/avx512vldqintrin.h
index 68bd52e43981a..2d3c4b551e3b0 100644
--- a/clang/lib/Headers/avx512vldqintrin.h
+++ b/clang/lib/Headers/avx512vldqintrin.h
@@ -1075,7 +1075,7 @@ _mm256_maskz_broadcast_i64x2 (__mmask8 __M, __m128i __A)
#define _mm256_extractf64x2_pd(A, imm) \
((__m128d)__builtin_ia32_extractf64x2_256_mask((__v4df)(__m256d)(A), \
(int)(imm), \
- (__v2df)_mm_undefined_pd(), \
+ (__v2df)_mm_setzero_pd(), \
(__mmask8)-1))
#define _mm256_mask_extractf64x2_pd(W, U, A, imm) \
@@ -1093,7 +1093,7 @@ _mm256_maskz_broadcast_i64x2 (__mmask8 __M, __m128i __A)
#define _mm256_extracti64x2_epi64(A, imm) \
((__m128i)__builtin_ia32_extracti64x2_256_mask((__v4di)(__m256i)(A), \
(int)(imm), \
- (__v2di)_mm_undefined_si128(), \
+ (__v2di)_mm_setzero_si128(), \
(__mmask8)-1))
#define _mm256_mask_extracti64x2_epi64(W, U, A, imm) \
diff --git a/clang/lib/Headers/avx512vlintrin.h b/clang/lib/Headers/avx512vlintrin.h
index 754f43ad88543..ab0aa6f0cde15 100644
--- a/clang/lib/Headers/avx512vlintrin.h
+++ b/clang/lib/Headers/avx512vlintrin.h
@@ -7622,7 +7622,7 @@ _mm256_mask_cvtepi64_storeu_epi16 (void * __P, __mmask8 __M, __m256i __A)
#define _mm256_extractf32x4_ps(A, imm) \
((__m128)__builtin_ia32_extractf32x4_256_mask((__v8sf)(__m256)(A), \
(int)(imm), \
- (__v4sf)_mm_undefined_ps(), \
+ (__v4sf)_mm_setzero_ps(), \
(__mmask8)-1))
#define _mm256_mask_extractf32x4_ps(W, U, A, imm) \
@@ -7640,7 +7640,7 @@ _mm256_mask_cvtepi64_storeu_epi16 (void * __P, __mmask8 __M, __m256i __A)
#define _mm256_extracti32x4_epi32(A, imm) \
((__m128i)__builtin_ia32_extracti32x4_256_mask((__v8si)(__m256i)(A), \
(int)(imm), \
- (__v4si)_mm_undefined_si128(), \
+ (__v4si)_mm_setzero_si128(), \
(__mmask8)-1))
#define _mm256_mask_extracti32x4_epi32(W, U, A, imm) \
diff --git a/clang/test/CodeGen/X86/avx512vl-builtins.c b/clang/test/CodeGen/X86/avx512vl-builtins.c
index b2de0d660b786..3aa42fda0620b 100644
--- a/clang/test/CodeGen/X86/avx512vl-builtins.c
+++ b/clang/test/CodeGen/X86/avx512vl-builtins.c
@@ -9520,9 +9520,8 @@ __m128 test_mm256_extractf32x4_ps(__m256 __A) {
// CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
return _mm256_extractf32x4_ps(__A, 1);
}
-TEST_CONSTEXPR(match_m128(_mm256_extractf32x4_ps(((__m256){
- 0,1,2,3, 4,5,6,7
- }), 1),
+TEST_CONSTEXPR(match_m128(
+ _mm256_extractf32x4_ps(((__m256){0,1,2,3, 4,5,6,7}), 1),
4.0f, 5.0f, 6.0f, 7.0f));
__m128 test_mm256_mask_extractf32x4_ps(__m128 __W, __mmask8 __U, __m256 __A) {
@@ -9531,12 +9530,13 @@ __m128 test_mm256_mask_extractf32x4_ps(__m128 __W, __mmask8 __U, __m256 __A) {
// CHECK: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
return _mm256_mask_extractf32x4_ps(__W, __U, __A, 1);
}
-TEST_CONSTEXPR( match_m128(_mm256_mask_extractf32x4_ps(
- (__m128){100,101,102,103}, // W (merge)
- (__mmask8)0x5, // 0101b
- (__m256){0,1,2,3, 4,5,6,7},
- 1),
- 4.0f, 101.0f, 6.0f, 103.0f));
+TEST_CONSTEXPR(match_m128(
+ _mm256_mask_extractf32x4_ps(
+ (((__m128){100,101,102,103})),
+ (__mmask8)0x5,
+ (((__m256){0,1,2,3, 4,5,6,7})),
+ 1),
+ 4.0f, 101.0f, 6.0f, 103.0f));
__m128 test_mm256_maskz_extractf32x4_ps(__mmask8 __U, __m256 __A) {
// CHECK-LABEL: test_mm256_maskz_extractf32x4_ps
@@ -9544,21 +9544,23 @@ __m128 test_mm256_maskz_extractf32x4_ps(__mmask8 __U, __m256 __A) {
// CHECK: select <4 x i1> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}
return _mm256_maskz_extractf32x4_ps(__U, __A, 1);
}
-TEST_CONSTEXPR(match_m128(_mm256_maskz_extractf32x4_ps(
- (__mmask8)0x3,
- (__m256){0,1,2,3, 4,5,6,7},
- 1),
- 4.0f, 5.0f, 0.0f, 0.0f));
+TEST_CONSTEXPR(match_m128(
+ _mm256_maskz_extractf32x4_ps(
+ (__mmask8)0x3,
+ (((__m256){0,1,2,3, 4,5,6,7})),
+ 1),
+ 4.0f, 5.0f, 0.0f, 0.0f));
__m128i test_mm256_extracti32x4_epi32(__m256i __A) {
// CHECK-LABEL: test_mm256_extracti32x4_epi32
// CHECK: shufflevector <8 x i32> %{{.*}}, <8 x i32> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
return _mm256_extracti32x4_epi32(__A, 1);
}
-TEST_CONSTEXPR(match_m128i(_mm256_extracti32x4_epi32(((__m256i){
- 0,1,2,3, 4,5,6,7
- }), 1),
- 4, 5, 6, 7));
+TEST_CONSTEXPR(match_m128i(
+ _mm256_extracti32x4_epi32(
+ (((__m256i)(__v8si){0,1,2,3, 4,5,6,7})), 1),
+ 0x0000000500000004ULL,
+ 0x0000000700000006ULL));
__m128i test_mm256_mask_extracti32x4_epi32(__m128i __W, __mmask8 __U, __m256i __A) {
// CHECK-LABEL: test_mm256_mask_extracti32x4_epi32
@@ -9566,12 +9568,14 @@ __m128i test_mm256_mask_extracti32x4_epi32(__m128i __W, __mmask8 __U, __m256i __
// CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm256_mask_extracti32x4_epi32(__W, __U, __A, 1);
}
-TEST_CONSTEXPR(match_m128i(_mm256_mask_extracti32x4_epi32(
- (__m128i){100,101,102,103}, // W (merge)
- (__mmask8)0xA, // 1010b
- (__m256i){0,1,2,3, 4,5,6,7},
- 1),
- 100, 5, 102, 7));
+TEST_CONSTEXPR(match_m128i(
+ _mm256_mask_extracti32x4_epi32(
+ (((__m128i)(__v4si){100,101,102,103})),
+ (__mmask8)0xA,
+ (((__m256i)(__v8si){0,1,2,3, 4,5,6,7})),
+ 1),
+ 0x0000000500000064ULL,
+ 0x0000000700000066ULL));
__m128i test_mm256_maskz_extracti32x4_epi32(__mmask8 __U, __m256i __A) {
// CHECK-LABEL: test_mm256_maskz_extracti32x4_epi32
@@ -9579,11 +9583,13 @@ __m128i test_mm256_maskz_extracti32x4_epi32(__mmask8 __U, __m256i __A) {
// CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}}
return _mm256_maskz_extracti32x4_epi32(__U, __A, 1);
}
-TEST_CONSTEXPR(match_m128i(_mm256_maskz_extracti32x4_epi32(
- (__mmask8)0x3,
- (__m256i){0,1,2,3, 4,5,6,7},
- 1),
- 4, 5, 0, 0));
+TEST_CONSTEXPR(match_m128i(
+ _mm256_maskz_extracti32x4_epi32(
+ (__mmask8)0x3,
+ (((__m256i)(__v8si){0,1,2,3, 4,5,6,7})),
+ 1),
+ 0x0000000500000004ULL,
+ 0x0000000000000000ULL));
__m256 test_mm256_insertf32x4(__m256 __A, __m128 __B) {
// CHECK-LABEL: test_mm256_insertf32x4
diff --git a/clang/test/CodeGen/X86/avx512vldq-builtins.c b/clang/test/CodeGen/X86/avx512vldq-builtins.c
index 9cfcfea3dafc7..d566363d1f291 100644
--- a/clang/test/CodeGen/X86/avx512vldq-builtins.c
+++ b/clang/test/CodeGen/X86/avx512vldq-builtins.c
@@ -1093,9 +1093,9 @@ __m128d test_mm256_mask_extractf64x2_pd(__m128d __W, __mmask8 __U, __m256d __A)
return _mm256_mask_extractf64x2_pd(__W, __U, __A, 1);
}
TEST_CONSTEXPR(match_m128d(_mm256_mask_extractf64x2_pd(
- (__m128d){100.0, 101.0}, // W(merge)
+ (((__m128d){100.0, 101.0})), // W(merge)
(__mmask8)0x1,
- (__m256d){0.0,1.0,2.0,3.0},
+ (((__m256d){0.0,1.0,2.0,3.0})),
1),
2.0, 101.0));
@@ -1107,7 +1107,7 @@ __m128d test_mm256_maskz_extractf64x2_pd(__mmask8 __U, __m256d __A) {
}
TEST_CONSTEXPR(match_m128d(_mm256_maskz_extractf64x2_pd(
(__mmask8)0x2,
- (__m256d){0.0,1.0,2.0,3.0},
+ (((__m256d){0.0,1.0,2.0,3.0})),
1),
0.0, 3.0));
@@ -1116,7 +1116,7 @@ __m128i test_mm256_extracti64x2_epi64(__m256i __A) {
// CHECK: shufflevector <4 x i64> %{{.*}}, <4 x i64> poison, <2 x i32> <i32 2, i32 3>
return _mm256_extracti64x2_epi64(__A, 1);
}
-TEST_CONSTEXPR(match_m128i_64(_mm256_extracti64x2_epi64(((__m256i){0ULL,1ULL,2ULL,3ULL}), 1),
+TEST_CONSTEXPR(match_m128i(_mm256_extracti64x2_epi64(((__m256i){0ULL,1ULL,2ULL,3ULL}), 1),
2ULL, 3ULL));
__m128i test_mm256_mask_extracti64x2_epi64(__m128i __W, __mmask8 __U, __m256i __A) {
@@ -1125,10 +1125,10 @@ __m128i test_mm256_mask_extracti64x2_epi64(__m128i __W, __mmask8 __U, __m256i __
// CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
return _mm256_mask_extracti64x2_epi64(__W, __U, __A, 1);
}
-TEST_CONSTEXPR(match_m128i_64(_mm256_mask_extracti64x2_epi64(
- (__m128i){100ULL, 101ULL}, // W(merge)
+TEST_CONSTEXPR(match_m128i(_mm256_mask_extracti64x2_epi64(
+ (((__m128i){100ULL, 101ULL})), // W(merge)
(__mmask8)0x1,
- (__m256i){0ULL,1ULL,2ULL,3ULL},
+ (((__m256i){0ULL,1ULL,2ULL,3ULL})),
1),
2ULL, 101ULL));
@@ -1138,9 +1138,9 @@ __m128i test_mm256_maskz_extracti64x2_epi64(__mmask8 __U, __m256i __A) {
// CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}}
return _mm256_maskz_extracti64x2_epi64(__U, __A, 1);
}
-TEST_CONSTEXPR(match_m128i_64(_mm256_maskz_extracti64x2_epi64(
+TEST_CONSTEXPR(match_m128i(_mm256_maskz_extracti64x2_epi64(
(__mmask8)0x2,
- (__m256i){0ULL,1ULL,2ULL,3ULL},
+ (((__m256i){0ULL,1ULL,2ULL,3ULL})),
1),
0ULL, 3ULL));
>From 1292451acc9ccda5c2c0fbb397708275f0863b5f Mon Sep 17 00:00:00 2001
From: SeongjaeP <psjj960507 at gmail.com>
Date: Wed, 1 Oct 2025 12:44:02 +0900
Subject: [PATCH 19/21] Remove unrelated test files from previous patch
---
.../test/SemaCXX/constexpr-avx-intrinsics.cpp | 54 -------------------
1 file changed, 54 deletions(-)
delete mode 100644 clang/test/SemaCXX/constexpr-avx-intrinsics.cpp
diff --git a/clang/test/SemaCXX/constexpr-avx-intrinsics.cpp b/clang/test/SemaCXX/constexpr-avx-intrinsics.cpp
deleted file mode 100644
index 0f2554a2f5d18..0000000000000
--- a/clang/test/SemaCXX/constexpr-avx-intrinsics.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 \
-// RUN: -target-feature +avx -target-feature +avx2 \
-// RUN: -fsyntax-only -verify %s
-// expected-no-diagnostics
-
-// 128/256bit vector type
-
-using v2i64 = long long __attribute__((vector_size(16))); // 2 x i64 = 128b
-using v4i64 = long long __attribute__((vector_size(32))); // 4 x i64 = 256b
-using v4f32 = float __attribute__((vector_size(16))); // 4 x f32 = 128b
-using v8f32 = float __attribute__((vector_size(32))); // 8 x f32 = 256b
-using v2f64 = double __attribute__((vector_size(16))); // 2 x f64 = 128b
-using v4f64 = double __attribute__((vector_size(32))); // 4 x f64 = 256b
-using v4i32 = int __attribute__((vector_size(16))); // 4 x i32 = 128b
-using v8i32 = int __attribute__((vector_size(32))); // 8 x i32 = 256b
-
-
-// source vectors (constexpr)
-constexpr v4i64 SRC_I64_256 = {10, 20, 30, 40};
-constexpr v8f32 SRC_F32_256 = {0, 1, 2, 3, 4, 5, 6, 7};
-constexpr v4f64 SRC_F64_256 = {1.1, 2.2, 3.3, 4.4};
-constexpr v8i32 SRC_I32_256 = {10, 20, 30, 40, 50, 60, 70, 80};
-
-// 1) __builtin_ia32_extract128i256 : 256비트 i64 벡터 -> 하위/상위 128비트 추출
-constexpr v2i64 R_EXTRACT_I128_0 = __builtin_ia32_extract128i256(SRC_I64_256, 0);
-static_assert(R_EXTRACT_I128_0[0] == 10 && R_EXTRACT_I128_0[1] == 20);
-
-constexpr v2i64 R_EXTRACT_I128_1 = __builtin_ia32_extract128i256(SRC_I64_256, 1);
-static_assert(R_EXTRACT_I128_1[0] == 30 && R_EXTRACT_I128_1[1] == 40);
-
-// // 2) __builtin_ia32_vextractf128_ps256 : 256비트 f32 -> 128비트 f32
-// constexpr v4f32 R_EXTRACT_F128_PS_0 = __builtin_ia32_vextractf128_ps256(SRC_F32_256, 0);
-// static_assert(R_EXTRACT_F128_PS_0[0] == 0 && R_EXTRACT_F128_PS_0[1] == 1 &&
-// R_EXTRACT_F128_PS_0[2] == 2 && R_EXTRACT_F128_PS_0[3] == 3);
-
-// constexpr v4f32 R_EXTRACT_F128_PS_1 = __builtin_ia32_vextractf128_ps256(SRC_F32_256, 1);
-// static_assert(R_EXTRACT_F128_PS_1[0] == 4 && R_EXTRACT_F128_PS_1[1] == 5 &&
-// R_EXTRACT_F128_PS_1[2] == 6 && R_EXTRACT_F128_PS_1[3] == 7);
-
-// // 3) __builtin_ia32_vextractf128_pd256 : 256비트 f64 -> 128비트 f64
-// constexpr v2f64 R_EXTRACT_F128_PD_0 = __builtin_ia32_vextractf128_pd256(SRC_F64_256, 0);
-// static_assert(R_EXTRACT_F128_PD_0[0] == 1.1 && R_EXTRACT_F128_PD_0[1] == 2.2);
-
-// constexpr v2f64 R_EXTRACT_F128_PD_1 = __builtin_ia32_vextractf128_pd256(SRC_F64_256, 1);
-// static_assert(R_EXTRACT_F128_PD_1[0] == 3.3 && R_EXTRACT_F128_PD_1[1] == 4.4);
-
-// // 4) __builtin_ia32_vextractf128_si256 : 256비트 i32 -> 128비트 i32
-// constexpr v4i32 R_EXTRACT_F128_SI256_0 = __builtin_ia32_vextractf128_si256(SRC_I32_256, 0);
-// static_assert(R_EXTRACT_F128_SI256_0[0] == 10 && R_EXTRACT_F128_SI256_0[1] == 20 &&
-// R_EXTRACT_F128_SI256_0[2] == 30 && R_EXTRACT_F128_SI256_0[3] == 40);
-
-// constexpr v4i32 R_EXTRACT_F128_SI256_1 = __builtin_ia32_vextractf128_si256(SRC_I32_256, 1);
-// static_assert(R_EXTRACT_F128_SI256_1[0] == 50 && R_EXTRACT_F128_SI256_1[1] == 60 &&
-// R_EXTRACT_F128_SI256_1[2] == 70 && R_EXTRACT_F128_SI256_1[3] == 80);
\ No newline at end of file
>From 427bd099f264e983a7c84f19cd237fa74d100503 Mon Sep 17 00:00:00 2001
From: SeongjaeP <psjj960507 at gmail.com>
Date: Mon, 6 Oct 2025 19:30:04 +0900
Subject: [PATCH 20/21] Remove comment
---
clang/lib/AST/ExprConstant.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index a558a03589f9d..b7c65c46b4721 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -11999,7 +11999,7 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
if ((K >> i) & 1)
ResultElements.push_back(A.getVectorElt(base + i));
else
- ResultElements.push_back(W.getVectorElt(i)); // maskz/unmasked 모두 헤더에서 맞춰줌
+ ResultElements.push_back(W.getVectorElt(i));
}
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
}
>From 499bb83beccb55edff973a34ad9d899ac5466546 Mon Sep 17 00:00:00 2001
From: SeongjaeP <psjj960507 at gmail.com>
Date: Thu, 9 Oct 2025 01:53:26 +0900
Subject: [PATCH 21/21] Refactor review comments and remove unrelated files
---
clang/lib/AST/ByteCode/InterpBuiltin.cpp | 45 ++++++++----------
clang/lib/AST/ExprConstant.cpp | 39 ++++++++-------
.../InstCombine/\bfold-nested-max.ll" | 12 -----
test.o | Bin 528 -> 0 bytes
4 files changed, 39 insertions(+), 57 deletions(-)
delete mode 100644 "llvm/test/Transforms/InstCombine/\bfold-nested-max.ll"
delete mode 100644 test.o
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index fb909c678268f..5f9f21f62c5fd 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -2843,16 +2843,13 @@ static bool interp__builtin_x86_extract_vector(InterpState &S, CodePtr OpPC,
unsigned ID) {
assert(Call->getNumArgs() == 2);
- // srcimm
APSInt ImmAPS = popToAPSInt(S, Call->getArg(1));
uint64_t Index = ImmAPS.getZExtValue();
- // srcvec
const Pointer &Src = S.Stk.pop<Pointer>();
if (!Src.getFieldDesc()->isPrimitiveArray())
return false;
- // destination (return value)
const Pointer &Dst = S.Stk.peek<Pointer>();
if (!Dst.getFieldDesc()->isPrimitiveArray())
return false;
@@ -2867,12 +2864,11 @@ static bool interp__builtin_x86_extract_vector(InterpState &S, CodePtr OpPC,
unsigned Lane = static_cast<unsigned>(Index % NumLanes);
unsigned ExtractPos = Lane * DstElems;
- // element type
- PrimType ElemPT = Src.getFieldDesc()->getPrimType();
- if (ElemPT != Dst.getFieldDesc()->getPrimType())
+ PrimType ElemT = Src.getFieldDesc()->getPrimType();
+ if (ElemT != Dst.getFieldDesc()->getPrimType())
return false;
- TYPE_SWITCH(ElemPT, {
+ TYPE_SWITCH(ElemT, {
for (unsigned I = 0; I != DstElems; ++I) {
Dst.elem<T>(I) = Src.elem<T>(ExtractPos + I);
}
@@ -2887,41 +2883,40 @@ static bool interp__builtin_x86_extract_vector_masked(InterpState &S, CodePtr Op
unsigned ID) {
assert(Call->getNumArgs() == 4);
- APSInt UAPS = popToAPSInt(S, Call->getArg(3));
- const Pointer &W = S.Stk.pop<Pointer>();
+ APSInt MaskAPS = popToAPSInt(S, Call->getArg(3));
+ const Pointer &Merge = S.Stk.pop<Pointer>();
APSInt ImmAPS = popToAPSInt(S, Call->getArg(1));
- const Pointer &A = S.Stk.pop<Pointer>();
+ const Pointer &Src = S.Stk.pop<Pointer>();
- if (!A.getFieldDesc()->isPrimitiveArray() || !W.getFieldDesc()->isPrimitiveArray())
+ if (!Src.getFieldDesc()->isPrimitiveArray() || !Merge.getFieldDesc()->isPrimitiveArray())
return false;
const Pointer &Dst = S.Stk.peek<Pointer>();
if (!Dst.getFieldDesc()->isPrimitiveArray())
return false;
- unsigned SrcElems = A.getNumElems();
+ unsigned SrcElems = Src.getNumElems();
unsigned DstElems = Dst.getNumElems();
if (!SrcElems || !DstElems || (SrcElems % DstElems) != 0)
return false;
- // 타입 일치 체크
- PrimType PT = A.getFieldDesc()->getPrimType();
- if (PT != Dst.getFieldDesc()->getPrimType() ||
- PT != W.getFieldDesc()->getPrimType())
+ PrimType ElemT = Src.getFieldDesc()->getPrimType();
+ if (ElemT != Dst.getFieldDesc()->getPrimType() ||
+ ElemT != Merge.getFieldDesc()->getPrimType())
return false;
- unsigned numLanes = SrcElems / DstElems;
- unsigned lane = static_cast<unsigned>(ImmAPS.getZExtValue() % numLanes);
- unsigned base = lane * DstElems;
+ unsigned NumLanes = SrcElems / DstElems;
+ unsigned Lane = static_cast<unsigned>(ImmAPS.getZExtValue() % NumLanes);
+ unsigned Base = Lane * DstElems;
- uint64_t U = UAPS.getZExtValue();
+ uint64_t Mask = MaskAPS.getZExtValue();
- TYPE_SWITCH(PT, {
- for (unsigned i = 0; i < DstElems; ++i) {
- if ((U >> i) & 1)
- Dst.elem<T>(i) = A.elem<T>(base + i);
+ TYPE_SWITCH(ElemT, {
+ for (unsigned I = 0; I < DstElems; ++I) {
+ if ((Mask >> I) & 1)
+ Dst.elem<T>(I) = Src.elem<T>(Base + I);
else
- Dst.elem<T>(i) = W.elem<T>(i);
+ Dst.elem<T>(I) = Merge.elem<T>(I);
}
});
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index b7c65c46b4721..d108a2883e6dd 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -11948,13 +11948,13 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
if (SrcLen != RetLen * 2)
return false;
- unsigned idx = SourceImm.getInt().getZExtValue() & 1;
+ unsigned Idx = SourceImm.getInt().getZExtValue() & 1;
SmallVector<APValue, 32> ResultElements;
ResultElements.reserve(RetLen);
- for (unsigned i = 0; i < RetLen; i++)
- ResultElements.push_back(SourceVec.getVectorElt(idx * RetLen + i));
+ for (unsigned I = 0; I < RetLen; I++)
+ ResultElements.push_back(SourceVec.getVectorElt(Idx * RetLen + I));
return Success(APValue(ResultElements.data(), RetLen), E);
}
@@ -11971,35 +11971,34 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
case X86::BI__builtin_ia32_extractf64x2_512_mask:
case X86::BI__builtin_ia32_extracti64x4_mask:
case X86::BI__builtin_ia32_extractf64x4_mask:{
- APValue A, W;
- APSInt Imm, U;
+ APValue SourceVec, MergeVec;
+ APSInt Imm, MaskImm;
- if (!EvaluateAsRValue(Info, E->getArg(0), A) || // A
- !EvaluateInteger(E->getArg(1), Imm, Info) || // imm
- !EvaluateAsRValue(Info, E->getArg(2), W) || // W (merge)
- !EvaluateInteger(E->getArg(3), U, Info)) // U (mask)
+ if (!EvaluateAsRValue(Info, E->getArg(0), SourceVec) ||
+ !EvaluateInteger(E->getArg(1), Imm, Info) ||
+ !EvaluateAsRValue(Info, E->getArg(2), MergeVec) ||
+ !EvaluateInteger(E->getArg(3), MaskImm, Info))
return false;
const auto *RetVT = E->getType()->castAs<VectorType>();
- // QualType EltTy = RetVT->getElementType();
unsigned RetLen = RetVT->getNumElements();
- if (!A.isVector() || !W.isVector()) return false;
- unsigned SrcLen = A.getVectorLength();
+ if (!SourceVec.isVector() || !MergeVec.isVector()) return false;
+ unsigned SrcLen = SourceVec.getVectorLength();
if (!SrcLen || !RetLen || (SrcLen % RetLen) != 0) return false;
- unsigned lanes = SrcLen / RetLen;
- unsigned lane = static_cast<unsigned>(Imm.getZExtValue() % lanes);
- unsigned base = lane * RetLen;
- uint64_t K = U.getZExtValue();
+ unsigned Lanes = SrcLen / RetLen;
+ unsigned Lane = static_cast<unsigned>(Imm.getZExtValue() % Lanes);
+ unsigned Base = Lane * RetLen;
+ uint64_t Mask = MaskImm.getZExtValue();
SmallVector<APValue, 32> ResultElements;
ResultElements.reserve(RetLen);
- for (unsigned i = 0; i < RetLen; ++i) {
- if ((K >> i) & 1)
- ResultElements.push_back(A.getVectorElt(base + i));
+ for (unsigned I = 0; I < RetLen; ++I) {
+ if ((Mask >> I) & 1)
+ ResultElements.push_back(SourceVec.getVectorElt(Base + I));
else
- ResultElements.push_back(W.getVectorElt(i));
+ ResultElements.push_back(MergeVec.getVectorElt(I));
}
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
}
diff --git "a/llvm/test/Transforms/InstCombine/\bfold-nested-max.ll" "b/llvm/test/Transforms/InstCombine/\bfold-nested-max.ll"
deleted file mode 100644
index 448365b64a169..0000000000000
--- "a/llvm/test/Transforms/InstCombine/\bfold-nested-max.ll"
+++ /dev/null
@@ -1,12 +0,0 @@
-; RUN: opt -passes=instcombine -S < %s | FileCheck %s
-
-define i64 @test1(i64 %x) {
- %1 = call i64 @llvm.umax.i64(i64 %x, i64 4)
- %2 = shl i64 %1, 1
- %3 = call i64 @llvm.umax.i64(i64 %2, i64 16)
- ret i64 %3
-}
-
-; CHECK-LABEL: @test1
-; CHECK: shl i64 %x, 1
-; CHECK: call i64 @llvm.umax.i64(i64 {{.*}}, i64 16)
\ No newline at end of file
diff --git a/test.o b/test.o
deleted file mode 100644
index 7198521f709c0b5851464db5012b25e0642d6660..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 528
zcmX^A>+L at t1_nk3AOI08K%4<$C;%}KNCNQ-Fbg|j0Tu25o4~*T<Ff<BL6`|DA0J<m
zT2TV!0IB%+5Z8zh1Rur{fighm!SsTKSQr{$YCv>+d~$wnL1J=Ad}&^JW?o8sypIdA
zyabe^0HqfI&0_|#4*+SXQ&EgJ0?L8(K;-xt7+8TA2tbNJ;wPZ`e*kF^pBsn+fEWZo
zYCssI7i0%H;BWQ*m4BHTCjR^XfBN6*gDVa&$6rG>2O2J*=)nL$d)WklqI at 6+Kmiw!
i<^wtk77idOek6Hd07e<7<>!|%<dozV7=lRypc()lI4qC=
More information about the llvm-commits
mailing list