summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/ConstantFolding.cpp
diff options
context:
space:
mode:
authorJames Y Knight <jyknight@google.com>2018-11-07 15:24:12 +0000
committerJames Y Knight <jyknight@google.com>2018-11-07 15:24:12 +0000
commit72f76bf2309a0beb4fbc0418a0f71242b530969f (patch)
treefca67afdb5fa4cefd285d0671ff8335ffb261466 /llvm/lib/Analysis/ConstantFolding.cpp
parent76faf5145df17deff4a278e938918ea71817e74c (diff)
downloadbcm5719-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.cpp22
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)
OpenPOWER on IntegriCloud