Skip to content

missed optimization for if let, even though equivalent match is optimized #110097

Closed
@davemilter

Description

@davemilter

I tried this code:

pub fn change_value(val: Result<i32, ()>) -> Result<i32, ()> {
    if let Ok(x) = val {
        Ok(x * 2)
    } else {
        Err(())
    }
}

pub fn change_value2(val: Result<i32, ()>) -> Result<i32, ()> {
    match val {
        Ok(x) => Ok(x * 2),
        Err(()) => Err(())
    }
}

I expected to see this happen:
in release build this code would translated into exact the same assembly/llvm-ir

Instead, this happened:

change_value:
	xorl	%eax, %eax
	testl	%edi, %edi
	setne	%al
	leal	(%rsi,%rsi), %edx
	retq
change_value2:
	movl	%edi, %eax
	leal	(%rsi,%rsi), %edx
	retq

and the llvm-ir is different:

define { i32, i32 } @_ZN10playground12change_value17h0230bd4091fd6529E(i32 noundef %0, i32 %1) unnamed_addr #0 {
start:
  %2 = icmp eq i32 %0, 0
  %_4 = shl i32 %1, 1
  %not. = xor i1 %2, true
  %.sroa.0.0 = zext i1 %not. to i32
  %.sroa.3.0 = select i1 %2, i32 %_4, i32 undef
  %3 = insertvalue { i32, i32 } undef, i32 %.sroa.0.0, 0
  %4 = insertvalue { i32, i32 } %3, i32 %.sroa.3.0, 1
  ret { i32, i32 } %4
}
define { i32, i32 } @_ZN10playground13change_value217h3302fbc2853d0a41E(i32 noundef %0, i32 %1) unnamed_addr #0 {
start:
  %switch = icmp eq i32 %0, 0
  %_4 = shl i32 %1, 1
  %.sroa.3.0 = select i1 %switch, i32 %_4, i32 undef
  %2 = insertvalue { i32, i32 } undef, i32 %0, 0
  %3 = insertvalue { i32, i32 } %2, i32 %.sroa.3.0, 1
  ret { i32, i32 } %3
}

Meta

I tried thin in rust-playground for 1.68.2, beta and nightly.

See also https://internals.rust-lang.org/t/why-match-is-better-then-if/18636

Metadata

Metadata

Assignees

Labels

A-mir-optArea: MIR optimizationsC-bugCategory: This is a bug.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-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