Skip to content

Missed Optimization: Inefficient Handling of Mutable Reference in Simple Conditional Assignment #124346

Open
@paolobarbolini

Description

@paolobarbolini

The following example shows how LLVM isn't able to optimize trivial branches when dealing with &mut pointers, while it can with owned values. I'd expect both functions to override current_len with 0 without needing to branch.

#[no_mangle]
pub fn unoptimized(current_len: &mut u32) {
    if *current_len != 0 {
        *current_len = 0;
    }
}

#[no_mangle]
pub fn optimized(mut current_len: u32) -> u32 {
    if current_len != 0 {
        current_len = 0;
    }
    current_len
}
unoptimized:
        cmp     dword ptr [rdi], 0
        je      .LBB0_2
        mov     dword ptr [rdi], 0
.LBB0_2:
        ret

optimized:
        xor     eax, eax
        ret
define void @unoptimized(ptr noalias nocapture noundef align 4 dereferenceable(4) %current_len) unnamed_addr {
start:
  %_2 = load i32, ptr %current_len, align 4
  %0 = icmp eq i32 %_2, 0
  br i1 %0, label %bb3, label %bb1

bb1:
  store i32 0, ptr %current_len, align 4
  br label %bb3

bb3:
  ret void
}

define noundef i32 @optimized(i32 noundef %0) unnamed_addr {
start:
  ret i32 0
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-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