[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