Skip to content

Potentially redundant check for zero alignment in generated assembly #91438

@alex65536

Description

@alex65536

Consider the following code with custom DSTs:

pub trait My {
    fn f(&self) -> i32;
}

pub struct Wrapper<T: ?Sized>(i8, T);

pub struct My1<T: My + ?Sized> {
    field: i8,
    my: Wrapper<T>,
}

type DynMy1 = My1<dyn My>;

pub fn run(d: &DynMy1) -> &Wrapper<dyn My> {
    &d.my
}

The generated assembly for x86_64 is as follows (with my comments added):

example::run:
  mov     rdx, rsi                   ; Copy vtable pointer into that of result
  mov     rcx, qword ptr [rsi + 16]  ; Load alignment into rcx
  test    rcx, rcx                   ; Check if the alignment is non-zero (?)
  mov     eax, 1
  cmovne  rax, rcx                   ; If the alignment is zero, then the offset is 1, otherwise it's rcx
  add     rax, rdi                   ; Add offset to base pointer and store into the base pointer of result
  ret

This can be seen on Godbolt.

Why does the compiler check for zero alignment? It seems that it's impossible, as the alignment cannot be zero.

Meta

rustc --version --verbose:

rustc 1.56.0 (09c42c458 2021-10-18)
binary: rustc
commit-hash: 09c42c45858d5f3aedfa670698275303a3d19afa
commit-date: 2021-10-18
host: x86_64-unknown-linux-gnu
release: 1.56.0
LLVM version: 13.0.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-codegenArea: Code generationC-bugCategory: This is a bug.I-slowIssue: Problems and improvements with respect to performance of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions