aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/MemoryBuiltins.cpp11
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp3
-rw-r--r--llvm/lib/Transforms/InstCombine/InstructionCombining.cpp2
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp2
4 files changed, 16 insertions, 2 deletions
diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp
index 213fdc5a..48c01fb 100644
--- a/llvm/lib/Analysis/MemoryBuiltins.cpp
+++ b/llvm/lib/Analysis/MemoryBuiltins.cpp
@@ -298,6 +298,17 @@ bool llvm::isStrdupLikeFn(const Value *V, const TargetLibraryInfo *TLI) {
return getAllocationData(V, StrDupLike, TLI).hasValue();
}
+bool llvm::isAllocRemovable(const CallBase *CB, const TargetLibraryInfo *TLI) {
+ assert(isAllocationFn(CB, TLI));
+
+ // Note: Removability is highly dependent on the source language. For
+ // example, recent C++ requires direct calls to the global allocation
+ // [basic.stc.dynamic.allocation] to be observable unless part of a new
+ // expression [expr.new paragraph 13].
+
+ // Historically we've treated the C family allocation routines as removable
+ return isAllocLikeFn(CB, TLI);
+}
Value *llvm::getAllocAlignment(const CallBase *V,
const TargetLibraryInfo *TLI) {
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 7904242..22c736f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2761,7 +2761,8 @@ Instruction *InstCombinerImpl::visitCallBase(CallBase &Call) {
Call, Builder.CreateBitOrPointerCast(ReturnedArg, CallTy));
}
- if (isAllocLikeFn(&Call, &TLI))
+ if (isAllocationFn(&Call, &TLI) &&
+ isAllocRemovable(&cast<CallBase>(Call), &TLI))
return visitAllocSite(Call);
// Handle intrinsics which can be used in both call and invoke context.
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 31329ae..6d5548d 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2696,6 +2696,8 @@ static bool isAllocSiteRemovable(Instruction *AI,
}
Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
+ assert(isa<AllocaInst>(MI) || isAllocRemovable(&cast<CallBase>(MI), &TLI));
+
// If we have a malloc call which is only used in any amount of comparisons to
// null and free calls, delete the calls and replace the comparisons with true
// or false as appropriate.
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index efc5396..3ea82e1 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -492,7 +492,7 @@ bool llvm::wouldInstructionBeTriviallyDead(Instruction *I,
}
}
- if (isAllocLikeFn(I, TLI))
+ if (isAllocationFn(I, TLI) && isAllocRemovable(cast<CallBase>(I), TLI))
return true;
if (CallInst *CI = isFreeCall(I, TLI))