aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2022-01-17 10:35:03 -0500
committerSanjay Patel <spatel@rotateright.com>2022-01-17 10:38:05 -0500
commit4cdf30d9d36ea6a6dfee967414f9f0e1748350af (patch)
tree9ad7bb36dc34224f8357def2b93b15b234a286b7
parentbcf5e687c917ed35c41395b92a5af8f162f89efc (diff)
downloadllvm-4cdf30d9d36ea6a6dfee967414f9f0e1748350af.zip
llvm-4cdf30d9d36ea6a6dfee967414f9f0e1748350af.tar.gz
llvm-4cdf30d9d36ea6a6dfee967414f9f0e1748350af.tar.bz2
[InstCombine] FP with reassoc FMF: (X * C) + X --> X * (MulC + 1.0)
This fold already exists for scalars via FAddCombine (and that's why 2 of the tests are only changed cosmetically), but that code misses vectors and has largely been replaced by simpler folds over time, so this is another step towards removing it.
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp8
-rw-r--r--llvm/test/Transforms/InstCombine/fadd.ll22
2 files changed, 22 insertions, 8 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index eb1b8a2..7f4f5d8 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1654,6 +1654,14 @@ Instruction *InstCombinerImpl::visitFAdd(BinaryOperator &I) {
{X->getType()}, {NewStartC, X}, &I));
}
+ // (X * MulC) + X --> X * (MulC + 1.0)
+ Constant *MulC;
+ if (match(&I, m_c_FAdd(m_FMul(m_Value(X), m_ImmConstant(MulC)),
+ m_Deferred(X)))) {
+ MulC = ConstantExpr::getFAdd(MulC, ConstantFP::get(I.getType(), 1.0));
+ return BinaryOperator::CreateFMulFMF(X, MulC, &I);
+ }
+
if (Value *V = FAddCombine(Builder).simplify(&I))
return replaceInstUsesWith(I, V);
}
diff --git a/llvm/test/Transforms/InstCombine/fadd.ll b/llvm/test/Transforms/InstCombine/fadd.ll
index d74d581..f69a69f 100644
--- a/llvm/test/Transforms/InstCombine/fadd.ll
+++ b/llvm/test/Transforms/InstCombine/fadd.ll
@@ -466,18 +466,19 @@ define float @fadd_rdx_nonzero_start_variable_op(float %x, <4 x float> %v) {
define float @fadd_fmul_common_op(float %x) {
; CHECK-LABEL: @fadd_fmul_common_op(
-; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc nsz float [[X:%.*]], 4.300000e+01
-; CHECK-NEXT: ret float [[TMP1]]
+; CHECK-NEXT: [[A:%.*]] = fmul reassoc nsz float [[X:%.*]], 4.300000e+01
+; CHECK-NEXT: ret float [[A]]
;
%m = fmul reassoc nsz float %x, 42.0
%a = fadd reassoc nsz float %m, %x
ret float %a
}
+; Splat constant is ok.
+
define <2 x float> @fadd_fmul_common_op_vec(<2 x float> %x) {
; CHECK-LABEL: @fadd_fmul_common_op_vec(
-; CHECK-NEXT: [[M:%.*]] = fmul reassoc nsz <2 x float> [[X:%.*]], <float 4.200000e+01, float 4.200000e+01>
-; CHECK-NEXT: [[A:%.*]] = fadd reassoc nsz <2 x float> [[M]], [[X]]
+; CHECK-NEXT: [[A:%.*]] = fmul reassoc nsz <2 x float> [[X:%.*]], <float 4.300000e+01, float 4.300000e+01>
; CHECK-NEXT: ret <2 x float> [[A]]
;
%m = fmul reassoc nsz <2 x float> %x, <float 42.0, float 42.0>
@@ -485,11 +486,12 @@ define <2 x float> @fadd_fmul_common_op_vec(<2 x float> %x) {
ret <2 x float> %a
}
+; Non-splat constant is ok.
+
define <2 x float> @fadd_fmul_common_op_commute_vec(<2 x float> %px) {
; CHECK-LABEL: @fadd_fmul_common_op_commute_vec(
; CHECK-NEXT: [[X:%.*]] = fmul <2 x float> [[PX:%.*]], [[PX]]
-; CHECK-NEXT: [[M:%.*]] = fmul reassoc nsz <2 x float> [[X]], <float 4.200000e+01, float -4.300000e+01>
-; CHECK-NEXT: [[A:%.*]] = fadd reassoc nsz <2 x float> [[X]], [[M]]
+; CHECK-NEXT: [[A:%.*]] = fmul reassoc nsz <2 x float> [[X]], <float 4.300000e+01, float -4.200000e+01>
; CHECK-NEXT: ret <2 x float> [[A]]
;
%x = fmul <2 x float> %px, %px ; thwart complexity-based canonicalization
@@ -498,12 +500,14 @@ define <2 x float> @fadd_fmul_common_op_commute_vec(<2 x float> %px) {
ret <2 x float> %a
}
+; Extra use is ok.
+
define float @fadd_fmul_common_op_use(float %x) {
; CHECK-LABEL: @fadd_fmul_common_op_use(
; CHECK-NEXT: [[M:%.*]] = fmul reassoc nsz float [[X:%.*]], 4.200000e+01
; CHECK-NEXT: call void @use(float [[M]])
-; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc nsz float [[X]], 4.300000e+01
-; CHECK-NEXT: ret float [[TMP1]]
+; CHECK-NEXT: [[A:%.*]] = fmul reassoc nsz float [[X]], 4.300000e+01
+; CHECK-NEXT: ret float [[A]]
;
%m = fmul reassoc nsz float %x, 42.0
call void @use(float %m)
@@ -511,6 +515,8 @@ define float @fadd_fmul_common_op_use(float %x) {
ret float %a
}
+; Negative test - must have 'reassoc' FMF
+
define float @fadd_fmul_common_op_wrong_fmf(float %x) {
; CHECK-LABEL: @fadd_fmul_common_op_wrong_fmf(
; CHECK-NEXT: [[M:%.*]] = fmul ninf nsz float [[X:%.*]], 4.200000e+01