diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2022-01-17 10:35:03 -0500 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2022-01-17 10:38:05 -0500 |
| commit | 4cdf30d9d36ea6a6dfee967414f9f0e1748350af (patch) | |
| tree | 9ad7bb36dc34224f8357def2b93b15b234a286b7 | |
| parent | bcf5e687c917ed35c41395b92a5af8f162f89efc (diff) | |
| download | llvm-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.cpp | 8 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/fadd.ll | 22 |
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 |
