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

Also assume wrap-around discriminants in as MIR building #111579

Merged
merged 1 commit into from
May 23, 2023

Conversation

scottmcm
Copy link
Member

Resolves this FIXME:

// FIXME: Handle wraparound cases too.

r? @oli-obk

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels May 15, 2023
@rustbot
Copy link
Collaborator

rustbot commented May 15, 2023

Hey! It looks like you've submitted a new PR for the library teams!

If this PR contains changes to any rust-lang/rust public library APIs then please comment with @rustbot label +T-libs-api -T-libs to tag it appropriately. If this PR contains changes to any unstable APIs please edit the PR description to add a link to the relevant API Change Proposal or create one if you haven't already. If you're unsure where your change falls no worries, just leave it as is and the reviewer will take a look and make a decision to forward on if necessary.

Examples of T-libs-api changes:

  • Stabilizing library features
  • Introducing insta-stable changes such as new implementations of existing stable traits on existing stable types
  • Introducing new or changing existing unstable library APIs (excluding permanently unstable features / features without a tracking issue)
  • Changing public documentation in ways that create new stability guarantees
  • Changing observable runtime behavior of library APIs

Comment on lines 39 to 51
pub fn ordering_eq(l: Option<Ordering>, r: Option<Ordering>) -> bool {
// CHECK: start:
// CHECK-NEXT: icmp eq i8
// CHECK-NEXT: ret i1
// CHECK-NOT: ret i1
// CHECK: %[[A1:.+]] = icmp ult i8
// CHECK-NEXT: call void @llvm.assume(i1 %[[A1]])
// CHECK-NOT: ret i1
// CHECK: %[[A2:.+]] = icmp ult i8
// CHECK-NEXT: call void @llvm.assume(i1 %[[A2]])
// CHECK-NOT: ret i1
// CHECK: %[[CMP:.+]] = icmp eq i8 %0, %1
// CHECK-NEXT: ret i1 %[[CMP]]
// CHECK-NOT: ret i1
l == r
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without the library change, this was giving

define noundef zeroext i1 @ordering_eq(i8 noundef %0, i8 noundef %1) unnamed_addr #0 personality ptr @__CxxFrameHandler3 {
start:
  %2 = icmp eq i8 %0, 2
  br i1 %2, label %"_ZN4core6option15Option$LT$T$GT$6map_or17h10b30776faeff97fE.exit", label %bb3.i

bb3.i:                                            ; preds = %start
  %3 = add i8 %0, 1
  %_7.i.i = icmp ult i8 %3, 3
  tail call void @llvm.assume(i1 %_7.i.i)
  br label %"_ZN4core6option15Option$LT$T$GT$6map_or17h10b30776faeff97fE.exit"

"_ZN4core6option15Option$LT$T$GT$6map_or17h10b30776faeff97fE.exit": ; preds = %start, %bb3.i
  %4 = icmp eq i8 %1, 2
  br i1 %4, label %"_ZN4core6option15Option$LT$T$GT$6map_or17hd4add697368b47d3E.exit", label %bb3.i2

bb3.i2:                                           ; preds = %"_ZN4core6option15Option$LT$T$GT$6map_or17h10b30776faeff97fE.exit"
  %5 = add i8 %1, 1
  %_7.i.i1 = icmp ult i8 %5, 3
  tail call void @llvm.assume(i1 %_7.i.i1)
  br label %"_ZN4core6option15Option$LT$T$GT$6map_or17hd4add697368b47d3E.exit"

"_ZN4core6option15Option$LT$T$GT$6map_or17hd4add697368b47d3E.exit": ; preds = %"_ZN4core6option15Option$LT$T$GT$6map_or17h10b30776faeff97fE.exit", %bb3.i2
  %6 = icmp eq i8 %0, %1
  ret i1 %6
}

Now that it's using the transmute instead of the map_or approach, it's

define noundef zeroext i1 @ordering_eq(i8 noundef %0, i8 noundef %1) unnamed_addr #0 {
start:
  %2 = add i8 %0, 1
  %3 = icmp ult i8 %2, 4
  tail call void @llvm.assume(i1 %3)
  %4 = add i8 %1, 1
  %5 = icmp ult i8 %4, 4
  tail call void @llvm.assume(i1 %5)
  %6 = icmp eq i8 %0, %1
  ret i1 %6
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While we can do this hack in libcore, this means user code will regress in similar situations. Should we track this issue to figure out how to improve it? We could autogenerate the transmute in a MIR opt for example.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it should block this PR, because it's only the fluke of its chosen discriminants -- using more normal enums the map_or plan already didn't work: https://rust.godbolt.org/z/Tnvvev789

