[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