Skip to content

rustc generates terrible code for is_char_boundary #32471

Closed
@eefriedman

Description

@eefriedman

Testcase:

#![crate_type="rlib"]
trait ZZZ { fn is_char_boundaryx(&self, index: usize) -> bool; }
impl ZZZ for str {
    fn is_char_boundaryx(&self, index: usize) -> bool {
        if index == self.len() { return true; }
        match self.as_bytes().get(index) {
            None => false,
            Some(&b) => b < 128 || b >= 192,
        }
    }
}

Excerpt from the assembly:

    movzbl  (%rdi,%rdx), %eax
    cmpl    $191, %eax
    seta    %cl
    shrb    $7, %al
    xorb    $1, %al
    orb %cl, %al
    setne   %al

This is generated from the expression b < 128 || b >= 192. The code should look more like this:

    movsbl  (%rdi,%rdx), %eax
    cmpl    $-65, %eax
    setg    %al

LLVM probably should be able to perform this optimization, but it looks like it's confusing itself by converting b < 128 into a shift.

CC @bluss.

Metadata

Metadata

Assignees

No one assigned

    Labels

    I-slowIssue: Problems and improvements with respect to performance of generated code.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions