mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[InstSimplify] loosen FMF for sqrt(X) * sqrt(X) --> X
As shown in the code comment, we don't need all of 'fast', but we do need reassoc + nsz + nnan. Differential Revision: https://reviews.llvm.org/D43765 llvm-svn: 327796
This commit is contained in:
parent
83f069b61f
commit
83d39ccfbf
@ -4249,10 +4249,13 @@ static Value *SimplifyFMulInst(Value *Op0, Value *Op1, FastMathFlags FMF,
|
||||
if (FMF.noNaNs() && FMF.noSignedZeros() && match(Op1, m_AnyZeroFP()))
|
||||
return ConstantFP::getNullValue(Op0->getType());
|
||||
|
||||
// sqrt(X) * sqrt(X) --> X
|
||||
// sqrt(X) * sqrt(X) --> X, if we can:
|
||||
// 1. Remove the intermediate rounding (reassociate).
|
||||
// 2. Ignore non-zero negative numbers because sqrt would produce NAN.
|
||||
// 3. Ignore -0.0 because sqrt(-0.0) == -0.0, but -0.0 * -0.0 == 0.0.
|
||||
Value *X;
|
||||
if (FMF.isFast() && Op0 == Op1 &&
|
||||
match(Op0, m_Intrinsic<Intrinsic::sqrt>(m_Value(X))))
|
||||
if (Op0 == Op1 && match(Op0, m_Intrinsic<Intrinsic::sqrt>(m_Value(X))) &&
|
||||
FMF.allowReassoc() && FMF.noNaNs() && FMF.noSignedZeros())
|
||||
return X;
|
||||
|
||||
return nullptr;
|
||||
|
@ -323,7 +323,7 @@ define float @fdiv_neg_swapped2(float %f) {
|
||||
}
|
||||
|
||||
; PR21126: http://llvm.org/bugs/show_bug.cgi?id=21126
|
||||
; With unsafe/fast math, sqrt(X) * sqrt(X) is just X.
|
||||
; With loose math, sqrt(X) * sqrt(X) is just X.
|
||||
|
||||
declare double @llvm.sqrt.f64(double)
|
||||
|
||||
@ -332,7 +332,42 @@ define double @sqrt_squared(double %f) {
|
||||
; CHECK-NEXT: ret double [[F:%.*]]
|
||||
;
|
||||
%sqrt = call double @llvm.sqrt.f64(double %f)
|
||||
%mul = fmul fast double %sqrt, %sqrt
|
||||
%mul = fmul reassoc nnan nsz double %sqrt, %sqrt
|
||||
ret double %mul
|
||||
}
|
||||
|
||||
; Negative tests for the above transform: we need all 3 of those flags.
|
||||
|
||||
define double @sqrt_squared_not_fast_enough1(double %f) {
|
||||
; CHECK-LABEL: @sqrt_squared_not_fast_enough1(
|
||||
; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[F:%.*]])
|
||||
; CHECK-NEXT: [[MUL:%.*]] = fmul nnan nsz double [[SQRT]], [[SQRT]]
|
||||
; CHECK-NEXT: ret double [[MUL]]
|
||||
;
|
||||
%sqrt = call double @llvm.sqrt.f64(double %f)
|
||||
%mul = fmul nnan nsz double %sqrt, %sqrt
|
||||
ret double %mul
|
||||
}
|
||||
|
||||
define double @sqrt_squared_not_fast_enough2(double %f) {
|
||||
; CHECK-LABEL: @sqrt_squared_not_fast_enough2(
|
||||
; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[F:%.*]])
|
||||
; CHECK-NEXT: [[MUL:%.*]] = fmul reassoc nnan double [[SQRT]], [[SQRT]]
|
||||
; CHECK-NEXT: ret double [[MUL]]
|
||||
;
|
||||
%sqrt = call double @llvm.sqrt.f64(double %f)
|
||||
%mul = fmul reassoc nnan double %sqrt, %sqrt
|
||||
ret double %mul
|
||||
}
|
||||
|
||||
define double @sqrt_squared_not_fast_enough3(double %f) {
|
||||
; CHECK-LABEL: @sqrt_squared_not_fast_enough3(
|
||||
; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[F:%.*]])
|
||||
; CHECK-NEXT: [[MUL:%.*]] = fmul reassoc nsz double [[SQRT]], [[SQRT]]
|
||||
; CHECK-NEXT: ret double [[MUL]]
|
||||
;
|
||||
%sqrt = call double @llvm.sqrt.f64(double %f)
|
||||
%mul = fmul reassoc nsz double %sqrt, %sqrt
|
||||
ret double %mul
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user