Skip to content

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

@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