[llvm] [X86] - Add cases for poison value in pmulh[u] (PR #203534)
Rohit Aggarwal via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 12 07:16:34 PDT 2026
https://github.com/rohitaggarwal007 created https://github.com/llvm/llvm-project/pull/203534
The PR is based on the issue reported in SemiAnalysisAI by @jlebar
Bug : [060-pmulhuw-multiply-by-one-undef-elements](https://github.com/SemiAnalysisAI/FuzzX/blob/master/x86/bugs/060-pmulhuw-multiply-by-one-undef-elements/NOTES.md)
Issue was reported for presence of Undef value in the vector of 1's. The case is already handled in the code. But the case for poison value is not handled and there are no test cases associated to it.
Adding test case for poison value handling for pmulh[u] special case when one argument is vector of 1's.
I can update the PR if we want to handle the poison value similar to the Undef.
>From 16931a653dcb3ee98251da40240dc694b06f5149 Mon Sep 17 00:00:00 2001
From: Rohit Aggarwal <Rohit.Aggarwal at amd.com>
Date: Mon, 8 Jun 2026 18:50:24 +0530
Subject: [PATCH] [X86] - Add cases for poison value in pmulh[u]
---
.../Transforms/InstCombine/X86/x86-pmulh.ll | 34 +++++++++++++++++++
.../Transforms/InstCombine/X86/x86-pmulhu.ll | 32 +++++++++++++++++
2 files changed, 66 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/X86/x86-pmulh.ll b/llvm/test/Transforms/InstCombine/X86/x86-pmulh.ll
index 4d4d619ea7cb4..10223ebb86ee6 100644
--- a/llvm/test/Transforms/InstCombine/X86/x86-pmulh.ll
+++ b/llvm/test/Transforms/InstCombine/X86/x86-pmulh.ll
@@ -163,6 +163,40 @@ define <32 x i16> @one_pmulh_512_commute(<32 x i16> %a0) {
ret <32 x i16> %1
}
+; A splat-of-one with a poison lane still matches m_One() (poison lanes are
+; ignored), so it folds to ashr. This is a valid refinement: the poison lane can
+; be instantiated to 1, which yields the sign-bit replication of the other arg.
+
+define <8 x i16> @one_poison_pmulh_128(<8 x i16> %a0) {
+; CHECK-LABEL: @one_poison_pmulh_128(
+; CHECK-NEXT: [[TMP1:%.*]] = ashr <8 x i16> [[A0:%.*]], splat (i16 15)
+; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+;
+ %1 = call <8 x i16> @llvm.x86.sse2.pmulh.w(<8 x i16> %a0, <8 x i16> <i16 1, i16 poison, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+ ret <8 x i16> %1
+}
+
+define <8 x i16> @one_poison_pmulh_128_commute(<8 x i16> %a0) {
+; CHECK-LABEL: @one_poison_pmulh_128_commute(
+; CHECK-NEXT: [[TMP1:%.*]] = ashr <8 x i16> [[A0:%.*]], splat (i16 15)
+; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+;
+ %1 = call <8 x i16> @llvm.x86.sse2.pmulh.w(<8 x i16> <i16 1, i16 poison, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <8 x i16> %a0)
+ ret <8 x i16> %1
+}
+
+; A splat-of-one with an undef lane does NOT match m_One() (only poison lanes are
+; ignored), so the intrinsic is preserved.
+
+define <8 x i16> @one_undef_pmulh_128(<8 x i16> %a0) {
+; CHECK-LABEL: @one_undef_pmulh_128(
+; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.x86.sse2.pmulh.w(<8 x i16> [[A0:%.*]], <8 x i16> <i16 1, i16 undef, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+;
+ %1 = call <8 x i16> @llvm.x86.sse2.pmulh.w(<8 x i16> %a0, <8 x i16> <i16 1, i16 undef, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+ ret <8 x i16> %1
+}
+
;
; Constant Folding
;
diff --git a/llvm/test/Transforms/InstCombine/X86/x86-pmulhu.ll b/llvm/test/Transforms/InstCombine/X86/x86-pmulhu.ll
index 560969f7c4a81..d3117700ce7f5 100644
--- a/llvm/test/Transforms/InstCombine/X86/x86-pmulhu.ll
+++ b/llvm/test/Transforms/InstCombine/X86/x86-pmulhu.ll
@@ -157,6 +157,38 @@ define <32 x i16> @one_pmulhu_512_commute(<32 x i16> %a0) {
ret <32 x i16> %1
}
+; A splat-of-one with a poison lane still matches m_One() (poison lanes are
+; ignored), so it folds to zero. This is a valid refinement: the poison lane can
+; be instantiated to 0, which produces a 0 result.
+
+define <8 x i16> @one_poison_pmulhu_128(<8 x i16> %a0) {
+; CHECK-LABEL: @one_poison_pmulhu_128(
+; CHECK-NEXT: ret <8 x i16> zeroinitializer
+;
+ %1 = call <8 x i16> @llvm.x86.sse2.pmulhu.w(<8 x i16> %a0, <8 x i16> <i16 1, i16 poison, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+ ret <8 x i16> %1
+}
+
+define <8 x i16> @one_poison_pmulhu_128_commute(<8 x i16> %a0) {
+; CHECK-LABEL: @one_poison_pmulhu_128_commute(
+; CHECK-NEXT: ret <8 x i16> zeroinitializer
+;
+ %1 = call <8 x i16> @llvm.x86.sse2.pmulhu.w(<8 x i16> <i16 1, i16 poison, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>, <8 x i16> %a0)
+ ret <8 x i16> %1
+}
+
+; A splat-of-one with an undef lane does NOT match m_One() (only poison lanes are
+; ignored), so the intrinsic is preserved.
+
+define <8 x i16> @one_undef_pmulhu_128(<8 x i16> %a0) {
+; CHECK-LABEL: @one_undef_pmulhu_128(
+; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i16> @llvm.x86.sse2.pmulhu.w(<8 x i16> [[A0:%.*]], <8 x i16> <i16 1, i16 undef, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+; CHECK-NEXT: ret <8 x i16> [[TMP1]]
+;
+ %1 = call <8 x i16> @llvm.x86.sse2.pmulhu.w(<8 x i16> %a0, <8 x i16> <i16 1, i16 undef, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+ ret <8 x i16> %1
+}
+
;
; Constant Folding
;
More information about the llvm-commits
mailing list