diff options
author | James Y Knight <jyknight@google.com> | 2018-11-07 15:24:12 +0000 |
---|---|---|
committer | James Y Knight <jyknight@google.com> | 2018-11-07 15:24:12 +0000 |
commit | 72f76bf2309a0beb4fbc0418a0f71242b530969f (patch) | |
tree | fca67afdb5fa4cefd285d0671ff8335ffb261466 /llvm/lib/Analysis/ConstantFolding.cpp | |
parent | 76faf5145df17deff4a278e938918ea71817e74c (diff) | |
download | bcm5719-llvm-72f76bf2309a0beb4fbc0418a0f71242b530969f.tar.gz bcm5719-llvm-72f76bf2309a0beb4fbc0418a0f71242b530969f.zip |
Add support for llvm.is.constant intrinsic (PR4898)
This adds the llvm-side support for post-inlining evaluation of the
__builtin_constant_p GCC intrinsic.
Also fixed SCCPSolver::visitCallSite to not blow up when seeing a call
to a function where canConstantFoldTo returns true, and one of the
arguments is a struct.
Updated from patch initially by Janusz Sobczak.
Differential Revision: https://reviews.llvm.org/D4276
llvm-svn: 346322
Diffstat (limited to 'llvm/lib/Analysis/ConstantFolding.cpp')
-rw-r--r-- | llvm/lib/Analysis/ConstantFolding.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index 9ae8f1728c2..92b05559137 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -1426,6 +1426,7 @@ bool llvm::canConstantFoldCallTo(ImmutableCallSite CS, const Function *F) { case Intrinsic::x86_avx512_vcvtsd2usi64: case Intrinsic::x86_avx512_cvttsd2usi: case Intrinsic::x86_avx512_cvttsd2usi64: + case Intrinsic::is_constant: return true; default: return false; @@ -1600,11 +1601,32 @@ double getValueAsDouble(ConstantFP *Op) { return APF.convertToDouble(); } +static bool isManifestConstant(const Constant *c) { + if (isa<ConstantData>(c)) { + return true; + } else if (isa<ConstantAggregate>(c) || isa<ConstantExpr>(c)) { + for (const Value *subc : c->operand_values()) { + if (!isManifestConstant(cast<Constant>(subc))) + return false; + } + return true; + } + return false; +} + Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty, ArrayRef<Constant *> Operands, const TargetLibraryInfo *TLI, ImmutableCallSite CS) { if (Operands.size() == 1) { + if (IntrinsicID == Intrinsic::is_constant) { + // We know we have a "Constant" argument. But we want to only + // return true for manifest constants, not those that depend on + // constants with unknowable values, e.g. GlobalValue or BlockAddress. + if (isManifestConstant(Operands[0])) + return ConstantInt::getTrue(Ty->getContext()); + return nullptr; + } if (isa<UndefValue>(Operands[0])) { // cosine(arg) is between -1 and 1. cosine(invalid arg) is NaN if (IntrinsicID == Intrinsic::cos) |