summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/docs/LangRef.rst8
-rw-r--r--llvm/lib/Analysis/MemoryBuiltins.cpp9
-rw-r--r--llvm/test/Transforms/CodeGenPrepare/basic.ll20
-rw-r--r--llvm/test/Transforms/InstCombine/objsize.ll8
4 files changed, 35 insertions, 10 deletions
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 64eca1c3f7b..57abe7f9067 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -14459,10 +14459,10 @@ The ``llvm.objectsize`` intrinsic takes three arguments. The first argument is
a pointer to or into the ``object``. The second argument determines whether
``llvm.objectsize`` returns 0 (if true) or -1 (if false) when the object size
is unknown. The third argument controls how ``llvm.objectsize`` acts when
-``null`` is used as its pointer argument. If it's true and the pointer is in
-address space 0, ``null`` is treated as an opaque value with an unknown number
-of bytes. Otherwise, ``llvm.objectsize`` reports 0 bytes available when given
-``null``.
+``null`` in address space 0 is used as its pointer argument. If it's ``false``,
+``llvm.objectsize`` reports 0 bytes available when given ``null``. Otherwise, if
+the ``null`` is in a non-zero address space or if ``true`` is given for the
+third argument of ``llvm.objectsize``, we assume its size is unknown.
The second and third arguments only accept constants.
diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp
index deacdb9e324..686ad294378 100644
--- a/llvm/lib/Analysis/MemoryBuiltins.cpp
+++ b/llvm/lib/Analysis/MemoryBuiltins.cpp
@@ -642,7 +642,14 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitCallSite(CallSite CS) {
SizeOffsetType
ObjectSizeOffsetVisitor::visitConstantPointerNull(ConstantPointerNull& CPN) {
- if (Options.NullIsUnknownSize && CPN.getType()->getAddressSpace() == 0)
+ // If null is unknown, there's nothing we can do. Additionally, non-zero
+ // address spaces can make use of null, so we don't presume to know anything
+ // about that.
+ //
+ // TODO: How should this work with address space casts? We currently just drop
+ // them on the floor, but it's unclear what we should do when a NULL from
+ // addrspace(1) gets casted to addrspace(0) (or vice-versa).
+ if (Options.NullIsUnknownSize || CPN.getType()->getAddressSpace())
return unknown();
return std::make_pair(Zero, Zero);
}
diff --git a/llvm/test/Transforms/CodeGenPrepare/basic.ll b/llvm/test/Transforms/CodeGenPrepare/basic.ll
index b8ca6d6cde9..768209abcdf 100644
--- a/llvm/test/Transforms/CodeGenPrepare/basic.ll
+++ b/llvm/test/Transforms/CodeGenPrepare/basic.ll
@@ -46,7 +46,7 @@ entry:
; CHECK-LABEL: @test_objectsize_null_flag_noas0(
define i64 @test_objectsize_null_flag_noas0() {
entry:
- ; CHECK: ret i64 0
+ ; CHECK: ret i64 -1
%0 = tail call i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)* null, i1 false,
i1 true)
ret i64 %0
@@ -61,6 +61,24 @@ entry:
ret i64 %0
}
+; CHECK-LABEL: @test_objectsize_null_known_flag_noas0
+define i64 @test_objectsize_null_known_flag_noas0() {
+entry:
+ ; CHECK: ret i64 -1
+ %0 = tail call i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)* null, i1 false,
+ i1 false)
+ ret i64 %0
+}
+
+; CHECK-LABEL: @test_objectsize_null_known_flag_min_noas0
+define i64 @test_objectsize_null_known_flag_min_noas0() {
+entry:
+ ; CHECK: ret i64 0
+ %0 = tail call i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)* null, i1 true,
+ i1 false)
+ ret i64 %0
+}
+
declare i64 @llvm.objectsize.i64(i8*, i1, i1) nounwind readonly
declare i64 @llvm.objectsize.i64.p1i8(i8 addrspace(1)*, i1, i1) nounwind readonly
diff --git a/llvm/test/Transforms/InstCombine/objsize.ll b/llvm/test/Transforms/InstCombine/objsize.ll
index 86b087567e2..12262c03670 100644
--- a/llvm/test/Transforms/InstCombine/objsize.ll
+++ b/llvm/test/Transforms/InstCombine/objsize.ll
@@ -271,7 +271,7 @@ define i32 @test23() {
; 1 is an arbitrary non-zero address space.
; CHECK-LABEL: @test24(
-; CHECK: ret i32 0
+; CHECK: llvm.objectsize
define i32 @test24() {
%1 = call i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1 false,
i1 false)
@@ -279,7 +279,7 @@ define i32 @test24() {
}
; CHECK-LABEL: @test25(
-; CHECK: ret i32 0
+; CHECK: llvm.objectsize
define i32 @test25() {
%1 = call i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1 true,
i1 false)
@@ -287,7 +287,7 @@ define i32 @test25() {
}
; CHECK-LABEL: @test26(
-; CHECK: ret i32 0
+; CHECK: llvm.objectsize
define i32 @test26() {
%1 = call i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1 false,
i1 true)
@@ -295,7 +295,7 @@ define i32 @test26() {
}
; CHECK-LABEL: @test27(
-; CHECK: ret i32 0
+; CHECK: llvm.objectsize
define i32 @test27() {
%1 = call i32 @llvm.objectsize.i32.p1i8(i8 addrspace(1)* null, i1 true,
i1 true)
OpenPOWER on IntegriCloud