[clang] [CIR] pmovdb512_mask, pmovdw512_mask, pmovqw512_mask (PR #213571)
Dao Bo Yang via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 20 22:09:52 PDT 2026
https://github.com/DannyDaoBoYang updated https://github.com/llvm/llvm-project/pull/213571
>From 84b95cc43e60cc7283c0a1aebdc153a7d67a0895 Mon Sep 17 00:00:00 2001
From: DannyDaoBoYang <34634047+DannyDaoBoYang at users.noreply.github.com>
Date: Sun, 2 Aug 2026 16:13:15 -0400
Subject: [PATCH 1/5] implement pmovdb512_mask, pmovdw512_mask, pmovqw512_mask
---
clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 3 ++
.../CodeGenBuiltins/X86/avx512f-builtins.c | 45 +++++++++++++++++++
2 files changed, 48 insertions(+)
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 9c98f4bc55daa..e4d838eacccb2 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -1871,7 +1871,10 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) {
return builder.createVecShuffle(getLoc(expr->getExprLoc()), ops[0], op1,
mask);
}
+ case X86::BI__builtin_ia32_pmovdb512_mask:
+ case X86::BI__builtin_ia32_pmovdw512_mask:
case X86::BI__builtin_ia32_pmovqd512_mask:
+ case X86::BI__builtin_ia32_pmovqw512_mask:
case X86::BI__builtin_ia32_pmovwb512_mask: {
mlir::Value Res =
builder.createIntCast(ops[0], cast<cir::VectorType>(ops[1].getType()));
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c b/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
index 819b0d3b2e17e..dcbffce413ba0 100644
--- a/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
+++ b/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
@@ -1066,6 +1066,51 @@ __m256i test_mm512_cvtepi64_epi32(__m512i __A) {
return _mm512_cvtepi64_epi32(__A);
}
+__m128i test_mm512_cvtepi32_epi8(__m512i a) {
+ // CIR-LABEL: test_mm512_cvtepi32_epi8
+ // CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} :
+ // CIR-SAME: !cir.vector<16 x !s32i> -> !cir.vector<16 x !s8i>
+ //
+ // LLVM-LABEL: test_mm512_cvtepi32_epi8
+ // LLVM: trunc <16 x i32> %{{.*}} to <16 x i8>
+ //
+ // OGCG-LABEL: test_mm512_cvtepi32_epi8
+ // OGCG: trunc <16 x i32> %{{.*}} to <16 x i8>
+ return _mm512_cvtepi32_epi8(a);
+}
+
+__m128i test_mm512_mask_cvtepi32_epi8(__m128i src, __mmask16 k,
+ __m512i a) {
+ // CIR-LABEL: test_mm512_mask_cvtepi32_epi8
+ // CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} :
+ // CIR-SAME: !cir.vector<16 x !s32i> -> !cir.vector<16 x !s8i>
+ // CIR: %[[MASK:.*]] = cir.cast bitcast {{.*}} :
+ // CIR-SAME: !u16i -> !cir.vector<16 x !cir.int<s, 1>>
+ // CIR: %[[SELECT:.*]] = cir.vec.ternary(%[[MASK]], %[[TRUNC]], {{.*}}) :
+ // CIR-SAME: !cir.vector<16 x !cir.int<s, 1>>,
+ // CIR-SAME: !cir.vector<16 x !s8i>
+ //
+ // LLVM-LABEL: test_mm512_mask_cvtepi32_epi8
+ // LLVM: %[[TRUNC:.*]] = trunc <16 x i32> %{{.*}} to <16 x i8>
+ // LLVM: %[[MASK:.*]] = bitcast i16 %{{.*}} to <16 x i1>
+ // LLVM: select <16 x i1> %[[MASK]], <16 x i8> %[[TRUNC]],
+ //
+ // OGCG-LABEL: test_mm512_mask_cvtepi32_epi8
+ // OGCG: call <16 x i8> @llvm.x86.avx512.mask.pmov.db.512
+ return _mm512_mask_cvtepi32_epi8(src, k, a);
+}
+
+__m128i test_mm512_maskz_cvtepi32_epi8(__mmask16 k, __m512i a) {
+ // CIR-LABEL: test_mm512_maskz_cvtepi32_epi8
+ // CIR: cir.call
+ //
+ // LLVM-LABEL: test_mm512_maskz_cvtepi32_epi8
+ // LLVM: trunc <16 x i32> %{{.*}} to <16 x i8>
+ // LLVM: bitcast i16 %{{.*}} to <16 x i1>
+ // LLVM: select <16 x i1>
+ return _mm512_maskz_cvtepi32_epi8(k, a);
+}
+
__m256i test_mm512_mask_cvtepi64_epi32(__m256i __O, __mmask8 __M, __m512i __A) {
// CIR-LABEL: test_mm512_mask_cvtepi64_epi32
// CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} : !cir.vector<8 x !s64i> -> !cir.vector<8 x !s32i>
>From ef947b88d9fc44c68a76598dbc8c59f613e095d1 Mon Sep 17 00:00:00 2001
From: DannyDaoBoYang <daobo.yang at mechanical-orchard.com>
Date: Sun, 2 Aug 2026 17:30:31 -0400
Subject: [PATCH 2/5] add more tests
---
.../CodeGenBuiltins/X86/avx512f-builtins.c | 135 ++++++++++++++++--
1 file changed, 125 insertions(+), 10 deletions(-)
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c b/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
index dcbffce413ba0..875355fa9c049 100644
--- a/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
+++ b/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
@@ -1049,7 +1049,7 @@ int test_mm512_kortestz(__mmask16 __A, __mmask16 __B) {
}
__m256i test_mm512_cvtepi64_epi32(__m512i __A) {
- // CIR-LABEL: test_mm512_cvtepi64_epi32
+ // CIR-LABEL: _mm512_cvtepi64_epi32
// CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} : !cir.vector<8 x !s64i> -> !cir.vector<8 x !s32i>
// CIR: %[[RETBC:.*]] = cir.cast bitcast {{.*}} : !cir.vector<8 x !s32i> -> !cir.vector<4 x !s64i>
// CIR: cir.store %[[RETBC]], %[[RETPTR:.*]] : !cir.vector<4 x !s64i>, !cir.ptr<!cir.vector<4 x !s64i>>
@@ -1067,8 +1067,8 @@ __m256i test_mm512_cvtepi64_epi32(__m512i __A) {
}
__m128i test_mm512_cvtepi32_epi8(__m512i a) {
- // CIR-LABEL: test_mm512_cvtepi32_epi8
- // CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} :
+ // CIR-LABEL: _mm512_cvtepi32_epi8
+ // CIR: cir.cast integral {{.*}} :
// CIR-SAME: !cir.vector<16 x !s32i> -> !cir.vector<16 x !s8i>
//
// LLVM-LABEL: test_mm512_cvtepi32_epi8
@@ -1081,12 +1081,12 @@ __m128i test_mm512_cvtepi32_epi8(__m512i a) {
__m128i test_mm512_mask_cvtepi32_epi8(__m128i src, __mmask16 k,
__m512i a) {
- // CIR-LABEL: test_mm512_mask_cvtepi32_epi8
+ // CIR-LABEL: _mm512_mask_cvtepi32_epi8
// CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} :
// CIR-SAME: !cir.vector<16 x !s32i> -> !cir.vector<16 x !s8i>
// CIR: %[[MASK:.*]] = cir.cast bitcast {{.*}} :
// CIR-SAME: !u16i -> !cir.vector<16 x !cir.int<s, 1>>
- // CIR: %[[SELECT:.*]] = cir.vec.ternary(%[[MASK]], %[[TRUNC]], {{.*}}) :
+ // CIR: cir.vec.ternary(%[[MASK]], %[[TRUNC]], {{.*}}) :
// CIR-SAME: !cir.vector<16 x !cir.int<s, 1>>,
// CIR-SAME: !cir.vector<16 x !s8i>
//
@@ -1101,16 +1101,131 @@ __m128i test_mm512_mask_cvtepi32_epi8(__m128i src, __mmask16 k,
}
__m128i test_mm512_maskz_cvtepi32_epi8(__mmask16 k, __m512i a) {
- // CIR-LABEL: test_mm512_maskz_cvtepi32_epi8
- // CIR: cir.call
+ // CIR-LABEL: _mm512_maskz_cvtepi32_epi8
+ // CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} :
+ // CIR-SAME: !cir.vector<16 x !s32i> -> !cir.vector<16 x !s8i>
+ // CIR: %[[MASK:.*]] = cir.cast bitcast {{.*}} :
+ // CIR-SAME: !u16i -> !cir.vector<16 x !cir.int<s, 1>>
+ // CIR: cir.vec.ternary(%[[MASK]], %[[TRUNC]], {{.*}}) :
+ // CIR-SAME: !cir.vector<16 x !cir.int<s, 1>>,
+ // CIR-SAME: !cir.vector<16 x !s8i>
//
// LLVM-LABEL: test_mm512_maskz_cvtepi32_epi8
- // LLVM: trunc <16 x i32> %{{.*}} to <16 x i8>
- // LLVM: bitcast i16 %{{.*}} to <16 x i1>
- // LLVM: select <16 x i1>
+ // LLVM: %[[TRUNC:.*]] = trunc <16 x i32> %{{.*}} to <16 x i8>
+ // LLVM: %[[MASK:.*]] = bitcast i16 %{{.*}} to <16 x i1>
+ // LLVM: select <16 x i1> %[[MASK]], <16 x i8> %[[TRUNC]],
+ //
+ // OGCG-LABEL: test_mm512_maskz_cvtepi32_epi8
+ // OGCG: call <16 x i8> @llvm.x86.avx512.mask.pmov.db.512
return _mm512_maskz_cvtepi32_epi8(k, a);
}
+__m256i test_mm512_cvtepi32_epi16(__m512i a) {
+ // CIR-LABEL: _mm512_cvtepi32_epi16
+ // CIR: cir.cast integral {{.*}} :
+ // CIR-SAME: !cir.vector<16 x !s32i> -> !cir.vector<16 x !s16i>
+ //
+ // LLVM-LABEL: test_mm512_cvtepi32_epi16
+ // LLVM: trunc <16 x i32> %{{.*}} to <16 x i16>
+ //
+ // OGCG-LABEL: test_mm512_cvtepi32_epi16
+ // OGCG: trunc <16 x i32> %{{.*}} to <16 x i16>
+ return _mm512_cvtepi32_epi16(a);
+}
+
+__m256i test_mm512_mask_cvtepi32_epi16(__m256i src, __mmask16 k, __m512i a) {
+ // CIR-LABEL: _mm512_mask_cvtepi32_epi16
+ // CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} :
+ // CIR-SAME: !cir.vector<16 x !s32i> -> !cir.vector<16 x !s16i>
+ // CIR: %[[MASK:.*]] = cir.cast bitcast {{.*}} :
+ // CIR-SAME: !u16i -> !cir.vector<16 x !cir.int<s, 1>>
+ // CIR: cir.vec.ternary(%[[MASK]], %[[TRUNC]], {{.*}}) :
+ // CIR-SAME: !cir.vector<16 x !cir.int<s, 1>>,
+ // CIR-SAME: !cir.vector<16 x !s16i>
+ //
+ // LLVM-LABEL: test_mm512_mask_cvtepi32_epi16
+ // LLVM: %[[TRUNC:.*]] = trunc <16 x i32> %{{.*}} to <16 x i16>
+ // LLVM: %[[MASK:.*]] = bitcast i16 %{{.*}} to <16 x i1>
+ // LLVM: select <16 x i1> %[[MASK]], <16 x i16> %[[TRUNC]],
+ //
+ // OGCG-LABEL: test_mm512_mask_cvtepi32_epi16
+ // OGCG: call <16 x i16> @llvm.x86.avx512.mask.pmov.dw.512
+ return _mm512_mask_cvtepi32_epi16(src, k, a);
+}
+
+__m256i test_mm512_maskz_cvtepi32_epi16(__mmask16 k, __m512i a) {
+ // CIR-LABEL: _mm512_maskz_cvtepi32_epi16
+ // CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} :
+ // CIR-SAME: !cir.vector<16 x !s32i> -> !cir.vector<16 x !s16i>
+ // CIR: %[[MASK:.*]] = cir.cast bitcast {{.*}} :
+ // CIR-SAME: !u16i -> !cir.vector<16 x !cir.int<s, 1>>
+ // CIR: cir.vec.ternary(%[[MASK]], %[[TRUNC]], {{.*}}) :
+ // CIR-SAME: !cir.vector<16 x !cir.int<s, 1>>,
+ // CIR-SAME: !cir.vector<16 x !s16i>
+ //
+ // LLVM-LABEL: test_mm512_maskz_cvtepi32_epi16
+ // LLVM: %[[TRUNC:.*]] = trunc <16 x i32> %{{.*}} to <16 x i16>
+ // LLVM: %[[MASK:.*]] = bitcast i16 %{{.*}} to <16 x i1>
+ // LLVM: select <16 x i1> %[[MASK]], <16 x i16> %[[TRUNC]],
+ //
+ // OGCG-LABEL: test_mm512_maskz_cvtepi32_epi16
+ // OGCG: call <16 x i16> @llvm.x86.avx512.mask.pmov.dw.512
+ return _mm512_maskz_cvtepi32_epi16(k, a);
+}
+
+__m128i test_mm512_cvtepi64_epi16(__m512i a) {
+ // CIR-LABEL: _mm512_cvtepi64_epi16
+ // CIR: cir.cast integral {{.*}} :
+ // CIR-SAME: !cir.vector<8 x !s64i> -> !cir.vector<8 x !s16i>
+ //
+ // LLVM-LABEL: test_mm512_cvtepi64_epi16
+ // LLVM: trunc <8 x i64> %{{.*}} to <8 x i16>
+ //
+ // OGCG-LABEL: test_mm512_cvtepi64_epi16
+ // OGCG: trunc <8 x i64> %{{.*}} to <8 x i16>
+ return _mm512_cvtepi64_epi16(a);
+}
+
+__m128i test_mm512_mask_cvtepi64_epi16(__m128i src, __mmask8 k, __m512i a) {
+ // CIR-LABEL: _mm512_mask_cvtepi64_epi16
+ // CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} :
+ // CIR-SAME: !cir.vector<8 x !s64i> -> !cir.vector<8 x !s16i>
+ // CIR: %[[MASK:.*]] = cir.cast bitcast {{.*}} :
+ // CIR-SAME: !u8i -> !cir.vector<8 x !cir.int<s, 1>>
+ // CIR: cir.vec.ternary(%[[MASK]], %[[TRUNC]], {{.*}}) :
+ // CIR-SAME: !cir.vector<8 x !cir.int<s, 1>>,
+ // CIR-SAME: !cir.vector<8 x !s16i>
+ //
+ // LLVM-LABEL: test_mm512_mask_cvtepi64_epi16
+ // LLVM: %[[TRUNC:.*]] = trunc <8 x i64> %{{.*}} to <8 x i16>
+ // LLVM: %[[MASK:.*]] = bitcast i8 %{{.*}} to <8 x i1>
+ // LLVM: select <8 x i1> %[[MASK]], <8 x i16> %[[TRUNC]],
+ //
+ // OGCG-LABEL: test_mm512_mask_cvtepi64_epi16
+ // OGCG: call <8 x i16> @llvm.x86.avx512.mask.pmov.qw.512
+ return _mm512_mask_cvtepi64_epi16(src, k, a);
+}
+
+__m128i test_mm512_maskz_cvtepi64_epi16(__mmask8 k, __m512i a) {
+ // CIR-LABEL: _mm512_maskz_cvtepi64_epi16
+ // CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} :
+ // CIR-SAME: !cir.vector<8 x !s64i> -> !cir.vector<8 x !s16i>
+ // CIR: %[[MASK:.*]] = cir.cast bitcast {{.*}} :
+ // CIR-SAME: !u8i -> !cir.vector<8 x !cir.int<s, 1>>
+ // CIR: cir.vec.ternary(%[[MASK]], %[[TRUNC]], {{.*}}) :
+ // CIR-SAME: !cir.vector<8 x !cir.int<s, 1>>,
+ // CIR-SAME: !cir.vector<8 x !s16i>
+ //
+ // LLVM-LABEL: test_mm512_maskz_cvtepi64_epi16
+ // LLVM: %[[TRUNC:.*]] = trunc <8 x i64> %{{.*}} to <8 x i16>
+ // LLVM: %[[MASK:.*]] = bitcast i8 %{{.*}} to <8 x i1>
+ // LLVM: select <8 x i1> %[[MASK]], <8 x i16> %[[TRUNC]],
+ //
+ // OGCG-LABEL: test_mm512_maskz_cvtepi64_epi16
+ // OGCG: call <8 x i16> @llvm.x86.avx512.mask.pmov.qw.512
+ return _mm512_maskz_cvtepi64_epi16(k, a);
+}
+
__m256i test_mm512_mask_cvtepi64_epi32(__m256i __O, __mmask8 __M, __m512i __A) {
// CIR-LABEL: test_mm512_mask_cvtepi64_epi32
// CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} : !cir.vector<8 x !s64i> -> !cir.vector<8 x !s32i>
>From 9ea7deb30290780316a092f59b0f30f8af29269f Mon Sep 17 00:00:00 2001
From: DannyDaoBoYang <daobo.yang at mechanical-orchard.com>
Date: Mon, 17 Aug 2026 00:38:35 -0400
Subject: [PATCH 3/5] Address review sugguestion to distinguish zero-musking
instead of using a wild card
---
.../test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c b/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
index 875355fa9c049..83a20d99b2439 100644
--- a/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
+++ b/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
@@ -1102,11 +1102,13 @@ __m128i test_mm512_mask_cvtepi32_epi8(__m128i src, __mmask16 k,
__m128i test_mm512_maskz_cvtepi32_epi8(__mmask16 k, __m512i a) {
// CIR-LABEL: _mm512_maskz_cvtepi32_epi8
+ // CIR: %[[ZERO:.*]] = cir.call @{{.*}}_mm_setzero_si128
+ // CIR: %[[ZERO_CAST:.*]] = cir.cast bitcast %[[ZERO]]
// CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} :
// CIR-SAME: !cir.vector<16 x !s32i> -> !cir.vector<16 x !s8i>
// CIR: %[[MASK:.*]] = cir.cast bitcast {{.*}} :
// CIR-SAME: !u16i -> !cir.vector<16 x !cir.int<s, 1>>
- // CIR: cir.vec.ternary(%[[MASK]], %[[TRUNC]], {{.*}}) :
+ // CIR: cir.vec.ternary(%[[MASK]], %[[TRUNC]], %[[ZERO_CAST]]) :
// CIR-SAME: !cir.vector<16 x !cir.int<s, 1>>,
// CIR-SAME: !cir.vector<16 x !s8i>
//
@@ -1155,11 +1157,13 @@ __m256i test_mm512_mask_cvtepi32_epi16(__m256i src, __mmask16 k, __m512i a) {
__m256i test_mm512_maskz_cvtepi32_epi16(__mmask16 k, __m512i a) {
// CIR-LABEL: _mm512_maskz_cvtepi32_epi16
+ // CIR: %[[ZERO:.*]] = cir.call @{{.*}}_mm256_setzero_si256
+ // CIR: %[[ZERO_CAST:.*]] = cir.cast bitcast %[[ZERO]]
// CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} :
// CIR-SAME: !cir.vector<16 x !s32i> -> !cir.vector<16 x !s16i>
// CIR: %[[MASK:.*]] = cir.cast bitcast {{.*}} :
// CIR-SAME: !u16i -> !cir.vector<16 x !cir.int<s, 1>>
- // CIR: cir.vec.ternary(%[[MASK]], %[[TRUNC]], {{.*}}) :
+ // CIR: cir.vec.ternary(%[[MASK]], %[[TRUNC]], %[[ZERO_CAST]]) :
// CIR-SAME: !cir.vector<16 x !cir.int<s, 1>>,
// CIR-SAME: !cir.vector<16 x !s16i>
//
@@ -1208,11 +1212,13 @@ __m128i test_mm512_mask_cvtepi64_epi16(__m128i src, __mmask8 k, __m512i a) {
__m128i test_mm512_maskz_cvtepi64_epi16(__mmask8 k, __m512i a) {
// CIR-LABEL: _mm512_maskz_cvtepi64_epi16
+ // CIR: %[[ZERO:.*]] = cir.call @{{.*}}_mm_setzero_si128
+ // CIR: %[[ZERO_CAST:.*]] = cir.cast bitcast %[[ZERO]]
// CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} :
// CIR-SAME: !cir.vector<8 x !s64i> -> !cir.vector<8 x !s16i>
// CIR: %[[MASK:.*]] = cir.cast bitcast {{.*}} :
// CIR-SAME: !u8i -> !cir.vector<8 x !cir.int<s, 1>>
- // CIR: cir.vec.ternary(%[[MASK]], %[[TRUNC]], {{.*}}) :
+ // CIR: cir.vec.ternary(%[[MASK]], %[[TRUNC]], %[[ZERO_CAST]]) :
// CIR-SAME: !cir.vector<8 x !cir.int<s, 1>>,
// CIR-SAME: !cir.vector<8 x !s16i>
//
>From 73704e76a0ec68495fea4e877a98f9527593f492 Mon Sep 17 00:00:00 2001
From: DannyDaoBoYang <daobo.yang at mechanical-orchard.com>
Date: Mon, 12 Oct 2026 17:07:31 -0400
Subject: [PATCH 4/5] Address review: Emit masked pmov intrinsic for
pmovdb/dw/qw512_mask to match OGCG
---
clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 31 ++++++-
.../CodeGenBuiltins/X86/avx512f-builtins.c | 90 +++++--------------
2 files changed, 52 insertions(+), 69 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index e0548aafd9bab..a0864fbdf2427 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -1874,16 +1874,41 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) {
return builder.createVecShuffle(getLoc(expr->getExprLoc()), ops[0], op1,
mask);
}
- case X86::BI__builtin_ia32_pmovdb512_mask:
- case X86::BI__builtin_ia32_pmovdw512_mask:
case X86::BI__builtin_ia32_pmovqd512_mask:
- case X86::BI__builtin_ia32_pmovqw512_mask:
case X86::BI__builtin_ia32_pmovwb512_mask: {
mlir::Value Res =
builder.createIntCast(ops[0], cast<cir::VectorType>(ops[1].getType()));
return emitX86Select(builder, getLoc(expr->getExprLoc()), ops[2], Res,
ops[1]);
}
+ case X86::BI__builtin_ia32_pmovdb512_mask:
+ case X86::BI__builtin_ia32_pmovdw512_mask:
+ case X86::BI__builtin_ia32_pmovqw512_mask: {
+ // These only require AVX512F, but a byte/word select would need AVX512BW,
+ // so use the masked intrinsic unless the mask is all ones.
+ mlir::Location loc = getLoc(expr->getExprLoc());
+ auto c = mlir::dyn_cast_or_null<cir::ConstantOp>(ops[2].getDefiningOp());
+ if (c && c.isAllOnesValue())
+ return builder.createIntCast(ops[0],
+ cast<cir::VectorType>(ops[1].getType()));
+
+ llvm::StringRef intrinsicName;
+ switch (builtinID) {
+ default:
+ llvm_unreachable("Unsupported intrinsic!");
+ case X86::BI__builtin_ia32_pmovdb512_mask:
+ intrinsicName = "x86.avx512.mask.pmov.db.512";
+ break;
+ case X86::BI__builtin_ia32_pmovdw512_mask:
+ intrinsicName = "x86.avx512.mask.pmov.dw.512";
+ break;
+ case X86::BI__builtin_ia32_pmovqw512_mask:
+ intrinsicName = "x86.avx512.mask.pmov.qw.512";
+ break;
+ }
+ return builder.emitIntrinsicCallOp(loc, intrinsicName, ops[1].getType(),
+ ops);
+ }
case X86::BI__builtin_ia32_pblendw128:
case X86::BI__builtin_ia32_blendpd:
case X86::BI__builtin_ia32_blendps:
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c b/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
index 83a20d99b2439..d1c07479f4c11 100644
--- a/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
+++ b/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
@@ -1082,21 +1082,14 @@ __m128i test_mm512_cvtepi32_epi8(__m512i a) {
__m128i test_mm512_mask_cvtepi32_epi8(__m128i src, __mmask16 k,
__m512i a) {
// CIR-LABEL: _mm512_mask_cvtepi32_epi8
- // CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} :
- // CIR-SAME: !cir.vector<16 x !s32i> -> !cir.vector<16 x !s8i>
- // CIR: %[[MASK:.*]] = cir.cast bitcast {{.*}} :
- // CIR-SAME: !u16i -> !cir.vector<16 x !cir.int<s, 1>>
- // CIR: cir.vec.ternary(%[[MASK]], %[[TRUNC]], {{.*}}) :
- // CIR-SAME: !cir.vector<16 x !cir.int<s, 1>>,
- // CIR-SAME: !cir.vector<16 x !s8i>
+ // CIR: cir.call_llvm_intrinsic "x86.avx512.mask.pmov.db.512" %{{.*}}, %{{.*}}, %{{.*}} :
+ // CIR-SAME: (!cir.vector<16 x !s32i>, !cir.vector<16 x !s8i>, !u16i) -> !cir.vector<16 x !s8i>
//
// LLVM-LABEL: test_mm512_mask_cvtepi32_epi8
- // LLVM: %[[TRUNC:.*]] = trunc <16 x i32> %{{.*}} to <16 x i8>
- // LLVM: %[[MASK:.*]] = bitcast i16 %{{.*}} to <16 x i1>
- // LLVM: select <16 x i1> %[[MASK]], <16 x i8> %[[TRUNC]],
+ // LLVM: call <16 x i8> @llvm.x86.avx512.mask.pmov.db.512(<16 x i32> %{{.*}}, <16 x i8> %{{.*}}, i16 %{{.*}})
//
// OGCG-LABEL: test_mm512_mask_cvtepi32_epi8
- // OGCG: call <16 x i8> @llvm.x86.avx512.mask.pmov.db.512
+ // OGCG: call <16 x i8> @llvm.x86.avx512.mask.pmov.db.512(<16 x i32> %{{.*}}, <16 x i8> %{{.*}}, i16 %{{.*}})
return _mm512_mask_cvtepi32_epi8(src, k, a);
}
@@ -1104,21 +1097,14 @@ __m128i test_mm512_maskz_cvtepi32_epi8(__mmask16 k, __m512i a) {
// CIR-LABEL: _mm512_maskz_cvtepi32_epi8
// CIR: %[[ZERO:.*]] = cir.call @{{.*}}_mm_setzero_si128
// CIR: %[[ZERO_CAST:.*]] = cir.cast bitcast %[[ZERO]]
- // CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} :
- // CIR-SAME: !cir.vector<16 x !s32i> -> !cir.vector<16 x !s8i>
- // CIR: %[[MASK:.*]] = cir.cast bitcast {{.*}} :
- // CIR-SAME: !u16i -> !cir.vector<16 x !cir.int<s, 1>>
- // CIR: cir.vec.ternary(%[[MASK]], %[[TRUNC]], %[[ZERO_CAST]]) :
- // CIR-SAME: !cir.vector<16 x !cir.int<s, 1>>,
- // CIR-SAME: !cir.vector<16 x !s8i>
+ // CIR: cir.call_llvm_intrinsic "x86.avx512.mask.pmov.db.512" %{{.*}}, %[[ZERO_CAST]], %{{.*}} :
+ // CIR-SAME: (!cir.vector<16 x !s32i>, !cir.vector<16 x !s8i>, !u16i) -> !cir.vector<16 x !s8i>
//
// LLVM-LABEL: test_mm512_maskz_cvtepi32_epi8
- // LLVM: %[[TRUNC:.*]] = trunc <16 x i32> %{{.*}} to <16 x i8>
- // LLVM: %[[MASK:.*]] = bitcast i16 %{{.*}} to <16 x i1>
- // LLVM: select <16 x i1> %[[MASK]], <16 x i8> %[[TRUNC]],
+ // LLVM: call <16 x i8> @llvm.x86.avx512.mask.pmov.db.512(<16 x i32> %{{.*}}, <16 x i8> %{{.*}}, i16 %{{.*}})
//
// OGCG-LABEL: test_mm512_maskz_cvtepi32_epi8
- // OGCG: call <16 x i8> @llvm.x86.avx512.mask.pmov.db.512
+ // OGCG: call <16 x i8> @llvm.x86.avx512.mask.pmov.db.512(<16 x i32> %{{.*}}, <16 x i8> %{{.*}}, i16 %{{.*}})
return _mm512_maskz_cvtepi32_epi8(k, a);
}
@@ -1137,21 +1123,14 @@ __m256i test_mm512_cvtepi32_epi16(__m512i a) {
__m256i test_mm512_mask_cvtepi32_epi16(__m256i src, __mmask16 k, __m512i a) {
// CIR-LABEL: _mm512_mask_cvtepi32_epi16
- // CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} :
- // CIR-SAME: !cir.vector<16 x !s32i> -> !cir.vector<16 x !s16i>
- // CIR: %[[MASK:.*]] = cir.cast bitcast {{.*}} :
- // CIR-SAME: !u16i -> !cir.vector<16 x !cir.int<s, 1>>
- // CIR: cir.vec.ternary(%[[MASK]], %[[TRUNC]], {{.*}}) :
- // CIR-SAME: !cir.vector<16 x !cir.int<s, 1>>,
- // CIR-SAME: !cir.vector<16 x !s16i>
+ // CIR: cir.call_llvm_intrinsic "x86.avx512.mask.pmov.dw.512" %{{.*}}, %{{.*}}, %{{.*}} :
+ // CIR-SAME: (!cir.vector<16 x !s32i>, !cir.vector<16 x !s16i>, !u16i) -> !cir.vector<16 x !s16i>
//
// LLVM-LABEL: test_mm512_mask_cvtepi32_epi16
- // LLVM: %[[TRUNC:.*]] = trunc <16 x i32> %{{.*}} to <16 x i16>
- // LLVM: %[[MASK:.*]] = bitcast i16 %{{.*}} to <16 x i1>
- // LLVM: select <16 x i1> %[[MASK]], <16 x i16> %[[TRUNC]],
+ // LLVM: call <16 x i16> @llvm.x86.avx512.mask.pmov.dw.512(<16 x i32> %{{.*}}, <16 x i16> %{{.*}}, i16 %{{.*}})
//
// OGCG-LABEL: test_mm512_mask_cvtepi32_epi16
- // OGCG: call <16 x i16> @llvm.x86.avx512.mask.pmov.dw.512
+ // OGCG: call <16 x i16> @llvm.x86.avx512.mask.pmov.dw.512(<16 x i32> %{{.*}}, <16 x i16> %{{.*}}, i16 %{{.*}})
return _mm512_mask_cvtepi32_epi16(src, k, a);
}
@@ -1159,21 +1138,14 @@ __m256i test_mm512_maskz_cvtepi32_epi16(__mmask16 k, __m512i a) {
// CIR-LABEL: _mm512_maskz_cvtepi32_epi16
// CIR: %[[ZERO:.*]] = cir.call @{{.*}}_mm256_setzero_si256
// CIR: %[[ZERO_CAST:.*]] = cir.cast bitcast %[[ZERO]]
- // CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} :
- // CIR-SAME: !cir.vector<16 x !s32i> -> !cir.vector<16 x !s16i>
- // CIR: %[[MASK:.*]] = cir.cast bitcast {{.*}} :
- // CIR-SAME: !u16i -> !cir.vector<16 x !cir.int<s, 1>>
- // CIR: cir.vec.ternary(%[[MASK]], %[[TRUNC]], %[[ZERO_CAST]]) :
- // CIR-SAME: !cir.vector<16 x !cir.int<s, 1>>,
- // CIR-SAME: !cir.vector<16 x !s16i>
+ // CIR: cir.call_llvm_intrinsic "x86.avx512.mask.pmov.dw.512" %{{.*}}, %[[ZERO_CAST]], %{{.*}} :
+ // CIR-SAME: (!cir.vector<16 x !s32i>, !cir.vector<16 x !s16i>, !u16i) -> !cir.vector<16 x !s16i>
//
// LLVM-LABEL: test_mm512_maskz_cvtepi32_epi16
- // LLVM: %[[TRUNC:.*]] = trunc <16 x i32> %{{.*}} to <16 x i16>
- // LLVM: %[[MASK:.*]] = bitcast i16 %{{.*}} to <16 x i1>
- // LLVM: select <16 x i1> %[[MASK]], <16 x i16> %[[TRUNC]],
+ // LLVM: call <16 x i16> @llvm.x86.avx512.mask.pmov.dw.512(<16 x i32> %{{.*}}, <16 x i16> %{{.*}}, i16 %{{.*}})
//
// OGCG-LABEL: test_mm512_maskz_cvtepi32_epi16
- // OGCG: call <16 x i16> @llvm.x86.avx512.mask.pmov.dw.512
+ // OGCG: call <16 x i16> @llvm.x86.avx512.mask.pmov.dw.512(<16 x i32> %{{.*}}, <16 x i16> %{{.*}}, i16 %{{.*}})
return _mm512_maskz_cvtepi32_epi16(k, a);
}
@@ -1192,21 +1164,14 @@ __m128i test_mm512_cvtepi64_epi16(__m512i a) {
__m128i test_mm512_mask_cvtepi64_epi16(__m128i src, __mmask8 k, __m512i a) {
// CIR-LABEL: _mm512_mask_cvtepi64_epi16
- // CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} :
- // CIR-SAME: !cir.vector<8 x !s64i> -> !cir.vector<8 x !s16i>
- // CIR: %[[MASK:.*]] = cir.cast bitcast {{.*}} :
- // CIR-SAME: !u8i -> !cir.vector<8 x !cir.int<s, 1>>
- // CIR: cir.vec.ternary(%[[MASK]], %[[TRUNC]], {{.*}}) :
- // CIR-SAME: !cir.vector<8 x !cir.int<s, 1>>,
- // CIR-SAME: !cir.vector<8 x !s16i>
+ // CIR: cir.call_llvm_intrinsic "x86.avx512.mask.pmov.qw.512" %{{.*}}, %{{.*}}, %{{.*}} :
+ // CIR-SAME: (!cir.vector<8 x !s64i>, !cir.vector<8 x !s16i>, !u8i) -> !cir.vector<8 x !s16i>
//
// LLVM-LABEL: test_mm512_mask_cvtepi64_epi16
- // LLVM: %[[TRUNC:.*]] = trunc <8 x i64> %{{.*}} to <8 x i16>
- // LLVM: %[[MASK:.*]] = bitcast i8 %{{.*}} to <8 x i1>
- // LLVM: select <8 x i1> %[[MASK]], <8 x i16> %[[TRUNC]],
+ // LLVM: call <8 x i16> @llvm.x86.avx512.mask.pmov.qw.512(<8 x i64> %{{.*}}, <8 x i16> %{{.*}}, i8 %{{.*}})
//
// OGCG-LABEL: test_mm512_mask_cvtepi64_epi16
- // OGCG: call <8 x i16> @llvm.x86.avx512.mask.pmov.qw.512
+ // OGCG: call <8 x i16> @llvm.x86.avx512.mask.pmov.qw.512(<8 x i64> %{{.*}}, <8 x i16> %{{.*}}, i8 %{{.*}})
return _mm512_mask_cvtepi64_epi16(src, k, a);
}
@@ -1214,21 +1179,14 @@ __m128i test_mm512_maskz_cvtepi64_epi16(__mmask8 k, __m512i a) {
// CIR-LABEL: _mm512_maskz_cvtepi64_epi16
// CIR: %[[ZERO:.*]] = cir.call @{{.*}}_mm_setzero_si128
// CIR: %[[ZERO_CAST:.*]] = cir.cast bitcast %[[ZERO]]
- // CIR: %[[TRUNC:.*]] = cir.cast integral {{.*}} :
- // CIR-SAME: !cir.vector<8 x !s64i> -> !cir.vector<8 x !s16i>
- // CIR: %[[MASK:.*]] = cir.cast bitcast {{.*}} :
- // CIR-SAME: !u8i -> !cir.vector<8 x !cir.int<s, 1>>
- // CIR: cir.vec.ternary(%[[MASK]], %[[TRUNC]], %[[ZERO_CAST]]) :
- // CIR-SAME: !cir.vector<8 x !cir.int<s, 1>>,
- // CIR-SAME: !cir.vector<8 x !s16i>
+ // CIR: cir.call_llvm_intrinsic "x86.avx512.mask.pmov.qw.512" %{{.*}}, %[[ZERO_CAST]], %{{.*}} :
+ // CIR-SAME: (!cir.vector<8 x !s64i>, !cir.vector<8 x !s16i>, !u8i) -> !cir.vector<8 x !s16i>
//
// LLVM-LABEL: test_mm512_maskz_cvtepi64_epi16
- // LLVM: %[[TRUNC:.*]] = trunc <8 x i64> %{{.*}} to <8 x i16>
- // LLVM: %[[MASK:.*]] = bitcast i8 %{{.*}} to <8 x i1>
- // LLVM: select <8 x i1> %[[MASK]], <8 x i16> %[[TRUNC]],
+ // LLVM: call <8 x i16> @llvm.x86.avx512.mask.pmov.qw.512(<8 x i64> %{{.*}}, <8 x i16> %{{.*}}, i8 %{{.*}})
//
// OGCG-LABEL: test_mm512_maskz_cvtepi64_epi16
- // OGCG: call <8 x i16> @llvm.x86.avx512.mask.pmov.qw.512
+ // OGCG: call <8 x i16> @llvm.x86.avx512.mask.pmov.qw.512(<8 x i64> %{{.*}}, <8 x i16> %{{.*}}, i8 %{{.*}})
return _mm512_maskz_cvtepi64_epi16(k, a);
}
>From 95467ed84935b425436af8a554d31e8db7c96a5f Mon Sep 17 00:00:00 2001
From: DannyDaoBoYang <daobo.yang at mechanical-orchard.com>
Date: Mon, 12 Oct 2026 17:09:17 -0400
Subject: [PATCH 5/5] address review
---
.../CodeGenBuiltins/X86/avx512f-builtins.c | 24 ++++++++++++++-----
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c b/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
index d1c07479f4c11..f088885e87738 100644
--- a/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
+++ b/clang/test/CIR/CodeGenBuiltins/X86/avx512f-builtins.c
@@ -1101,10 +1101,14 @@ __m128i test_mm512_maskz_cvtepi32_epi8(__mmask16 k, __m512i a) {
// CIR-SAME: (!cir.vector<16 x !s32i>, !cir.vector<16 x !s8i>, !u16i) -> !cir.vector<16 x !s8i>
//
// LLVM-LABEL: test_mm512_maskz_cvtepi32_epi8
- // LLVM: call <16 x i8> @llvm.x86.avx512.mask.pmov.db.512(<16 x i32> %{{.*}}, <16 x i8> %{{.*}}, i16 %{{.*}})
+ // LLVM: store <2 x i64> zeroinitializer
+ // LLVM: %[[ZERO:.*]] = bitcast <2 x i64> %{{.*}} to <16 x i8>
+ // LLVM: call <16 x i8> @llvm.x86.avx512.mask.pmov.db.512(<16 x i32> %{{.*}}, <16 x i8> %[[ZERO]], i16 %{{.*}})
//
// OGCG-LABEL: test_mm512_maskz_cvtepi32_epi8
- // OGCG: call <16 x i8> @llvm.x86.avx512.mask.pmov.db.512(<16 x i32> %{{.*}}, <16 x i8> %{{.*}}, i16 %{{.*}})
+ // OGCG: store <2 x i64> zeroinitializer
+ // OGCG: %[[ZERO:.*]] = bitcast <2 x i64> %{{.*}} to <16 x i8>
+ // OGCG: call <16 x i8> @llvm.x86.avx512.mask.pmov.db.512(<16 x i32> %{{.*}}, <16 x i8> %[[ZERO]], i16 %{{.*}})
return _mm512_maskz_cvtepi32_epi8(k, a);
}
@@ -1142,10 +1146,14 @@ __m256i test_mm512_maskz_cvtepi32_epi16(__mmask16 k, __m512i a) {
// CIR-SAME: (!cir.vector<16 x !s32i>, !cir.vector<16 x !s16i>, !u16i) -> !cir.vector<16 x !s16i>
//
// LLVM-LABEL: test_mm512_maskz_cvtepi32_epi16
- // LLVM: call <16 x i16> @llvm.x86.avx512.mask.pmov.dw.512(<16 x i32> %{{.*}}, <16 x i16> %{{.*}}, i16 %{{.*}})
+ // LLVM: store <4 x i64> zeroinitializer
+ // LLVM: %[[ZERO:.*]] = bitcast <4 x i64> %{{.*}} to <16 x i16>
+ // LLVM: call <16 x i16> @llvm.x86.avx512.mask.pmov.dw.512(<16 x i32> %{{.*}}, <16 x i16> %[[ZERO]], i16 %{{.*}})
//
// OGCG-LABEL: test_mm512_maskz_cvtepi32_epi16
- // OGCG: call <16 x i16> @llvm.x86.avx512.mask.pmov.dw.512(<16 x i32> %{{.*}}, <16 x i16> %{{.*}}, i16 %{{.*}})
+ // OGCG: store <4 x i64> zeroinitializer
+ // OGCG: %[[ZERO:.*]] = bitcast <4 x i64> %{{.*}} to <16 x i16>
+ // OGCG: call <16 x i16> @llvm.x86.avx512.mask.pmov.dw.512(<16 x i32> %{{.*}}, <16 x i16> %[[ZERO]], i16 %{{.*}})
return _mm512_maskz_cvtepi32_epi16(k, a);
}
@@ -1183,10 +1191,14 @@ __m128i test_mm512_maskz_cvtepi64_epi16(__mmask8 k, __m512i a) {
// CIR-SAME: (!cir.vector<8 x !s64i>, !cir.vector<8 x !s16i>, !u8i) -> !cir.vector<8 x !s16i>
//
// LLVM-LABEL: test_mm512_maskz_cvtepi64_epi16
- // LLVM: call <8 x i16> @llvm.x86.avx512.mask.pmov.qw.512(<8 x i64> %{{.*}}, <8 x i16> %{{.*}}, i8 %{{.*}})
+ // LLVM: store <2 x i64> zeroinitializer
+ // LLVM: %[[ZERO:.*]] = bitcast <2 x i64> %{{.*}} to <8 x i16>
+ // LLVM: call <8 x i16> @llvm.x86.avx512.mask.pmov.qw.512(<8 x i64> %{{.*}}, <8 x i16> %[[ZERO]], i8 %{{.*}})
//
// OGCG-LABEL: test_mm512_maskz_cvtepi64_epi16
- // OGCG: call <8 x i16> @llvm.x86.avx512.mask.pmov.qw.512(<8 x i64> %{{.*}}, <8 x i16> %{{.*}}, i8 %{{.*}})
+ // OGCG: store <2 x i64> zeroinitializer
+ // OGCG: %[[ZERO:.*]] = bitcast <2 x i64> %{{.*}} to <8 x i16>
+ // OGCG: call <8 x i16> @llvm.x86.avx512.mask.pmov.qw.512(<8 x i64> %{{.*}}, <8 x i16> %[[ZERO]], i8 %{{.*}})
return _mm512_maskz_cvtepi64_epi16(k, a);
}
More information about the cfe-commits
mailing list