[llvm] [InstSimplify] Simplify `(fmul -x, +/-0)` -> `-/+0` (PR #85345)

via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 15 10:26:31 PDT 2024


https://github.com/goldsteinn updated https://github.com/llvm/llvm-project/pull/85345

>From b1bebb9f4a9fca341b3f6e1801d60b791abf3ab2 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Thu, 14 Mar 2024 20:03:01 -0500
Subject: [PATCH 1/2] [InstSimply] Add tests for simplify `(fmul -x, +/-0)`;
 NFC

---
 .../InstSimplify/floating-point-arithmetic.ll | 47 +++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll b/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll
index b8244b1d508c62..ffdca34b529b43 100644
--- a/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll
+++ b/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll
@@ -211,6 +211,53 @@ define double @fmul_nnan_ninf_nneg_n0.0_commute(i127 %x) {
   ret double %r
 }
 
+define float @src_mul_nzero_neg(float nofpclass(inf nan pzero psub pnorm) %f) {
+; CHECK-LABEL: @src_mul_nzero_neg(
+; CHECK-NEXT:    [[R:%.*]] = fmul float [[F:%.*]], -0.000000e+00
+; CHECK-NEXT:    ret float [[R]]
+;
+  %r = fmul float %f, -0.0
+  ret float %r
+}
+
+define <2 x float> @src_mul_zero_neg(<2 x float> nofpclass(inf nan pzero psub pnorm) %f) {
+; CHECK-LABEL: @src_mul_zero_neg(
+; CHECK-NEXT:    [[R:%.*]] = fmul <2 x float> zeroinitializer, [[F:%.*]]
+; CHECK-NEXT:    ret <2 x float> [[R]]
+;
+  %r = fmul <2 x float> <float 0.0, float 0.0>, %f
+  ret <2 x float> %r
+}
+
+define <2 x float> @src_mul_zero_and_nzero_neg(<2 x float> nofpclass(inf nan pzero psub pnorm) %f) {
+; CHECK-LABEL: @src_mul_zero_and_nzero_neg(
+; CHECK-NEXT:    [[R:%.*]] = fmul <2 x float> <float -0.000000e+00, float 0.000000e+00>, [[F:%.*]]
+; CHECK-NEXT:    ret <2 x float> [[R]]
+;
+  %r = fmul <2 x float> <float -0.0, float 0.0>, %f
+  ret <2 x float> %r
+}
+
+
+define float @src_muladd_zero_neg(float nofpclass(inf nan pzero psub pnorm) %f, float %add) {
+; CHECK-LABEL: @src_muladd_zero_neg(
+; CHECK-NEXT:    [[R:%.*]] = call float @llvm.fmuladd.f32(float [[F:%.*]], float 0.000000e+00, float [[ADD:%.*]])
+; CHECK-NEXT:    ret float [[R]]
+;
+  %r = call float @llvm.fmuladd.f32(float %f, float 0.0, float %add)
+  ret float %r
+}
+
+define float @src_fma_nzero_neg(float nofpclass(inf nan pzero psub pnorm) %f, float %add) {
+; CHECK-LABEL: @src_fma_nzero_neg(
+; CHECK-NEXT:    [[R:%.*]] = call float @llvm.fma.f32(float -0.000000e+00, float [[F:%.*]], float [[ADD:%.*]])
+; CHECK-NEXT:    ret float [[R]]
+;
+  %r = call float @llvm.fma.f32(float -0.0, float %f, float %add)
+  ret float %r
+}
+
+
 ; Make sure we can infer %x can't be 0 based on assumes.
 define { float, float } @test_fmul_0_assumed_finite(float %x) {
 ; CHECK-LABEL: @test_fmul_0_assumed_finite(

>From d84e96c3ffe02d2d4d6406e3f133582001e3275e Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Thu, 14 Mar 2024 20:03:05 -0500
Subject: [PATCH 2/2] [InstSimply] Simplify `(fmul -x, +/-0)` -> `-/+0`

We already handle the `+x` case, and noticed it was missing in the bug
affecting #82555

Proofs: https://alive2.llvm.org/ce/z/WUSvmV
---
 llvm/lib/Analysis/InstructionSimplify.cpp             | 11 ++++++++---
 .../InstSimplify/floating-point-arithmetic.ll         |  9 +++------
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index d14897a86314e1..06283cb4bb934b 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -5767,11 +5767,16 @@ static Value *simplifyFMAFMul(Value *Op0, Value *Op1, FastMathFlags FMF,
     if (FMF.noNaNs() && FMF.noSignedZeros())
       return ConstantFP::getZero(Op0->getType());
 
-    // +normal number * (-)0.0 --> (-)0.0
     KnownFPClass Known =
         computeKnownFPClass(Op0, FMF, fcInf | fcNan, /*Depth=*/0, Q);
-    if (Known.SignBit == false && Known.isKnownNever(fcInf | fcNan))
-      return Op1;
+    if (Known.isKnownNever(fcInf | fcNan)) {
+      // +normal number * (-)0.0 --> (-)0.0
+      if (Known.SignBit == false)
+        return Op1;
+      // -normal number * (-)0.0 --> -(-)0.0
+      if (Known.SignBit == true)
+        return foldConstant(Instruction::FNeg, Op1, Q);
+    }
   }
 
   // sqrt(X) * sqrt(X) --> X, if we can:
diff --git a/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll b/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll
index ffdca34b529b43..5d17504c09df67 100644
--- a/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll
+++ b/llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll
@@ -213,8 +213,7 @@ define double @fmul_nnan_ninf_nneg_n0.0_commute(i127 %x) {
 
 define float @src_mul_nzero_neg(float nofpclass(inf nan pzero psub pnorm) %f) {
 ; CHECK-LABEL: @src_mul_nzero_neg(
-; CHECK-NEXT:    [[R:%.*]] = fmul float [[F:%.*]], -0.000000e+00
-; CHECK-NEXT:    ret float [[R]]
+; CHECK-NEXT:    ret float 0.000000e+00
 ;
   %r = fmul float %f, -0.0
   ret float %r
@@ -222,8 +221,7 @@ define float @src_mul_nzero_neg(float nofpclass(inf nan pzero psub pnorm) %f) {
 
 define <2 x float> @src_mul_zero_neg(<2 x float> nofpclass(inf nan pzero psub pnorm) %f) {
 ; CHECK-LABEL: @src_mul_zero_neg(
-; CHECK-NEXT:    [[R:%.*]] = fmul <2 x float> zeroinitializer, [[F:%.*]]
-; CHECK-NEXT:    ret <2 x float> [[R]]
+; CHECK-NEXT:    ret <2 x float> <float -0.000000e+00, float -0.000000e+00>
 ;
   %r = fmul <2 x float> <float 0.0, float 0.0>, %f
   ret <2 x float> %r
@@ -231,8 +229,7 @@ define <2 x float> @src_mul_zero_neg(<2 x float> nofpclass(inf nan pzero psub pn
 
 define <2 x float> @src_mul_zero_and_nzero_neg(<2 x float> nofpclass(inf nan pzero psub pnorm) %f) {
 ; CHECK-LABEL: @src_mul_zero_and_nzero_neg(
-; CHECK-NEXT:    [[R:%.*]] = fmul <2 x float> <float -0.000000e+00, float 0.000000e+00>, [[F:%.*]]
-; CHECK-NEXT:    ret <2 x float> [[R]]
+; CHECK-NEXT:    ret <2 x float> <float 0.000000e+00, float -0.000000e+00>
 ;
   %r = fmul <2 x float> <float -0.0, float 0.0>, %f
   ret <2 x float> %r



More information about the llvm-commits mailing list