Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -2651,7 +2651,8 @@ return cannotBeOrderedLessThanZeroImpl(I->getOperand(0), TLI, SignBitOnly, Depth + 1); case Instruction::Call: - Intrinsic::ID IID = getIntrinsicForCallSite(cast(I), TLI); + const auto *CI = cast(I); + Intrinsic::ID IID = getIntrinsicForCallSite(CI, TLI); switch (IID) { default: break; @@ -2668,12 +2669,18 @@ case Intrinsic::exp: case Intrinsic::exp2: case Intrinsic::fabs: - case Intrinsic::sqrt: return true; + + case Intrinsic::sqrt: + // sqrt(x) is always >= -0 or NaN. Moreover, sqrt(x) == -0 iff x == -0. + // IEEE 754 section 6.3 lets us assume that the sign bit of the NaN + // returned here is whatever we want, so we assume that it's 0. + return !SignBitOnly || CannotBeNegativeZero(CI->getOperand(0), TLI); + case Intrinsic::powi: - if (ConstantInt *CI = dyn_cast(I->getOperand(1))) { + if (ConstantInt *Exponent = dyn_cast(I->getOperand(1))) { // powi(x,n) is non-negative if n is even. - if (CI->getBitWidth() <= 64 && CI->getSExtValue() % 2u == 0) + if (Exponent->getBitWidth() <= 64 && Exponent->getSExtValue() % 2u == 0) return true; } // TODO: This is not correct. Given that exp is an integer, here are the Index: llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll =================================================================== --- llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll +++ llvm/test/Transforms/InstSimplify/floating-point-arithmetic.ll @@ -104,6 +104,7 @@ } declare float @llvm.fabs.f32(float) +declare float @llvm.sqrt.f32(float) ; CHECK-LABEL: @fabs_select_positive_constants( ; CHECK: %select = select i1 %cmp, float 1.000000e+00, float 2.000000e+00 @@ -195,3 +196,13 @@ %fabs = call float @llvm.fabs.f32(float %select) ret float %fabs } + +; CHECK-LABEL: @fabs_sqrt +; CHECK: call float @llvm.sqrt.f32 +; CHECK: call float @llvm.fabs.f32 +define float @fabs_sqrt(float %a) { +; The fabs can't be eliminated because llvm.sqrt.f32 may return -0. + %sqrt = call float @llvm.sqrt.f32(float %a) + %fabs = call float @llvm.fabs.f32(float %sqrt) + ret float %fabs +}