[llvm] [instcombine][x86]: simplifyx86fpmaxmin - allow negzero for single operand (PR #180418)

via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 8 08:07:31 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Madhur Kumar (MadhurKumar004)

<details>
<summary>Changes</summary>

fixes: https://github.com/llvm/llvm-project/issues/175552

---
Full diff: https://github.com/llvm/llvm-project/pull/180418.diff


2 Files Affected:

- (modified) llvm/lib/Target/X86/X86InstCombineIntrinsic.cpp (+13-9) 
- (added) llvm/test/Transforms/InstCombine/X86/x86-fp-minmax-negzero.ll (+46) 


``````````diff
diff --git a/llvm/lib/Target/X86/X86InstCombineIntrinsic.cpp b/llvm/lib/Target/X86/X86InstCombineIntrinsic.cpp
index d46dbf178bcff..682a25ec2151e 100644
--- a/llvm/lib/Target/X86/X86InstCombineIntrinsic.cpp
+++ b/llvm/lib/Target/X86/X86InstCombineIntrinsic.cpp
@@ -1745,15 +1745,19 @@ static Value *simplifyX86FPMaxMin(const IntrinsicInst &II, InstCombiner &IC,
   APInt DemandedElts =
       IsScalar ? APInt::getOneBitSet(VWidth, 0) : APInt::getAllOnes(VWidth);
 
-  // Verify that the inputs are not one of (NaN, Inf, Subnormal, NegZero),
-  // otherwise we cannot safely generalize to MAXNUM/MINNUM.
-  FPClassTest Forbidden = fcNan | fcInf | fcSubnormal | fcNegZero;
-  KnownFPClass KnownArg0 =
-      computeKnownFPClass(Arg0, DemandedElts, Forbidden, SQ);
-  KnownFPClass KnownArg1 =
-      computeKnownFPClass(Arg1, DemandedElts, Forbidden, SQ);
-
-  if (KnownArg0.isKnownNever(Forbidden) && KnownArg1.isKnownNever(Forbidden)) {
+  FPClassTest Forbidden0 = fcNan | fcInf | fcSubnormal;
+  FPClassTest Forbidden1 = fcNan | fcInf | fcSubnormal;
+  if (NewIID == Intrinsic::maxnum) {
+    // For maxnum, only forbid NegZero in the second operand.
+    Forbidden1 |= fcNegZero;
+  } else if (NewIID == Intrinsic::minnum) {
+    // For minnum, only forbid NegZero in the first operand.
+    Forbidden0 |= fcNegZero;
+  }
+  KnownFPClass KnownArg0 = computeKnownFPClass(Arg0, DemandedElts, Forbidden0, SQ);
+  KnownFPClass KnownArg1 = computeKnownFPClass(Arg1, DemandedElts, Forbidden1, SQ);
+
+  if (KnownArg0.isKnownNever(Forbidden0) && KnownArg1.isKnownNever(Forbidden1)) {
     if (IsScalar) {
       // It performs the operation on the first element and puts it back into
       // the vector.
diff --git a/llvm/test/Transforms/InstCombine/X86/x86-fp-minmax-negzero.ll b/llvm/test/Transforms/InstCombine/X86/x86-fp-minmax-negzero.ll
new file mode 100644
index 0000000000000..501971e4a646c
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/X86/x86-fp-minmax-negzero.ll
@@ -0,0 +1,46 @@
+; RUN: opt -passes=instcombine -mtriple=x86_64-unknown-unknown < %s -S | FileCheck %s
+
+; Test relaxed negzero handling for X86 max/min intrinsics.
+
+declare <4 x float> @llvm.x86.sse.max.ps(<4 x float>, <4 x float>)
+declare <4 x float> @llvm.x86.sse.min.ps(<4 x float>, <4 x float>)
+
+; For maxnum, allow -0.0 in the first operand only.
+
+define <4 x float> @test_max_allow_negzero_first() {
+; CHECK-LABEL: @test_max_allow_negzero_first(
+; CHECK: ret <4 x float> splat (float 1.000000e+00)
+entry:
+  %r = call <4 x float> @llvm.x86.sse.max.ps(<4 x float> <float -0.0, float -0.0, float -0.0, float -0.0>, <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>)
+  ret <4 x float> %r
+}
+
+; For minnum, allow -0.0 in the second operand only.
+
+define <4 x float> @test_min_allow_negzero_second() {
+; CHECK-LABEL: @test_min_allow_negzero_second(
+; CHECK: ret <4 x float> splat (float -0.000000e+00)
+entry:
+  %r = call <4 x float> @llvm.x86.sse.min.ps(<4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>, <4 x float> <float -0.0, float -0.0, float -0.0, float -0.0>)
+  ret <4 x float> %r
+}
+
+; Negative test: max should not fold when -0.0 is in the second operand.
+
+define <4 x float> @test_max_disallow_negzero_second() {
+; CHECK-LABEL: @test_max_disallow_negzero_second(
+; CHECK: call <4 x float> @llvm.x86.sse.max.ps
+entry:
+  %r = call <4 x float> @llvm.x86.sse.max.ps(<4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>, <4 x float> <float -0.0, float -0.0, float -0.0, float -0.0>)
+  ret <4 x float> %r
+}
+
+; Negative test: min should not fold when -0.0 is in the first operand.
+
+define <4 x float> @test_min_disallow_negzero_first() {
+; CHECK-LABEL: @test_min_disallow_negzero_first(
+; CHECK: call <4 x float> @llvm.x86.sse.min.ps
+entry:
+  %r = call <4 x float> @llvm.x86.sse.min.ps(<4 x float> <float -0.0, float -0.0, float -0.0, float -0.0>, <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>)
+  ret <4 x float> %r
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/180418


More information about the llvm-commits mailing list