[llvm] 44b7da8 - [InstCombine] fmul nnan X, 0.0 --> copysign(0.0, X)

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 18 08:34:12 PDT 2022


Author: Sanjay Patel
Date: 2022-10-18T11:34:02-04:00
New Revision: 44b7da89d774019dc52342712a0edd73f90ad90a

URL: https://github.com/llvm/llvm-project/commit/44b7da89d774019dc52342712a0edd73f90ad90a
DIFF: https://github.com/llvm/llvm-project/commit/44b7da89d774019dc52342712a0edd73f90ad90a.diff

LOG: [InstCombine] fmul nnan X, 0.0 --> copysign(0.0, X)

https://alive2.llvm.org/ce/z/ybgM5F

Differential Revision: https://reviews.llvm.org/D136166

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
    llvm/test/Transforms/InstCombine/fmul.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index c2c35c643adc..829b619f3c3b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -521,6 +521,13 @@ Instruction *InstCombinerImpl::visitFMul(BinaryOperator &I) {
   if (match(Op1, m_SpecificFP(-1.0)))
     return UnaryOperator::CreateFNegFMF(Op0, &I);
 
+  // With no-nans: X * 0.0 --> copysign(0.0, X)
+  if (I.hasNoNaNs() && match(Op1, m_PosZeroFP())) {
+    CallInst *CopySign = Builder.CreateIntrinsic(Intrinsic::copysign,
+                                                 {I.getType()}, {Op1, Op0}, &I);
+    return replaceInstUsesWith(I, CopySign);
+  }
+
   // -X * C --> X * -C
   Value *X, *Y;
   Constant *C;

diff  --git a/llvm/test/Transforms/InstCombine/fmul.ll b/llvm/test/Transforms/InstCombine/fmul.ll
index 1c393e6dcb86..b84a5bd56a6d 100644
--- a/llvm/test/Transforms/InstCombine/fmul.ll
+++ b/llvm/test/Transforms/InstCombine/fmul.ll
@@ -1203,22 +1203,26 @@ define <vscale x 2 x float> @mul_scalable_splat_zero(<vscale x 2 x float> %z) {
 
 define half @mul_zero_nnan(half %x) {
 ; CHECK-LABEL: @mul_zero_nnan(
-; CHECK-NEXT:    [[R:%.*]] = fmul nnan half [[X:%.*]], 0xH0000
-; CHECK-NEXT:    ret half [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan half @llvm.copysign.f16(half 0xH0000, half [[X:%.*]])
+; CHECK-NEXT:    ret half [[TMP1]]
 ;
   %r = fmul nnan half %x, 0.0
   ret half %r
 }
 
+; poison propagates through vector elements
+
 define <2 x float> @mul_zero_nnan_vec_poison(<2 x float> %x) {
 ; CHECK-LABEL: @mul_zero_nnan_vec_poison(
-; CHECK-NEXT:    [[R:%.*]] = fmul nnan <2 x float> [[X:%.*]], <float 0.000000e+00, float poison>
-; CHECK-NEXT:    ret <2 x float> [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call nnan <2 x float> @llvm.copysign.v2f32(<2 x float> <float 0.000000e+00, float poison>, <2 x float> [[X:%.*]])
+; CHECK-NEXT:    ret <2 x float> [[TMP1]]
 ;
   %r = fmul nnan <2 x float> %x, <float 0.0, float poison>
   ret <2 x float> %r
 }
 
+; negative test - must have nnan
+
 define half @mul_zero(half %x) {
 ; CHECK-LABEL: @mul_zero(
 ; CHECK-NEXT:    [[R:%.*]] = fmul ninf nsz half [[X:%.*]], 0xH0000
@@ -1228,6 +1232,8 @@ define half @mul_zero(half %x) {
   ret half %r
 }
 
+; TODO: This could be fneg+copysign.
+
 define half @mul_negzero_nnan(half %x) {
 ; CHECK-LABEL: @mul_negzero_nnan(
 ; CHECK-NEXT:    [[R:%.*]] = fmul nnan half [[X:%.*]], 0xH8000


        


More information about the llvm-commits mailing list