Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fast isel dislikes switch, which pattern matching can generate #4353

Closed
pcwalton opened this issue Jan 5, 2013 · 12 comments
Closed

Fast isel dislikes switch, which pattern matching can generate #4353

pcwalton opened this issue Jan 5, 2013 · 12 comments
Labels
A-codegen Area: Code generation A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-enhancement Category: An issue proposing an enhancement or a PR with one. I-compiletime Issue: Problems and improvements with respect to compile times. P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@pcwalton
Copy link
Contributor

pcwalton commented Jan 5, 2013

We should use the compare mode otherwise.

@huonw
Copy link
Member

huonw commented Sep 23, 2013

Triage. As demonstrated below, we still generate switchs, but I don't know how to check for Fast ISel vs not, so I can't verify if they still upset it after 9 months of upgrades.

fn main() {
    match 1 {
        0 => {}
        _ => {}
    };
}
define void @_ZN4main18h7c52aaf9b95dc92af4v0.0E({ i64, %tydesc*, i8*, i8*, i8 }*) #4 {
"function top level":
  %1 = alloca i64
  store i64 1, i64* %1
  %2 = load i64* %1
  switch i64 %2, label %match_else [
    i64 0, label %match_case
  ]

case_body:                                        ; preds = %match_case
  br label %join

case_body1:                                       ; preds = %match_else
  br label %join

match_else:                                       ; preds = %"function top level"
  br label %case_body1

match_case:                                       ; preds = %"function top level"
  br label %case_body

join:                                             ; preds = %case_body1, %case_body
  ret void
}

@pnkfelix
Copy link
Member

pnkfelix commented Feb 6, 2014

P-low, not 1.0 blocker.

@steveklabnik
Copy link
Member

Today, compiling with rustc -O --emit=llvm-ir hello.rs, I get

define i64 @main(i64, i8**) unnamed_addr #1 {
top:
  %2 = tail call i64 @_ZN2rt10lang_start20he050f8de3bcc02b7VRIE(i8* bitcast (void ()* @_ZN4main20h04abfe0370f26946eaaE to i8*), i64 %0, i8** %1)
  ret i64 %2
}

No more case. Is this resolved, or does some other code still generate poorly?

@huonw
Copy link
Member

huonw commented Apr 17, 2015

I think fast isel is only ever attempted to be used when optimisations are off. Using fast isel makes compilation faster and so we want to ensure we're using with opt-level=0 as much as possible. I don't how one can detect if fast isel is being used by LLVM.

@steveklabnik
Copy link
Member

Ah, gotcha, that makes sense. Given that it's an optimization, I assumed that it would be with optimizations on. :)

@jonas-schievink
Copy link
Contributor

FastISel still dislikes switch, and the MIR translator generates it as well. Fixing this with MIR is much easier, we could replace unneeded SwitchInts in the SimplifyCfg pass or write another pass for this.

(you can check for FastISel by running the LLVM IR through llc -O0 -fast-isel -fast-isel-abort 1 test.ll - preferrably using the llc compiled from Rust's LLVM submodule, which is located in ./x86_64-unknown-linux-gnu/llvm/Release/bin/llc)

@arielb1
Copy link
Contributor

arielb1 commented Feb 15, 2016

@jonas-schievink

We may want to do this in the lowering for SwitchInt.

@Mark-Simulacrum Mark-Simulacrum added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jul 19, 2017
Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this issue Jun 4, 2018
Generate br for all two target SwitchInts

Instead of only for booleans. This means that `if let` also becomes a br.

Apart from making the IR slightly simpler, this is supported by FastISel (rust-lang#4353).
@steveklabnik
Copy link
Member

Triage: I'm not aware of any changes, nor anybody working on something like this.

@rust-lang/compiler do you think this ticket is useful?

@nagisa
Copy link
Member

nagisa commented Sep 24, 2018

This ticket is still useful. That being said, benefits of fixing this are comparatively minor and there are bigger fish to catch.

@scottmcm
Copy link
Member

I think this needs a new repro, as the one above appears to have been fixed by #51323: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=5a29683164b1399f1a2418dd9f6718ee

As an attempt, the following does generate a switch:

pub fn foo(c: i32) -> i32 {
    match c {
        0 => 1,
        1 => 7,
        _ => 2,
    }
}

How were you thinking of fixing this? Should there be a opt-level-zero-only MIR optimiztransformation to replace multi-way switchInts with two-way ones and extra blocks? Or did you want it to happen in codegen?

@nikic
Copy link
Contributor

nikic commented Jan 24, 2019

Unfortunately fastisel doesn't support quite a few things that are common in LLVM IR generated by Rust. It's probably not worthwhile to change the codegen for switch if we're quite likely to fail on an invoke or some scalar pair operation anyway.

@jonas-schievink jonas-schievink added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Jan 31, 2020
@workingjubilee
Copy link
Member

Closing per the same judgement as this sibling issue: #26600 (comment)

@workingjubilee workingjubilee closed this as not planned Won't fix, can't repro, duplicate, stale Jul 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-codegen Area: Code generation A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-enhancement Category: An issue proposing an enhancement or a PR with one. I-compiletime Issue: Problems and improvements with respect to compile times. P-low Low priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests