From 1fb854a0f5ec500414f7e4fd4eac30357a9dd666 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 16 Aug 2019 16:05:36 +0200 Subject: [PATCH 1/3] Do not generate allocations for zero sized allocations --- src/librustc_codegen_llvm/common.rs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index b0c94a139be08..a2026e1461d8e 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -333,14 +333,19 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { offset: Size, ) -> PlaceRef<'tcx, &'ll Value> { assert_eq!(alloc.align, layout.align.abi); - let init = const_alloc_to_llvm(self, alloc); - let base_addr = self.static_addr_of(init, alloc.align, None); - - let llval = unsafe { llvm::LLVMConstInBoundsGEP( - self.const_bitcast(base_addr, self.type_i8p()), - &self.const_usize(offset.bytes()), - 1, - )}; + let llval = if layout.size == Size::ZERO { + let llval = self.const_usize(alloc.align.bytes()); + unsafe { llvm::LLVMConstIntToPtr(llval, self.type_ptr_to(self.type_i8p())) } + } else { + let init = const_alloc_to_llvm(self, alloc); + let base_addr = self.static_addr_of(init, alloc.align, None); + + unsafe { llvm::LLVMConstInBoundsGEP( + self.const_bitcast(base_addr, self.type_i8p()), + &self.const_usize(offset.bytes()), + 1, + )} + }; let llval = self.const_bitcast(llval, self.type_ptr_to(layout.llvm_type(self))); PlaceRef::new_sized(llval, layout, alloc.align) } From ab949fdd64433749ebb7f8ef516ee2cdfe217a9d Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 17 Aug 2019 11:29:17 +0200 Subject: [PATCH 2/3] Cast only where necessary --- src/librustc_codegen_llvm/common.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index a2026e1461d8e..19f18088579b3 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -333,20 +333,21 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { offset: Size, ) -> PlaceRef<'tcx, &'ll Value> { assert_eq!(alloc.align, layout.align.abi); + let llty = self.type_ptr_to(layout.llvm_type(self)); let llval = if layout.size == Size::ZERO { let llval = self.const_usize(alloc.align.bytes()); - unsafe { llvm::LLVMConstIntToPtr(llval, self.type_ptr_to(self.type_i8p())) } + unsafe { llvm::LLVMConstIntToPtr(llval, llty) } } else { let init = const_alloc_to_llvm(self, alloc); let base_addr = self.static_addr_of(init, alloc.align, None); - unsafe { llvm::LLVMConstInBoundsGEP( + let llval = unsafe { llvm::LLVMConstInBoundsGEP( self.const_bitcast(base_addr, self.type_i8p()), &self.const_usize(offset.bytes()), 1, - )} + )}; + self.const_bitcast(llval, llty) }; - let llval = self.const_bitcast(llval, self.type_ptr_to(layout.llvm_type(self))); PlaceRef::new_sized(llval, layout, alloc.align) } From 1ea88a8689a461638fef31e01e62fffc63ac5b79 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 17 Aug 2019 11:31:09 +0200 Subject: [PATCH 3/3] Add tests --- src/test/ui/consts/zst_no_llvm_alloc.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/test/ui/consts/zst_no_llvm_alloc.rs diff --git a/src/test/ui/consts/zst_no_llvm_alloc.rs b/src/test/ui/consts/zst_no_llvm_alloc.rs new file mode 100644 index 0000000000000..5d779355400cc --- /dev/null +++ b/src/test/ui/consts/zst_no_llvm_alloc.rs @@ -0,0 +1,19 @@ +// run-pass + +#[repr(align(4))] +struct Foo; + +static FOO: Foo = Foo; + +fn main() { + let x: &'static () = &(); + assert_eq!(x as *const () as usize, 1); + let x: &'static Foo = &Foo; + assert_eq!(x as *const Foo as usize, 4); + + // statics must have a unique address + assert_ne!(&FOO as *const Foo as usize, 4); + + assert_eq!(>::new().as_ptr(), <&[i32]>::default().as_ptr()); + assert_eq!(>::default().as_ptr(), (&[]).as_ptr()); +}