[PATCH] D37933: Prevent InstCombine from miscompiling `operator delete`
Davide Italiano via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 15 14:42:09 PDT 2017
davide created this revision.
It's not legal inventing calls to operator delete.
https://reviews.llvm.org/D37933
Files:
include/llvm/Analysis/MemoryBuiltins.h
lib/Analysis/MemoryBuiltins.cpp
lib/Transforms/InstCombine/InstructionCombining.cpp
test/Transforms/InstCombine/pr34581.ll
Index: test/Transforms/InstCombine/pr34581.ll
===================================================================
--- /dev/null
+++ test/Transforms/InstCombine/pr34581.ll
@@ -0,0 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; Instcombine is not free of doing anything hazy like hoisting calls to operator
+; delete. This is PR34581.
+
+; RUN: opt -instcombine %s -S | FileCheck %s
+
+define void @patatino(i8* %c) #0 {
+; CHECK-LABEL: @patatino(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq i8* [[C:%.*]], null
+; CHECK-NEXT: br i1 [[ISNULL]], label [[DELETE_END:%.*]], label [[DELETE_NOTNULL:%.*]]
+; CHECK: delete.notnull:
+; CHECK-NEXT: call void @_ZdlPv(i8* [[C]])
+; CHECK-NEXT: br label [[DELETE_END]]
+; CHECK: delete.end:
+; CHECK-NEXT: ret void
+;
+entry:
+ %isnull = icmp eq i8* %c, null
+ br i1 %isnull, label %delete.end, label %delete.notnull
+
+delete.notnull:
+ call void @_ZdlPv(i8* %c)
+ br label %delete.end
+
+delete.end:
+ ret void
+}
+
+declare void @_ZdlPv(i8*)
+
+attributes #0 = { minsize }
Index: lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- lib/Transforms/InstCombine/InstructionCombining.cpp
+++ lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2247,7 +2247,9 @@
// if (foo) free(foo);
// into
// free(foo);
- if (MinimizeSize)
+ // Note we can't really do it in the case of `operator delete` as this one
+ // can have visible side effects.
+ if (MinimizeSize && !hasSideEffectsFreeCall(&FI, TLI))
if (Instruction *I = tryToMoveFreeBeforeNullTest(FI))
return I;
Index: lib/Analysis/MemoryBuiltins.cpp
===================================================================
--- lib/Analysis/MemoryBuiltins.cpp
+++ lib/Analysis/MemoryBuiltins.cpp
@@ -348,6 +348,26 @@
return isCallocLikeFn(I, TLI) ? cast<CallInst>(I) : nullptr;
}
+/// hasSideEffectsFreeCall - Returns true if the call has side effects.
+bool llvm::hasSideEffectsFreeCall(const CallInst *CI,
+ const TargetLibraryInfo &TLI) {
+ Function *Callee = CI->getCalledFunction();
+ if (Callee == nullptr)
+ return false;
+
+ StringRef FnName = Callee->getName();
+ LibFunc TLIFn;
+ if (!TLI.getLibFunc(FnName, TLIFn) || !TLI.has(TLIFn))
+ return false;
+
+ return TLIFn == LibFunc_ZdlPv || // operator delete(void*)
+ TLIFn == LibFunc_ZdaPv || // operator delete[](void*)
+ TLIFn == LibFunc_msvc_delete_ptr32 || // operator delete(void*)
+ TLIFn == LibFunc_msvc_delete_ptr64 || // operator delete(void*)
+ TLIFn == LibFunc_msvc_delete_array_ptr32 || // operator delete[](void*)
+ TLIFn == LibFunc_msvc_delete_array_ptr64; // operator delete[](void*)
+}
+
/// isFreeCall - Returns non-null if the value is a call to the builtin free()
const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) {
const CallInst *CI = dyn_cast<CallInst>(I);
Index: include/llvm/Analysis/MemoryBuiltins.h
===================================================================
--- include/llvm/Analysis/MemoryBuiltins.h
+++ include/llvm/Analysis/MemoryBuiltins.h
@@ -137,6 +137,9 @@
// free Call Utility Functions.
//
+/// hasSideEffectsFreeCall - Returns true if the call has side effects.
+bool hasSideEffectsFreeCall(const CallInst *CI, const TargetLibraryInfo &TLI);
+
/// isFreeCall - Returns non-null if the value is a call to the builtin free()
const CallInst *isFreeCall(const Value *I, const TargetLibraryInfo *TLI);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D37933.115501.patch
Type: text/x-patch
Size: 3660 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170915/2af0eab0/attachment-0001.bin>
More information about the llvm-commits
mailing list