Skip to content

LLVM failed to use the knowledge from a never-overflow assumption #509

Closed
llvm/llvm-project
#84016
@dtcxzyw

Description

@dtcxzyw

Hi all, I am an LLVM developer working on the middle-end optimizations.

Recently I found an anti-pattern in some Rust applications from my benchmark. All of them come from hashbrown::raw::RawTableInner::free_buckets:

hashbrown/src/raw/mod.rs

Lines 3290 to 3294 in 274c7bb

// Avoid `Option::unwrap_or_else` because it bloats LLVM IR.
let (layout, ctrl_offset) = match table_layout.calculate_layout_for(self.buckets()) {
Some(lco) => lco,
None => unsafe { hint::unreachable_unchecked() },
};

LLVM IR:

define i32 @src(i32 %x, i32 %y) {
  %res = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y)
  %ov = extractvalue { i32, i1 } %res, 1
  %nowrap = xor i1 %ov, true
  tail call void @llvm.assume(i1 %nowrap)
  %val = extractvalue { i32, i1 } %res, 0
  ret i32 %val
}
define i32 @tgt(i32 %x, i32 %y) {
  %res = mul nuw i32 %x, %y
  ret i32 %res
}

Alive2: https://alive2.llvm.org/ce/z/YBRjxc

Currently LLVM cannot use the knowledge from a never-overflow assumption. I have a draft patch for the fold and it enables more optimizations in downstream users of hashbrown. But I am not willing to do an application-specific optimization in LLVM. So I file this issue to see whether we can fix it in hashbrown.

cc @nikic @dianqk

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions