aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/ConstantFolding.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/ConstantFolding.cpp')
-rw-r--r--lib/Analysis/ConstantFolding.cpp204
1 files changed, 97 insertions, 107 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
index 73867279abe4..14176dac2104 100644
--- a/lib/Analysis/ConstantFolding.cpp
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -1058,8 +1058,8 @@ ConstantFoldConstantImpl(const Constant *C, const DataLayout &DL,
if (It == FoldedOps.end()) {
if (auto *FoldedC =
ConstantFoldConstantImpl(NewC, DL, TLI, FoldedOps)) {
- NewC = FoldedC;
FoldedOps.insert({NewC, FoldedC});
+ NewC = FoldedC;
} else {
FoldedOps.insert({NewC, NewC});
}
@@ -1401,7 +1401,7 @@ bool llvm::canConstantFoldCallTo(const Function *F) {
return true;
default:
return false;
- case 0: break;
+ case Intrinsic::not_intrinsic: break;
}
if (!F->hasName())
@@ -1518,9 +1518,9 @@ Constant *ConstantFoldSSEConvertToInt(const APFloat &Val, bool roundTowardZero,
bool isExact = false;
APFloat::roundingMode mode = roundTowardZero? APFloat::rmTowardZero
: APFloat::rmNearestTiesToEven;
- APFloat::opStatus status = Val.convertToInteger(&UIntVal, ResultWidth,
- /*isSigned=*/true, mode,
- &isExact);
+ APFloat::opStatus status =
+ Val.convertToInteger(makeMutableArrayRef(UIntVal), ResultWidth,
+ /*isSigned=*/true, mode, &isExact);
if (status != APFloat::opOK &&
(!roundTowardZero || status != APFloat::opInexact))
return nullptr;
@@ -1630,6 +1630,8 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,
return ConstantFoldFP(sin, V, Ty);
case Intrinsic::cos:
return ConstantFoldFP(cos, V, Ty);
+ case Intrinsic::sqrt:
+ return ConstantFoldFP(sqrt, V, Ty);
}
if (!TLI)
@@ -1637,87 +1639,74 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,
switch (Name[0]) {
case 'a':
- if ((Name == "acos" && TLI->has(LibFunc::acos)) ||
- (Name == "acosf" && TLI->has(LibFunc::acosf)))
+ if ((Name == "acos" && TLI->has(LibFunc_acos)) ||
+ (Name == "acosf" && TLI->has(LibFunc_acosf)))
return ConstantFoldFP(acos, V, Ty);
- else if ((Name == "asin" && TLI->has(LibFunc::asin)) ||
- (Name == "asinf" && TLI->has(LibFunc::asinf)))
+ else if ((Name == "asin" && TLI->has(LibFunc_asin)) ||
+ (Name == "asinf" && TLI->has(LibFunc_asinf)))
return ConstantFoldFP(asin, V, Ty);
- else if ((Name == "atan" && TLI->has(LibFunc::atan)) ||
- (Name == "atanf" && TLI->has(LibFunc::atanf)))
+ else if ((Name == "atan" && TLI->has(LibFunc_atan)) ||
+ (Name == "atanf" && TLI->has(LibFunc_atanf)))
return ConstantFoldFP(atan, V, Ty);
break;
case 'c':
- if ((Name == "ceil" && TLI->has(LibFunc::ceil)) ||
- (Name == "ceilf" && TLI->has(LibFunc::ceilf)))
+ if ((Name == "ceil" && TLI->has(LibFunc_ceil)) ||
+ (Name == "ceilf" && TLI->has(LibFunc_ceilf)))
return ConstantFoldFP(ceil, V, Ty);
- else if ((Name == "cos" && TLI->has(LibFunc::cos)) ||
- (Name == "cosf" && TLI->has(LibFunc::cosf)))
+ else if ((Name == "cos" && TLI->has(LibFunc_cos)) ||
+ (Name == "cosf" && TLI->has(LibFunc_cosf)))
return ConstantFoldFP(cos, V, Ty);
- else if ((Name == "cosh" && TLI->has(LibFunc::cosh)) ||
- (Name == "coshf" && TLI->has(LibFunc::coshf)))
+ else if ((Name == "cosh" && TLI->has(LibFunc_cosh)) ||
+ (Name == "coshf" && TLI->has(LibFunc_coshf)))
return ConstantFoldFP(cosh, V, Ty);
break;
case 'e':
- if ((Name == "exp" && TLI->has(LibFunc::exp)) ||
- (Name == "expf" && TLI->has(LibFunc::expf)))
+ if ((Name == "exp" && TLI->has(LibFunc_exp)) ||
+ (Name == "expf" && TLI->has(LibFunc_expf)))
return ConstantFoldFP(exp, V, Ty);
- if ((Name == "exp2" && TLI->has(LibFunc::exp2)) ||
- (Name == "exp2f" && TLI->has(LibFunc::exp2f)))
+ if ((Name == "exp2" && TLI->has(LibFunc_exp2)) ||
+ (Name == "exp2f" && TLI->has(LibFunc_exp2f)))
// Constant fold exp2(x) as pow(2,x) in case the host doesn't have a
// C99 library.
return ConstantFoldBinaryFP(pow, 2.0, V, Ty);
break;
case 'f':
- if ((Name == "fabs" && TLI->has(LibFunc::fabs)) ||
- (Name == "fabsf" && TLI->has(LibFunc::fabsf)))
+ if ((Name == "fabs" && TLI->has(LibFunc_fabs)) ||
+ (Name == "fabsf" && TLI->has(LibFunc_fabsf)))
return ConstantFoldFP(fabs, V, Ty);
- else if ((Name == "floor" && TLI->has(LibFunc::floor)) ||
- (Name == "floorf" && TLI->has(LibFunc::floorf)))
+ else if ((Name == "floor" && TLI->has(LibFunc_floor)) ||
+ (Name == "floorf" && TLI->has(LibFunc_floorf)))
return ConstantFoldFP(floor, V, Ty);
break;
case 'l':
- if ((Name == "log" && V > 0 && TLI->has(LibFunc::log)) ||
- (Name == "logf" && V > 0 && TLI->has(LibFunc::logf)))
+ if ((Name == "log" && V > 0 && TLI->has(LibFunc_log)) ||
+ (Name == "logf" && V > 0 && TLI->has(LibFunc_logf)))
return ConstantFoldFP(log, V, Ty);
- else if ((Name == "log10" && V > 0 && TLI->has(LibFunc::log10)) ||
- (Name == "log10f" && V > 0 && TLI->has(LibFunc::log10f)))
+ else if ((Name == "log10" && V > 0 && TLI->has(LibFunc_log10)) ||
+ (Name == "log10f" && V > 0 && TLI->has(LibFunc_log10f)))
return ConstantFoldFP(log10, V, Ty);
- else if (IntrinsicID == Intrinsic::sqrt &&
- (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy())) {
- if (V >= -0.0)
- return ConstantFoldFP(sqrt, V, Ty);
- else {
- // Unlike the sqrt definitions in C/C++, POSIX, and IEEE-754 - which
- // all guarantee or favor returning NaN - the square root of a
- // negative number is not defined for the LLVM sqrt intrinsic.
- // This is because the intrinsic should only be emitted in place of
- // libm's sqrt function when using "no-nans-fp-math".
- return UndefValue::get(Ty);
- }
- }
break;
case 'r':
- if ((Name == "round" && TLI->has(LibFunc::round)) ||
- (Name == "roundf" && TLI->has(LibFunc::roundf)))
+ if ((Name == "round" && TLI->has(LibFunc_round)) ||
+ (Name == "roundf" && TLI->has(LibFunc_roundf)))
return ConstantFoldFP(round, V, Ty);
case 's':
- if ((Name == "sin" && TLI->has(LibFunc::sin)) ||
- (Name == "sinf" && TLI->has(LibFunc::sinf)))
+ if ((Name == "sin" && TLI->has(LibFunc_sin)) ||
+ (Name == "sinf" && TLI->has(LibFunc_sinf)))
return ConstantFoldFP(sin, V, Ty);
- else if ((Name == "sinh" && TLI->has(LibFunc::sinh)) ||
- (Name == "sinhf" && TLI->has(LibFunc::sinhf)))
+ else if ((Name == "sinh" && TLI->has(LibFunc_sinh)) ||
+ (Name == "sinhf" && TLI->has(LibFunc_sinhf)))
return ConstantFoldFP(sinh, V, Ty);
- else if ((Name == "sqrt" && V >= 0 && TLI->has(LibFunc::sqrt)) ||
- (Name == "sqrtf" && V >= 0 && TLI->has(LibFunc::sqrtf)))
+ else if ((Name == "sqrt" && V >= 0 && TLI->has(LibFunc_sqrt)) ||
+ (Name == "sqrtf" && V >= 0 && TLI->has(LibFunc_sqrtf)))
return ConstantFoldFP(sqrt, V, Ty);
break;
case 't':
- if ((Name == "tan" && TLI->has(LibFunc::tan)) ||
- (Name == "tanf" && TLI->has(LibFunc::tanf)))
+ if ((Name == "tan" && TLI->has(LibFunc_tan)) ||
+ (Name == "tanf" && TLI->has(LibFunc_tanf)))
return ConstantFoldFP(tan, V, Ty);
- else if ((Name == "tanh" && TLI->has(LibFunc::tanh)) ||
- (Name == "tanhf" && TLI->has(LibFunc::tanhf)))
+ else if ((Name == "tanh" && TLI->has(LibFunc_tanh)) ||
+ (Name == "tanhf" && TLI->has(LibFunc_tanhf)))
return ConstantFoldFP(tanh, V, Ty);
break;
default:
@@ -1779,7 +1768,8 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,
}
if (isa<UndefValue>(Operands[0])) {
- if (IntrinsicID == Intrinsic::bswap)
+ if (IntrinsicID == Intrinsic::bswap ||
+ IntrinsicID == Intrinsic::bitreverse)
return Operands[0];
return nullptr;
}
@@ -1822,14 +1812,14 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,
if (!TLI)
return nullptr;
- if ((Name == "pow" && TLI->has(LibFunc::pow)) ||
- (Name == "powf" && TLI->has(LibFunc::powf)))
+ if ((Name == "pow" && TLI->has(LibFunc_pow)) ||
+ (Name == "powf" && TLI->has(LibFunc_powf)))
return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty);
- if ((Name == "fmod" && TLI->has(LibFunc::fmod)) ||
- (Name == "fmodf" && TLI->has(LibFunc::fmodf)))
+ if ((Name == "fmod" && TLI->has(LibFunc_fmod)) ||
+ (Name == "fmodf" && TLI->has(LibFunc_fmodf)))
return ConstantFoldBinaryFP(fmod, Op1V, Op2V, Ty);
- if ((Name == "atan2" && TLI->has(LibFunc::atan2)) ||
- (Name == "atan2f" && TLI->has(LibFunc::atan2f)))
+ if ((Name == "atan2" && TLI->has(LibFunc_atan2)) ||
+ (Name == "atan2f" && TLI->has(LibFunc_atan2f)))
return ConstantFoldBinaryFP(atan2, Op1V, Op2V, Ty);
} else if (auto *Op2C = dyn_cast<ConstantInt>(Operands[1])) {
if (IntrinsicID == Intrinsic::powi && Ty->isHalfTy())
@@ -2022,7 +2012,7 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {
if (!F)
return false;
- LibFunc::Func Func;
+ LibFunc Func;
if (!TLI || !TLI->getLibFunc(*F, Func))
return false;
@@ -2030,20 +2020,20 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {
if (ConstantFP *OpC = dyn_cast<ConstantFP>(CS.getArgOperand(0))) {
const APFloat &Op = OpC->getValueAPF();
switch (Func) {
- case LibFunc::logl:
- case LibFunc::log:
- case LibFunc::logf:
- case LibFunc::log2l:
- case LibFunc::log2:
- case LibFunc::log2f:
- case LibFunc::log10l:
- case LibFunc::log10:
- case LibFunc::log10f:
+ case LibFunc_logl:
+ case LibFunc_log:
+ case LibFunc_logf:
+ case LibFunc_log2l:
+ case LibFunc_log2:
+ case LibFunc_log2f:
+ case LibFunc_log10l:
+ case LibFunc_log10:
+ case LibFunc_log10f:
return Op.isNaN() || (!Op.isZero() && !Op.isNegative());
- case LibFunc::expl:
- case LibFunc::exp:
- case LibFunc::expf:
+ case LibFunc_expl:
+ case LibFunc_exp:
+ case LibFunc_expf:
// FIXME: These boundaries are slightly conservative.
if (OpC->getType()->isDoubleTy())
return Op.compare(APFloat(-745.0)) != APFloat::cmpLessThan &&
@@ -2053,9 +2043,9 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {
Op.compare(APFloat(88.0f)) != APFloat::cmpGreaterThan;
break;
- case LibFunc::exp2l:
- case LibFunc::exp2:
- case LibFunc::exp2f:
+ case LibFunc_exp2l:
+ case LibFunc_exp2:
+ case LibFunc_exp2f:
// FIXME: These boundaries are slightly conservative.
if (OpC->getType()->isDoubleTy())
return Op.compare(APFloat(-1074.0)) != APFloat::cmpLessThan &&
@@ -2065,17 +2055,17 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {
Op.compare(APFloat(127.0f)) != APFloat::cmpGreaterThan;
break;
- case LibFunc::sinl:
- case LibFunc::sin:
- case LibFunc::sinf:
- case LibFunc::cosl:
- case LibFunc::cos:
- case LibFunc::cosf:
+ case LibFunc_sinl:
+ case LibFunc_sin:
+ case LibFunc_sinf:
+ case LibFunc_cosl:
+ case LibFunc_cos:
+ case LibFunc_cosf:
return !Op.isInfinity();
- case LibFunc::tanl:
- case LibFunc::tan:
- case LibFunc::tanf: {
+ case LibFunc_tanl:
+ case LibFunc_tan:
+ case LibFunc_tanf: {
// FIXME: Stop using the host math library.
// FIXME: The computation isn't done in the right precision.
Type *Ty = OpC->getType();
@@ -2086,23 +2076,23 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {
break;
}
- case LibFunc::asinl:
- case LibFunc::asin:
- case LibFunc::asinf:
- case LibFunc::acosl:
- case LibFunc::acos:
- case LibFunc::acosf:
+ case LibFunc_asinl:
+ case LibFunc_asin:
+ case LibFunc_asinf:
+ case LibFunc_acosl:
+ case LibFunc_acos:
+ case LibFunc_acosf:
return Op.compare(APFloat(Op.getSemantics(), "-1")) !=
APFloat::cmpLessThan &&
Op.compare(APFloat(Op.getSemantics(), "1")) !=
APFloat::cmpGreaterThan;
- case LibFunc::sinh:
- case LibFunc::cosh:
- case LibFunc::sinhf:
- case LibFunc::coshf:
- case LibFunc::sinhl:
- case LibFunc::coshl:
+ case LibFunc_sinh:
+ case LibFunc_cosh:
+ case LibFunc_sinhf:
+ case LibFunc_coshf:
+ case LibFunc_sinhl:
+ case LibFunc_coshl:
// FIXME: These boundaries are slightly conservative.
if (OpC->getType()->isDoubleTy())
return Op.compare(APFloat(-710.0)) != APFloat::cmpLessThan &&
@@ -2112,9 +2102,9 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {
Op.compare(APFloat(89.0f)) != APFloat::cmpGreaterThan;
break;
- case LibFunc::sqrtl:
- case LibFunc::sqrt:
- case LibFunc::sqrtf:
+ case LibFunc_sqrtl:
+ case LibFunc_sqrt:
+ case LibFunc_sqrtf:
return Op.isNaN() || Op.isZero() || !Op.isNegative();
// FIXME: Add more functions: sqrt_finite, atanh, expm1, log1p,
@@ -2133,9 +2123,9 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {
const APFloat &Op1 = Op1C->getValueAPF();
switch (Func) {
- case LibFunc::powl:
- case LibFunc::pow:
- case LibFunc::powf: {
+ case LibFunc_powl:
+ case LibFunc_pow:
+ case LibFunc_powf: {
// FIXME: Stop using the host math library.
// FIXME: The computation isn't done in the right precision.
Type *Ty = Op0C->getType();
@@ -2149,9 +2139,9 @@ bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {
break;
}
- case LibFunc::fmodl:
- case LibFunc::fmod:
- case LibFunc::fmodf:
+ case LibFunc_fmodl:
+ case LibFunc_fmod:
+ case LibFunc_fmodf:
return Op0.isNaN() || Op1.isNaN() ||
(!Op0.isInfinity() && !Op1.isZero());