summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Reames <listmail@philipreames.com>2022-01-08 10:29:09 -0800
committerPhilip Reames <listmail@philipreames.com>2022-01-08 10:33:54 -0800
commit2cafbcb560d9e6e2300941d088e754b01d56595b (patch)
treeb40ef1247630614efadd8164e563e26b6daeaff5
parent6ce732cbadf7b474da1108dc7b3b473b80944aa5 (diff)
downloadllvm-2cafbcb560d9e6e2300941d088e754b01d56595b.tar.gz
[instcombine] Key deref vs deref_or_null annotation of allocation sites off nonnull attribute
Goal is to remove use of isOpNewLike. I looked at a couple approaches to this, and this turned out to be the cheapest one. Just letting deref_or_null be generated causes a bunch of test diffs, and I couldn't convince myself there wasn't a real regression somewhere. A generic instcombine to convert deref_or_null + nonnull to deref is annoying complicated since you have to mix facts from callsite and declaration while manipulating only existing call site attributes. It just wasn't worth the code complexity. Note that the change in new-delete-itanium.ll is a real regression. If you have a callsite which overrides the builtin status of a nobuiltin declaration, *and* you don't put the apppriate attributes on that callsite, you may lose the deref fact. I decided this didn't matter; if anyone disagrees, you can add this case to the generic non-null inference.
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp9
-rw-r--r--llvm/test/Transforms/InstCombine/new-delete-itanium.ll4
-rw-r--r--llvm/test/Transforms/InstCombine/objsize-64.ll4
3 files changed, 11 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index afd1ef2753cc..33450b7eb137 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2571,12 +2571,17 @@ static IntrinsicInst *findInitTrampoline(Value *Callee) {
}
void InstCombinerImpl::annotateAnyAllocSite(CallBase &Call, const TargetLibraryInfo *TLI) {
+ // Note: We only handle cases which can't be driven from generic attributes
+ // here. So, for example, nonnull and noalias (which are common properties
+ // of some allocation functions) are expected to be handled via annotation
+ // of the respective allocator declaration with generic attributes.
uint64_t Size;
ObjectSizeOpts Opts;
if (getObjectSize(&Call, Size, DL, TLI, Opts) && Size > 0) {
- // TODO: should be annotating these nonnull
- if (isOpNewLikeFn(&Call, TLI))
+ // TODO: We really should just emit deref_or_null here and then
+ // let the generic inference code combine that with nonnull.
+ if (Call.hasRetAttr(Attribute::NonNull))
Call.addRetAttr(Attribute::getWithDereferenceableBytes(
Call.getContext(), Size));
else
diff --git a/llvm/test/Transforms/InstCombine/new-delete-itanium.ll b/llvm/test/Transforms/InstCombine/new-delete-itanium.ll
index d2044fa05c02..4f0470c8a159 100644
--- a/llvm/test/Transforms/InstCombine/new-delete-itanium.ll
+++ b/llvm/test/Transforms/InstCombine/new-delete-itanium.ll
@@ -201,8 +201,8 @@ define void @test10() {
define void @test11() {
; CHECK-LABEL: @test11(
-; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable(8) i8* @_Znwm(i64 8) #[[ATTR5]]
-; CHECK-NEXT: call void @_ZdlPv(i8* nonnull [[CALL]])
+; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(8) i8* @_Znwm(i64 8) #[[ATTR5]]
+; CHECK-NEXT: call void @_ZdlPv(i8* [[CALL]])
; CHECK-NEXT: ret void
;
%call = call i8* @_Znwm(i64 8) builtin
diff --git a/llvm/test/Transforms/InstCombine/objsize-64.ll b/llvm/test/Transforms/InstCombine/objsize-64.ll
index 06ad232fce09..4a8522f90b5c 100644
--- a/llvm/test/Transforms/InstCombine/objsize-64.ll
+++ b/llvm/test/Transforms/InstCombine/objsize-64.ll
@@ -3,7 +3,7 @@
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
declare noalias i8* @malloc(i32) nounwind
-declare noalias i8* @_Znwm(i64) ; new(unsigned long)
+declare noalias nonnull i8* @_Znwm(i64) ; new(unsigned long)
declare i32 @__gxx_personality_v0(...)
declare void @__cxa_call_unexpected(i8*)
declare i64 @llvm.objectsize.i64(i8*, i1) nounwind readonly
@@ -33,7 +33,7 @@ define i64 @f2(i8** %esc) nounwind uwtable ssp personality i8* bitcast (i32 (...
; CHECK-NEXT: [[TMP0:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT: filter [0 x i8*] zeroinitializer
; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 0
-; CHECK-NEXT: tail call void @__cxa_call_unexpected(i8* [[TMP1]]) #3
+; CHECK-NEXT: tail call void @__cxa_call_unexpected(i8* [[TMP1]]) #[[ATTR3:[0-9]+]]
; CHECK-NEXT: unreachable
;
entry: