diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2018-03-18 14:32:54 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2018-03-18 14:32:54 +0000 |
| commit | 63b1028953cf688c687fc5f3168ab948a50fcc54 (patch) | |
| tree | cddd88adecca28ce4a8069b5cc6a4a3c9ad18cee | |
| parent | 95ec4a4dfe4655044a5f689f792e5394d73ea248 (diff) | |
| download | bcm5719-llvm-63b1028953cf688c687fc5f3168ab948a50fcc54.tar.gz bcm5719-llvm-63b1028953cf688c687fc5f3168ab948a50fcc54.zip | |
[InstCombine] add nnan requirement for sqrt(x) * sqrt(y) -> sqrt(x*y)
This is similar to D43765.
llvm-svn: 327797
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 4 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/fmul-sqrt.ll | 34 |
2 files changed, 28 insertions, 10 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 56de5ed006d..f35311bb966 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -636,7 +636,9 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) { } // sqrt(X) * sqrt(Y) -> sqrt(X * Y) - if (I.hasAllowReassoc() && + // nnan disallows the possibility of returning a number if both operands are + // negative (in that case, we should return NaN). + if (I.hasAllowReassoc() && I.hasNoNaNs() && match(Op0, m_OneUse(m_Intrinsic<Intrinsic::sqrt>(m_Value(X)))) && match(Op1, m_OneUse(m_Intrinsic<Intrinsic::sqrt>(m_Value(Y))))) { Value *XY = Builder.CreateFMulFMF(X, Y, &I); diff --git a/llvm/test/Transforms/InstCombine/fmul-sqrt.ll b/llvm/test/Transforms/InstCombine/fmul-sqrt.ll index 582fa606d3b..61d98c7972c 100644 --- a/llvm/test/Transforms/InstCombine/fmul-sqrt.ll +++ b/llvm/test/Transforms/InstCombine/fmul-sqrt.ll @@ -38,11 +38,27 @@ define double @sqrt_a_sqrt_b_multiple_uses(double %a, double %b) { ; sqrt(a) * sqrt(b) => sqrt(a*b) with fast-math +define double @sqrt_a_sqrt_b_reassoc_nnan(double %a, double %b) { +; CHECK-LABEL: @sqrt_a_sqrt_b_reassoc_nnan( +; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc nnan double [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = call reassoc nnan double @llvm.sqrt.f64(double [[TMP1]]) +; CHECK-NEXT: ret double [[TMP2]] +; + %1 = call double @llvm.sqrt.f64(double %a) + %2 = call double @llvm.sqrt.f64(double %b) + %mul = fmul reassoc nnan double %1, %2 + ret double %mul +} + +; nnan disallows the possibility that both operands are negative, +; so we won't return a number when the answer should be NaN. + define double @sqrt_a_sqrt_b_reassoc(double %a, double %b) { ; CHECK-LABEL: @sqrt_a_sqrt_b_reassoc( -; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc double [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[TMP2:%.*]] = call reassoc double @llvm.sqrt.f64(double [[TMP1]]) -; CHECK-NEXT: ret double [[TMP2]] +; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.sqrt.f64(double [[A:%.*]]) +; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.sqrt.f64(double [[B:%.*]]) +; CHECK-NEXT: [[MUL:%.*]] = fmul reassoc double [[TMP1]], [[TMP2]] +; CHECK-NEXT: ret double [[MUL]] ; %1 = call double @llvm.sqrt.f64(double %a) %2 = call double @llvm.sqrt.f64(double %b) @@ -51,23 +67,23 @@ define double @sqrt_a_sqrt_b_reassoc(double %a, double %b) { } ; sqrt(a) * sqrt(b) * sqrt(c) * sqrt(d) => sqrt(a*b*c*d) with fast-math -; 'reassoc' on the fmuls is all that is required, but check propagation of other FMF. +; 'reassoc nnan' on the fmuls is all that is required, but check propagation of other FMF. define double @sqrt_a_sqrt_b_sqrt_c_sqrt_d_reassoc(double %a, double %b, double %c, double %d) { ; CHECK-LABEL: @sqrt_a_sqrt_b_sqrt_c_sqrt_d_reassoc( -; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc arcp double [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc nnan arcp double [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = fmul reassoc nnan double [[TMP1]], [[C:%.*]] -; CHECK-NEXT: [[TMP3:%.*]] = fmul reassoc ninf double [[TMP2]], [[D:%.*]] -; CHECK-NEXT: [[TMP4:%.*]] = call reassoc ninf double @llvm.sqrt.f64(double [[TMP3]]) +; CHECK-NEXT: [[TMP3:%.*]] = fmul reassoc nnan ninf double [[TMP2]], [[D:%.*]] +; CHECK-NEXT: [[TMP4:%.*]] = call reassoc nnan ninf double @llvm.sqrt.f64(double [[TMP3]]) ; CHECK-NEXT: ret double [[TMP4]] ; %1 = call double @llvm.sqrt.f64(double %a) %2 = call double @llvm.sqrt.f64(double %b) %3 = call double @llvm.sqrt.f64(double %c) %4 = call double @llvm.sqrt.f64(double %d) - %mul = fmul reassoc arcp double %1, %2 + %mul = fmul reassoc nnan arcp double %1, %2 %mul1 = fmul reassoc nnan double %mul, %3 - %mul2 = fmul reassoc ninf double %mul1, %4 + %mul2 = fmul reassoc nnan ninf double %mul1, %4 ret double %mul2 } |

