-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Open
Labels
A-codegenArea: Code generationArea: Code generationC-bugCategory: This is a bug.Category: This is a bug.I-heavyIssue: Problems and improvements with respect to binary size of generated code.Issue: Problems and improvements with respect to binary size of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
Given this code:
struct Obj([u8; 8]);
extern "C" { fn f(o: &Obj); }
pub unsafe fn main()
{
let s = Obj([1,2,3,4,5,6,7,8]);
f(&s);
std::mem::drop(s);
let r = Obj([11,12,13,14,15,16,17,18]);
f(&r);
std::mem::drop(r);
}
It compiles to:
example::main:
push rbx
sub rsp, 16
movabs rax, 578437695752307201
mov qword ptr [rsp], rax
mov rbx, qword ptr [rip + f@GOTPCREL]
mov rdi, rsp
call rbx
movabs rax, 1301839424133073931
mov qword ptr [rsp + 8], rax
lea rdi, [rsp + 8]
call rbx
add rsp, 16
pop rbx
ret
The first value is stored at [rsp]
and the second value at [rsp + 8]
The LLVM IR looks like:
; example::main
; Function Attrs: nounwind nonlazybind uwtable
define void @_ZN7example4main17h377fad6dc64462c1E() unnamed_addr #0 !dbg !6 {
start:
%r = alloca %Obj, align 1
%s = alloca %Obj, align 1
%0 = getelementptr inbounds %Obj, %Obj* %s, i64 0, i32 0, i64 0, !dbg !10
call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %0), !dbg !10
store i8 1, i8* %0, align 1, !dbg !11
%1 = getelementptr inbounds %Obj, %Obj* %s, i64 0, i32 1, i64 1, !dbg !11
store i8 2, i8* %1, align 1, !dbg !11
%2 = getelementptr inbounds %Obj, %Obj* %s, i64 0, i32 1, i64 2, !dbg !11
store i8 3, i8* %2, align 1, !dbg !11
%3 = getelementptr inbounds %Obj, %Obj* %s, i64 0, i32 1, i64 3, !dbg !11
store i8 4, i8* %3, align 1, !dbg !11
%4 = getelementptr inbounds %Obj, %Obj* %s, i64 0, i32 1, i64 4, !dbg !11
store i8 5, i8* %4, align 1, !dbg !11
%5 = getelementptr inbounds %Obj, %Obj* %s, i64 0, i32 1, i64 5, !dbg !11
store i8 6, i8* %5, align 1, !dbg !11
%6 = getelementptr inbounds %Obj, %Obj* %s, i64 0, i32 1, i64 6, !dbg !11
store i8 7, i8* %6, align 1, !dbg !11
%7 = getelementptr inbounds %Obj, %Obj* %s, i64 0, i32 1, i64 7, !dbg !11
store i8 8, i8* %7, align 1, !dbg !11
call void @f(%Obj* noalias nonnull readonly align 1 dereferenceable(8) %s), !dbg !12
%8 = getelementptr inbounds %Obj, %Obj* %r, i64 0, i32 0, i64 0, !dbg !13
call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %8), !dbg !13
store i8 11, i8* %8, align 1, !dbg !14
%9 = getelementptr inbounds %Obj, %Obj* %r, i64 0, i32 1, i64 1, !dbg !14
store i8 12, i8* %9, align 1, !dbg !14
%10 = getelementptr inbounds %Obj, %Obj* %r, i64 0, i32 1, i64 2, !dbg !14
store i8 13, i8* %10, align 1, !dbg !14
%11 = getelementptr inbounds %Obj, %Obj* %r, i64 0, i32 1, i64 3, !dbg !14
store i8 14, i8* %11, align 1, !dbg !14
%12 = getelementptr inbounds %Obj, %Obj* %r, i64 0, i32 1, i64 4, !dbg !14
store i8 15, i8* %12, align 1, !dbg !14
%13 = getelementptr inbounds %Obj, %Obj* %r, i64 0, i32 1, i64 5, !dbg !14
store i8 16, i8* %13, align 1, !dbg !14
%14 = getelementptr inbounds %Obj, %Obj* %r, i64 0, i32 1, i64 6, !dbg !14
store i8 17, i8* %14, align 1, !dbg !14
%15 = getelementptr inbounds %Obj, %Obj* %r, i64 0, i32 1, i64 7, !dbg !14
store i8 18, i8* %15, align 1, !dbg !14
call void @f(%Obj* noalias nonnull readonly align 1 dereferenceable(8) %r), !dbg !15
call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %8), !dbg !16
call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %0), !dbg !16
ret void, !dbg !17
}
The llvm.lifetime.end intrinsic for the first value shows up at the end instead of after the call to drop. If I move it earlier then LLVM does reuse the stack slot.
Acciente717, chuigda, hzqd, Cupnfish, Jancd and 16 more
Metadata
Metadata
Assignees
Labels
A-codegenArea: Code generationArea: Code generationC-bugCategory: This is a bug.Category: This is a bug.I-heavyIssue: Problems and improvements with respect to binary size of generated code.Issue: Problems and improvements with respect to binary size of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.