[PATCH] D100779: free(nullptr) does not violate the nofree specification
Philip Reames via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 20 09:08:44 PDT 2021
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG3b1474cab26b: free(nullptr) does not violate the nofree specification (authored by reames).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D100779/new/
https://reviews.llvm.org/D100779
Files:
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/test/Transforms/InstCombine/malloc-free-delete.ll
Index: llvm/test/Transforms/InstCombine/malloc-free-delete.ll
===================================================================
--- llvm/test/Transforms/InstCombine/malloc-free-delete.ll
+++ llvm/test/Transforms/InstCombine/malloc-free-delete.ll
@@ -391,32 +391,45 @@
ret void
}
-; Freeing a no-free pointer -> full UB
+; Freeing a no-free pointer -> %foo must be null
define void @test13(i8* nofree %foo) {
; CHECK-LABEL: @test13(
-; CHECK-NEXT: store i1 true, i1* undef, align 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* [[FOO:%.*]], null
+; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
; CHECK-NEXT: ret void
;
call void @free(i8* %foo)
ret void
}
-; Freeing a no-free pointer -> full UB
+; Freeing a no-free pointer -> %foo must be null
define void @test14(i8* %foo) nofree {
; CHECK-LABEL: @test14(
-; CHECK-NEXT: store i1 true, i1* undef, align 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* [[FOO:%.*]], null
+; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
; CHECK-NEXT: ret void
;
call void @free(i8* %foo)
ret void
}
-; free call marked no-free -> full UB
+; free call marked no-free -> %foo must be null
define void @test15(i8* %foo) {
; CHECK-LABEL: @test15(
-; CHECK-NEXT: store i1 true, i1* undef, align 1
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* [[FOO:%.*]], null
+; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
; CHECK-NEXT: ret void
;
call void @free(i8* %foo) nofree
ret void
}
+
+; freeing a nonnull nofree pointer -> full UB
+define void @test16(i8* nonnull nofree %foo) {
+; CHECK-LABEL: @test16(
+; CHECK-NEXT: call void @llvm.assume(i1 false)
+; CHECK-NEXT: ret void
+;
+ call void @free(i8* %foo)
+ ret void
+}
Index: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2799,8 +2799,10 @@
if (isa<ConstantPointerNull>(Op))
return eraseInstFromFunction(FI);
- // If we free a pointer we've been explicitly told won't be freed, this
- // would be full UB and thus we can conclude this is unreachable. Cases:
+
+ // If we free a non-null pointer we've been explicitly told won't be freed,
+ // this would be full UB and thus we can conclude that the argument must
+ // be null at the point of the free. Cases:
// 1) freeing a pointer which is explicitly nofree
// 2) calling free from a call site marked nofree (TODO: can generalize
// for non-arguments)
@@ -2810,8 +2812,9 @@
if (A->hasAttribute(Attribute::NoFree) ||
FI.hasFnAttr(Attribute::NoFree) ||
FI.getFunction()->hasFnAttribute(Attribute::NoFree)) {
- // Leave a marker since we can't modify the CFG here.
- CreateNonTerminatorUnreachable(&FI);
+ Value *Null = ConstantPointerNull::get(cast<PointerType>(A->getType()));
+ Value *Cond = Builder.CreateICmpEQ(A, Null);
+ Builder.CreateAssumption(Cond);
return eraseInstFromFunction(FI);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D100779.338890.patch
Type: text/x-patch
Size: 3103 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210420/215992e3/attachment.bin>
More information about the llvm-commits
mailing list