[clang] [CIR][X86] Lower pmulhw/pmulhuw builtins to smulh/umulh (PR #231978)
Arseniy Obolenskiy via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 14 09:55:36 PDT 2026
https://github.com/aobolensk updated https://github.com/llvm/llvm-project/pull/231978
>From 9c660149450a674a156a9b3dd5ab5a47bd247a5b Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Wed, 14 Oct 2026 18:22:21 +0200
Subject: [PATCH] [CIR][X86] Lower pmulhw/pmulhuw builtins to smulh/umulh
The x86 pmulh intrinsics were removed in #227663, so CIR hit NYI on these builtins
---
clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 10 ++++++++
.../CIR/CodeGenBuiltins/X86/avx2-builtins.c | 24 +++++++++++++++++++
.../CodeGenBuiltins/X86/avx512bw-builtins.c | 24 +++++++++++++++++++
.../CIR/CodeGenBuiltins/X86/sse2-builtins.c | 24 +++++++++++++++++++
4 files changed, 82 insertions(+)
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index febcaa7459edb0..2bec45883554fc 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -2365,6 +2365,16 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) {
mlir::Value arg = ops[0];
return cir::SqrtOp::create(builder, loc, arg).getResult();
}
+ case X86::BI__builtin_ia32_pmulhw128:
+ case X86::BI__builtin_ia32_pmulhw256:
+ case X86::BI__builtin_ia32_pmulhw512:
+ return builder.emitIntrinsicCallOp(getLoc(expr->getExprLoc()), "smulh",
+ ops[0].getType(), ops);
+ case X86::BI__builtin_ia32_pmulhuw128:
+ case X86::BI__builtin_ia32_pmulhuw256:
+ case X86::BI__builtin_ia32_pmulhuw512:
+ return builder.emitIntrinsicCallOp(getLoc(expr->getExprLoc()), "umulh",
+ ops[0].getType(), ops);
case X86::BI__builtin_ia32_pmuludq128:
case X86::BI__builtin_ia32_pmuludq256:
case X86::BI__builtin_ia32_pmuludq512: {
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/avx2-builtins.c b/clang/test/CIR/CodeGenBuiltins/X86/avx2-builtins.c
index c6225d47671f2f..c5c807aaa5d7aa 100644
--- a/clang/test/CIR/CodeGenBuiltins/X86/avx2-builtins.c
+++ b/clang/test/CIR/CodeGenBuiltins/X86/avx2-builtins.c
@@ -176,6 +176,30 @@ __m256i test_mm256_mul_epi32(__m256i a, __m256i b) {
return _mm256_mul_epi32(a, b);
}
+__m256i test_mm256_mulhi_epi16(__m256i a, __m256i b) {
+ // CIR-LABEL: _mm256_mulhi_epi16
+ // CIR: cir.call_llvm_intrinsic "smulh" %{{.*}}, %{{.*}} : (!cir.vector<16 x !s16i>, !cir.vector<16 x !s16i>) -> !cir.vector<16 x !s16i>
+
+ // LLVM-LABEL: test_mm256_mulhi_epi16
+ // LLVM: call <16 x i16> @llvm.smulh.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}})
+
+ // OGCG-LABEL: test_mm256_mulhi_epi16
+ // OGCG: call <16 x i16> @llvm.smulh.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}})
+ return _mm256_mulhi_epi16(a, b);
+}
+
+__m256i test_mm256_mulhi_epu16(__m256i a, __m256i b) {
+ // CIR-LABEL: _mm256_mulhi_epu16
+ // CIR: cir.call_llvm_intrinsic "umulh" %{{.*}}, %{{.*}} : (!cir.vector<16 x !u16i>, !cir.vector<16 x !u16i>) -> !cir.vector<16 x !u16i>
+
+ // LLVM-LABEL: test_mm256_mulhi_epu16
+ // LLVM: call <16 x i16> @llvm.umulh.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}})
+
+ // OGCG-LABEL: test_mm256_mulhi_epu16
+ // OGCG: call <16 x i16> @llvm.umulh.v16i16(<16 x i16> %{{.*}}, <16 x i16> %{{.*}})
+ return _mm256_mulhi_epu16(a, b);
+}
+
__m256i test_mm256_alignr_epi8(__m256i a, __m256i b) {
// CIR-LABEL: _mm256_alignr_epi8
// CIR: {{.*}} = cir.vec.shuffle(%{{.*}}, {{.*}} : !cir.vector<32 x {{![us]8i}}>) [#cir.int<2> : !s32i, #cir.int<3> : !s32i, #cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : !s32i, #cir.int<8> : !s32i, #cir.int<9> : !s32i, #cir.int<10> : !s32i, #cir.int<11> : !s32i, #cir.int<12> : !s32i, #cir.int<13> : !s32i, #cir.int<14> : !s32i, #cir.int<15> : !s32i, #cir.int<32> : !s32i, #cir.int<33> : !s32i, #cir.int<18> : !s32i, #cir.int<19> : !s32i, #cir.int<20> : !s32i, #cir.int<21> : !s32i, #cir.int<22> : !s32i, #cir.int<23> : !s32i, #cir.int<24> : !s32i, #cir.int<25> : !s32i, #cir.int<26> : !s32i, #cir.int<27> : !s32i, #cir.int<28> : !s32i, #cir.int<29> : !s32i, #cir.int<30> : !s32i, #cir.int<31> : !s32i, #cir.int<48> : !s32i, #cir.int<49> : !s32i] : !cir.vector<32 x {{![us]8i}}>
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/avx512bw-builtins.c b/clang/test/CIR/CodeGenBuiltins/X86/avx512bw-builtins.c
index 525e703eabe2bd..6a872f4e9dccfa 100644
--- a/clang/test/CIR/CodeGenBuiltins/X86/avx512bw-builtins.c
+++ b/clang/test/CIR/CodeGenBuiltins/X86/avx512bw-builtins.c
@@ -866,6 +866,30 @@ __m256i test_mm512_maskz_cvtepi16_epi8(__mmask32 __M, __m512i __A) {
return _mm512_maskz_cvtepi16_epi8(__M, __A);
}
+__m512i test_mm512_mulhi_epi16(__m512i __A, __m512i __B) {
+ // CIR-LABEL: _mm512_mulhi_epi16
+ // CIR: cir.call_llvm_intrinsic "smulh" %{{.*}}, %{{.*}} : (!cir.vector<32 x !s16i>, !cir.vector<32 x !s16i>) -> !cir.vector<32 x !s16i>
+
+ // LLVM-LABEL: test_mm512_mulhi_epi16
+ // LLVM: call <32 x i16> @llvm.smulh.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}})
+
+ // OGCG-LABEL: test_mm512_mulhi_epi16
+ // OGCG: call <32 x i16> @llvm.smulh.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}})
+ return _mm512_mulhi_epi16(__A, __B);
+}
+
+__m512i test_mm512_mulhi_epu16(__m512i __A, __m512i __B) {
+ // CIR-LABEL: _mm512_mulhi_epu16
+ // CIR: cir.call_llvm_intrinsic "umulh" %{{.*}}, %{{.*}} : (!cir.vector<32 x !u16i>, !cir.vector<32 x !u16i>) -> !cir.vector<32 x !u16i>
+
+ // LLVM-LABEL: test_mm512_mulhi_epu16
+ // LLVM: call <32 x i16> @llvm.umulh.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}})
+
+ // OGCG-LABEL: test_mm512_mulhi_epu16
+ // OGCG: call <32 x i16> @llvm.umulh.v32i16(<32 x i16> %{{.*}}, <32 x i16> %{{.*}})
+ return _mm512_mulhi_epu16(__A, __B);
+}
+
__m512i test_mm512_alignr_epi8(__m512i __A,__m512i __B) {
// CIR-LABEL: _mm512_alignr_epi8
// CIR: %{{.*}} = cir.vec.shuffle(%{{.*}}, %{{.*}} : !cir.vector<64 x {{!s8i|!u8i}}>) [#cir.int<2> : !s32i, #cir.int<3> : !s32i, #cir.int<4> : !s32i, #cir.int<5> : !s32i, #cir.int<6> : !s32i, #cir.int<7> : !s32i, #cir.int<8> : !s32i, #cir.int<9> : !s32i, #cir.int<10> : !s32i, #cir.int<11> : !s32i, #cir.int<12> : !s32i, #cir.int<13> : !s32i, #cir.int<14> : !s32i, #cir.int<15> : !s32i, #cir.int<64> : !s32i, #cir.int<65> : !s32i, #cir.int<18> : !s32i, #cir.int<19> : !s32i, #cir.int<20> : !s32i, #cir.int<21> : !s32i, #cir.int<22> : !s32i, #cir.int<23> : !s32i, #cir.int<24> : !s32i, #cir.int<25> : !s32i, #cir.int<26> : !s32i, #cir.int<27> : !s32i, #cir.int<28> : !s32i, #cir.int<29> : !s32i, #cir.int<30> : !s32i, #cir.int<31> : !s32i, #cir.int<80> : !s32i, #cir.int<81> : !s32i, #cir.int<34> : !s32i, #cir.int<35> : !s32i, #cir.int<36> : !s32i, #cir.int<37> : !s32i, #cir.int<38> : !s32i, #cir.int<39> : !s32i, #cir.int<40> : !s32i, #cir.int<41> : !s32i, #cir.int<42> : !s32i, #cir.int<43> : !s32i, #cir.int<44> : !s32i, #cir.int<45> : !s32i, #cir.int<46> : !s32i, #cir.int<47> : !s32i, #cir.int<96> : !s32i, #cir.int<97> : !s32i, #cir.int<50> : !s32i, #cir.int<51> : !s32i, #cir.int<52> : !s32i, #cir.int<53> : !s32i, #cir.int<54> : !s32i, #cir.int<55> : !s32i, #cir.int<56> : !s32i, #cir.int<57> : !s32i, #cir.int<58> : !s32i, #cir.int<59> : !s32i, #cir.int<60> : !s32i, #cir.int<61> : !s32i, #cir.int<62> : !s32i, #cir.int<63> : !s32i, #cir.int<112> : !s32i, #cir.int<113> : !s32i] : !cir.vector<64 x {{!s8i|!u8i}}>
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/sse2-builtins.c b/clang/test/CIR/CodeGenBuiltins/X86/sse2-builtins.c
index 112407689cf7b8..652fa103970781 100644
--- a/clang/test/CIR/CodeGenBuiltins/X86/sse2-builtins.c
+++ b/clang/test/CIR/CodeGenBuiltins/X86/sse2-builtins.c
@@ -182,3 +182,27 @@ __m128i test_mm_mul_epu32(__m128i A, __m128i B) {
return _mm_mul_epu32(A, B);
}
+
+__m128i test_mm_mulhi_epi16(__m128i A, __m128i B) {
+ // CIR-LABEL: _mm_mulhi_epi16
+ // CIR: cir.call_llvm_intrinsic "smulh" %{{.*}}, %{{.*}} : (!cir.vector<8 x !s16i>, !cir.vector<8 x !s16i>) -> !cir.vector<8 x !s16i>
+
+ // LLVM-LABEL: test_mm_mulhi_epi16
+ // LLVM: call <8 x i16> @llvm.smulh.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+
+ // OGCG-LABEL: test_mm_mulhi_epi16
+ // OGCG: call <8 x i16> @llvm.smulh.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+ return _mm_mulhi_epi16(A, B);
+}
+
+__m128i test_mm_mulhi_epu16(__m128i A, __m128i B) {
+ // CIR-LABEL: _mm_mulhi_epu16
+ // CIR: cir.call_llvm_intrinsic "umulh" %{{.*}}, %{{.*}} : (!cir.vector<8 x !u16i>, !cir.vector<8 x !u16i>) -> !cir.vector<8 x !u16i>
+
+ // LLVM-LABEL: test_mm_mulhi_epu16
+ // LLVM: call <8 x i16> @llvm.umulh.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+
+ // OGCG-LABEL: test_mm_mulhi_epu16
+ // OGCG: call <8 x i16> @llvm.umulh.v8i16(<8 x i16> %{{.*}}, <8 x i16> %{{.*}})
+ return _mm_mulhi_epu16(A, B);
+}
More information about the cfe-commits
mailing list