Skip to content

Missed optimization with short circuit AND #103327

Closed
@y21

Description

@y21

Consider this code:

pub fn other(a: i32, b: i32) -> bool {
    let c1 = (a >= 0) & (a <= 10);
    let c2 = (b >= 0) & (b <= 20);

    if c1 & c2 {
        a + 100 != b
    } else {
        true
    }
}

This compiles to just:

example::other:
        mov     al, 1
        ret

(Godbolt)
However, changing any of the & to && breaks this optimization and a bunch of cmps are generated as well as the addition, which seems unnecessary in this case, because &/&& shouldn't make any difference as short circuit can't be observed.

example::other:
        mov     al, 1
        cmp     edi, 10
        ja      .LBB0_3
        cmp     esi, 20
        ja      .LBB0_3
        add     edi, 100
        cmp     edi, esi
        setne   al
.LBB0_3:
        ret

(Godbolt)
This works fine with Clang

Doesn't seem like an LLVM issue (to me?). The LLVM IR that Rust emits The resulting LLVM IR:

define zeroext i1 @test(i32 %a, i32 %b) unnamed_addr #0 {
start:
  %0 = icmp ult i32 %a, 11
  %1 = icmp ult i32 %b, 21
  %_13.0 = select i1 %0, i1 %1, i1 false
  br i1 %_13.0, label %bb4, label %bb6

bb4:                                              ; preds = %start
  %_16 = add nuw nsw i32 %a, 100
  %2 = icmp ne i32 %_16, %b
  br label %bb6

bb6:                                              ; preds = %start, %bb4
  %.0 = phi i1 [ %2, %bb4 ], [ true, %start ]
  ret i1 %.0
}

correctly gets optimized to this with opt -O3 in -S -o out

define zeroext i1 @test(i32 %a, i32 %b) unnamed_addr #0 {
start:
  ret i1 true
}

(Godbolt)

Metadata

Metadata

Assignees

Labels

A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-codegenArea: Code generationC-bugCategory: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.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