Index: llvm/trunk/docs/LangRef.rst =================================================================== --- llvm/trunk/docs/LangRef.rst +++ llvm/trunk/docs/LangRef.rst @@ -14459,10 +14459,10 @@ 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. Index: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp =================================================================== --- llvm/trunk/lib/Analysis/MemoryBuiltins.cpp +++ llvm/trunk/lib/Analysis/MemoryBuiltins.cpp @@ -642,7 +642,14 @@ 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); } Index: llvm/trunk/test/Transforms/CodeGenPrepare/basic.ll =================================================================== --- llvm/trunk/test/Transforms/CodeGenPrepare/basic.ll +++ llvm/trunk/test/Transforms/CodeGenPrepare/basic.ll @@ -46,7 +46,7 @@ ; 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 @@ 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 Index: llvm/trunk/test/Transforms/InstCombine/objsize.ll =================================================================== --- llvm/trunk/test/Transforms/InstCombine/objsize.ll +++ llvm/trunk/test/Transforms/InstCombine/objsize.ll @@ -271,7 +271,7 @@ ; 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 @@ } ; 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 @@ } ; 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 @@ } ; 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)