I could file a Rust issue, but I think the "right" fix would be fixing the root issue that made us start using this mitigation in the first place: Having LLVM just handle the derived equality better llvm/llvm-project#52622

(This is a hack inside a specialization hack, so I don't know that it's necessarily representative of user code.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, actually, maybe it's not a real problem. It looks bad in the LLVM IR, but the assembly generated for it is still the correct single test: https://rust.godbolt.org/z/da819G99e

example::qux:
        cmp     dil, sil
        sete    al
        ret

despite

define noundef zeroext i1 @_ZN7example3qux17hb5cd12f675ddd331E(i8 noundef %x, i8 noundef %y) unnamed_addr #0 personality ptr @rust_eh_personality {
  %0 = icmp eq i8 %x, -128
  br i1 %0, label %"_ZN4core6option15Option$LT$T$GT$6map_or17h8cb56c5fe57f6f5dE.exit", label %bb3.i

bb3.i:                                            ; preds = %start
  %_4.i.i = icmp sgt i8 %x, -1
  tail call void @llvm.assume(i1 %_4.i.i)
  br label %"_ZN4core6option15Option$LT$T$GT$6map_or17h8cb56c5fe57f6f5dE.exit"

"_ZN4core6option15Option$LT$T$GT$6map_or17h8cb56c5fe57f6f5dE.exit": ; preds = %start, %bb3.i
  %1 = icmp eq i8 %y, -128
  br i1 %1, label %"_ZN4core6option15Option$LT$T$GT$6map_or17h93b3ae047b8aab61E.exit", label %bb3.i2

bb3.i2:                                           ; preds = %"_ZN4core6option15Option$LT$T$GT$6map_or17h8cb56c5fe57f6f5dE.exit"
  %_4.i.i1 = icmp sgt i8 %y, -1
  tail call void @llvm.assume(i1 %_4.i.i1)
  br label %"_ZN4core6option15Option$LT$T$GT$6map_or17h93b3ae047b8aab61E.exit"

"_ZN4core6option15Option$LT$T$GT$6map_or17h93b3ae047b8aab61E.exit": ; preds = %"_ZN4core6option15Option$LT$T$GT$6map_or17h8cb56c5fe57f6f5dE.exit", %bb3.i2
  %2 = icmp eq i8 %x, %y
  ret i1 %2
}

So I suppose I could also try moving these tests to assembly tests if that would be better, and leaving the map_ors.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the thumb, I'll do that.

@rustbot author

Copy link
Member Author

@scottmcm scottmcm May 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, removed the library/ change, and instead moved the test to assembly. Didn't change the compiler logic.

@rustbot ready

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 16, 2023
@scottmcm scottmcm force-pushed the enum-as-signed branch 2 times, most recently from fc731be to 032cb59 Compare May 18, 2023 05:51
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 18, 2023
@oli-obk
Copy link
Contributor

oli-obk commented May 22, 2023

@bors r+

@bors
Copy link
Contributor

bors commented May 22, 2023

📌 Commit 400866b has been approved by oli-obk

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 22, 2023
bors added a commit to rust-lang-ci/rust that referenced this pull request May 23, 2023
Rollup of 6 pull requests

Successful merges:

 - rust-lang#111461 (Fix symbol conflict diagnostic mistakenly being shown instead of missing crate diagnostic)
 - rust-lang#111579 (Also assume wrap-around discriminants in `as` MIR building)
 - rust-lang#111704 (Remove return type sized check hack from hir typeck)
 - rust-lang#111853 (Check opaques for mismatch during writeback)
 - rust-lang#111854 (rustdoc: clean up `settings.css`)
 - rust-lang#111860 (Don't ICE if method receiver fails to unify with `arbitrary_self_types`)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 00185be into rust-lang:master May 23, 2023
@rustbot rustbot added this to the 1.71.0 milestone May 23, 2023
@scottmcm scottmcm deleted the enum-as-signed branch May 24, 2023 00:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants