summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/StackProtector.cpp
diff options
context:
space:
mode:
authorMatt Davis <Matthew.Davis@sony.com>2018-04-06 20:14:13 +0000
committerMatt Davis <Matthew.Davis@sony.com>2018-04-06 20:14:13 +0000
commit13b8331054a4a8434e1dbdca03ee4776b738be8a (patch)
tree58b8c6bccf9870c96cc20105dfc1b69753ad3eb4 /llvm/lib/CodeGen/StackProtector.cpp
parenteea7062c3a131718efe63f83499d9d78183cc85b (diff)
downloadbcm5719-llvm-13b8331054a4a8434e1dbdca03ee4776b738be8a.tar.gz
bcm5719-llvm-13b8331054a4a8434e1dbdca03ee4776b738be8a.zip
[StackProtector] Ignore certain intrinsics when calculating sspstrong heuristic.
Summary: The 'strong' StackProtector heuristic takes into consideration call instructions. Certain intrinsics, such as lifetime.start, can cause the StackProtector to protect functions that do not need to be protected. Specifically, a volatile variable, (not optimized away), but belonging to a stack allocation will encourage a llvm.lifetime.start to be inserted during compilation. Because that intrinsic is a 'call' the strong StackProtector will see that the alloca'd variable is being passed to a call instruction, and insert a stack protector. In this case the intrinsic isn't really lowered to a call. This can cause unnecessary stack checking, at the cost of additional (wasted) CPU cycles. In the future we should rely on TargetTransformInfo::isLoweredToCall, but as of now that routine considers all intrinsics as not being lowerable. That needs to be corrected, and such a change is on my list of things to get moving on. As a side note, the updated stack-protector-dbginfo.ll test always seems to pass. I never see the dbg.declare/dbg.value reaching the StackProtector::HasAddressTaken, but I don't see any code excluding dbg intrinsic calls either, so I think it's the safest thing to do. Reviewers: void, timshen Reviewed By: timshen Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D45331 llvm-svn: 329450
Diffstat (limited to 'llvm/lib/CodeGen/StackProtector.cpp')
-rw-r--r--llvm/lib/CodeGen/StackProtector.cpp15
1 files changed, 13 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp
index 62cef95a4af..8a7393501d0 100644
--- a/llvm/lib/CodeGen/StackProtector.cpp
+++ b/llvm/lib/CodeGen/StackProtector.cpp
@@ -36,6 +36,7 @@
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
@@ -182,6 +183,14 @@ bool StackProtector::ContainsProtectableArray(Type *Ty, bool &IsLarge,
return NeedsProtector;
}
+static bool isLifetimeInst(const Instruction *I) {
+ if (const auto Intrinsic = dyn_cast<IntrinsicInst>(I)) {
+ const auto Id = Intrinsic->getIntrinsicID();
+ return Id == Intrinsic::lifetime_start || Id == Intrinsic::lifetime_end;
+ }
+ return false;
+}
+
bool StackProtector::HasAddressTaken(const Instruction *AI) {
for (const User *U : AI->users()) {
if (const StoreInst *SI = dyn_cast<StoreInst>(U)) {
@@ -190,8 +199,10 @@ bool StackProtector::HasAddressTaken(const Instruction *AI) {
} else if (const PtrToIntInst *SI = dyn_cast<PtrToIntInst>(U)) {
if (AI == SI->getOperand(0))
return true;
- } else if (isa<CallInst>(U)) {
- return true;
+ } else if (const CallInst *CI = dyn_cast<CallInst>(U)) {
+ // Ignore intrinsics that are not calls. TODO: Use isLoweredToCall().
+ if (!isa<DbgInfoIntrinsic>(CI) && !isLifetimeInst(CI))
+ return true;
} else if (isa<InvokeInst>(U)) {
return true;
} else if (const SelectInst *SI = dyn_cast<SelectInst>(U)) {
OpenPOWER on IntegriCloud