summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-03-18 14:32:54 +0000
committerSanjay Patel <spatel@rotateright.com>2018-03-18 14:32:54 +0000
commit63b1028953cf688c687fc5f3168ab948a50fcc54 (patch)
treecddd88adecca28ce4a8069b5cc6a4a3c9ad18cee
parent95ec4a4dfe4655044a5f689f792e5394d73ea248 (diff)
downloadbcm5719-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.cpp4
-rw-r--r--llvm/test/Transforms/InstCombine/fmul-sqrt.ll34
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
}
OpenPOWER on IntegriCloud