rust/tests/mir-opt/pre-codegen
bors a77322c16f Auto merge of #118310 - scottmcm:three-way-compare, r=davidtwco
Add `Ord::cmp` for primitives as a `BinOp` in MIR

Update: most of this OP was written months ago.  See https://github.com/rust-lang/rust/pull/118310#issuecomment-2016940014 below for where we got to recently that made it ready for review.

---

There are dozens of reasonable ways to implement `Ord::cmp` for integers using comparison, bit-ops, and branches.  Those differences are irrelevant at the rust level, however, so we can make things better by adding `BinOp::Cmp` at the MIR level:

1. Exactly how to implement it is left up to the backends, so LLVM can use whatever pattern its optimizer best recognizes and cranelift can use whichever pattern codegens the fastest.
2. By not inlining those details for every use of `cmp`, we drastically reduce the amount of MIR generated for `derive`d `PartialOrd`, while also making it more amenable to MIR-level optimizations.

Having extremely careful `if` ordering to μoptimize resource usage on broadwell (#63767) is great, but it really feels to me like libcore is the wrong place to put that logic.  Similarly, using subtraction [tricks](https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign) (#105840) is arguably even nicer, but depends on the optimizer understanding it (https://github.com/llvm/llvm-project/issues/73417) to be practical.  Or maybe [bitor is better than add](https://discourse.llvm.org/t/representing-in-ir/67369/2?u=scottmcm)?  But maybe only on a future version that [has `or disjoint` support](https://discourse.llvm.org/t/rfc-add-or-disjoint-flag/75036?u=scottmcm)?  And just because one of those forms happens to be good for LLVM, there's no guarantee that it'd be the same form that GCC or Cranelift would rather see -- especially given their very different optimizers.  Not to mention that if LLVM gets a spaceship intrinsic -- [which it should](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Suboptimal.20inlining.20in.20std.20function.20.60binary_search.60/near/404250586) -- we'll need at least a rustc intrinsic to be able to call it.

As for simplifying it in Rust, we now regularly inline `{integer}::partial_cmp`, but it's quite a large amount of IR.  The best way to see that is with 8811efa88b (diff-d134c32d028fbe2bf835fef2df9aca9d13332dd82284ff21ee7ebf717bfa4765R113) -- I added a new pre-codegen MIR test for a simple 3-tuple struct, and this PR change it from 36 locals and 26 basic blocks down to 24 locals and 8 basic blocks.  Even better, as soon as the construct-`Some`-then-match-it-in-same-BB noise is cleaned up, this'll expose the `Cmp == 0` branches clearly in MIR, so that an InstCombine (#105808) can simplify that to just a `BinOp::Eq` and thus fix some of our generated code perf issues.  (Tracking that through today's `if a < b { Less } else if a == b { Equal } else { Greater }` would be *much* harder.)

---

r? `@ghost`
But first I should check that perf is ok with this
~~...and my true nemesis, tidy.~~
2024-04-02 19:21:44 +00:00
..
chained_comparison.bitand.PreCodegen.after.mir Remove comments from mir-opt MIR dumps 2023-06-15 15:19:11 -04:00
chained_comparison.naive.PreCodegen.after.mir update tests that are ignored by debug 2023-09-01 04:01:54 +08:00
chained_comparison.returning.PreCodegen.after.mir update tests that are ignored by debug 2023-09-01 04:01:54 +08:00
chained_comparison.rs [AUTO_GENERATED] Migrate compiletest to use ui_test-style //@ directives 2024-02-22 16:04:04 +00:00
checked_ops.checked_shl.PreCodegen.after.mir MIR printing: print the path of uneval'd const; refer to promoteds in a consistent way 2024-03-10 14:59:41 +01:00
checked_ops.rs Remove some only- clauses from mir-opt tests 2024-03-18 10:07:43 -04:00
checked_ops.step_forward.PreCodegen.after.mir Enable by default. 2024-02-09 21:13:51 +00:00
derived_ord.rs Add a MIR pre-codegen test for derived PartialOrd 2024-03-23 23:06:44 -07:00
derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir Slightly simplify the iN::partial_cmp MIR 2024-03-24 10:01:37 -07:00
duplicate_switch_targets.rs Enable more mir-opt tests in debug builds 2024-03-22 20:14:39 -04:00
duplicate_switch_targets.ub_if_b.PreCodegen.after.mir Eliminate UbCheck for non-standard libraries 2024-03-27 21:02:40 +08:00
intrinsics.f_u64.PreCodegen.after.mir Always propagate into operands. 2023-07-20 21:30:51 +00:00
intrinsics.f_unit.PreCodegen.after.mir Remove comments from mir-opt MIR dumps 2023-06-15 15:19:11 -04:00
intrinsics.rs Remove some only- clauses from mir-opt tests 2024-03-18 10:07:43 -04:00
issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff MIR printing: print the path of uneval'd const; refer to promoteds in a consistent way 2024-03-10 14:59:41 +01:00
issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff MIR printing: print the path of uneval'd const; refer to promoteds in a consistent way 2024-03-10 14:59:41 +01:00
issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff MIR printing: print the path of uneval'd const; refer to promoteds in a consistent way 2024-03-10 14:59:41 +01:00
issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff MIR printing: print the path of uneval'd const; refer to promoteds in a consistent way 2024-03-10 14:59:41 +01:00
issue_117368_print_invalid_constant.rs Make ui into mir-opt test. 2023-11-01 16:49:18 +00:00
loops.filter_mapped.PreCodegen.after.mir Sandwich MIR optimizations between DSE. 2024-01-11 09:58:19 +00:00
loops.int_range.PreCodegen.after.mir Enable by default. 2024-02-09 21:13:51 +00:00
loops.mapped.PreCodegen.after.mir Sandwich MIR optimizations between DSE. 2024-01-11 09:58:19 +00:00
loops.rs Remove some only- clauses from mir-opt tests 2024-03-18 10:07:43 -04:00
loops.vec_move.PreCodegen.after.mir make MIR less verbose 2023-08-24 14:26:26 +02:00
matches_macro.issue_77355_opt.PreCodegen.after.mir Remove ConstGoto and SeparateConstSwitch. 2024-02-09 21:13:53 +00:00
matches_macro.rs Remove ConstGoto and SeparateConstSwitch. 2024-02-09 21:13:53 +00:00
mem_replace.manual_replace.PreCodegen.after.panic-abort.mir Bless/fix tests 2024-02-08 19:56:30 -05:00
mem_replace.manual_replace.PreCodegen.after.panic-unwind.mir Bless/fix tests 2024-02-08 19:56:30 -05:00
mem_replace.mem_replace.PreCodegen.after.panic-abort.mir Bless/fix tests 2024-02-08 19:56:30 -05:00
mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir Bless/fix tests 2024-02-08 19:56:30 -05:00
mem_replace.rs Enable more mir-opt tests in debug builds 2024-03-22 20:14:39 -04:00
optimizes_into_variable.main.GVN.32bit.panic-abort.diff Sandwich MIR optimizations between DSE. 2024-01-11 09:58:19 +00:00
optimizes_into_variable.main.GVN.32bit.panic-unwind.diff Sandwich MIR optimizations between DSE. 2024-01-11 09:58:19 +00:00
optimizes_into_variable.main.GVN.64bit.panic-abort.diff Sandwich MIR optimizations between DSE. 2024-01-11 09:58:19 +00:00
optimizes_into_variable.main.GVN.64bit.panic-unwind.diff Sandwich MIR optimizations between DSE. 2024-01-11 09:58:19 +00:00
optimizes_into_variable.main.PreCodegen.after.32bit.panic-abort.mir Remove comments from mir-opt MIR dumps 2023-06-15 15:19:11 -04:00
optimizes_into_variable.main.PreCodegen.after.32bit.panic-unwind.mir Remove comments from mir-opt MIR dumps 2023-06-15 15:19:11 -04:00
optimizes_into_variable.main.PreCodegen.after.64bit.panic-abort.mir Remove comments from mir-opt MIR dumps 2023-06-15 15:19:11 -04:00
optimizes_into_variable.main.PreCodegen.after.64bit.panic-unwind.mir Remove comments from mir-opt MIR dumps 2023-06-15 15:19:11 -04:00
optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-abort.diff Reorder early post-inlining passes. 2024-01-07 01:42:57 +00:00
optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.panic-unwind.diff Reorder early post-inlining passes. 2024-01-07 01:42:57 +00:00
optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-abort.diff Reorder early post-inlining passes. 2024-01-07 01:42:57 +00:00
optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.panic-unwind.diff Reorder early post-inlining passes. 2024-01-07 01:42:57 +00:00
optimizes_into_variable.main.SimplifyLocals-final.after.32bit.panic-abort.mir Remove comments from mir-opt MIR dumps 2023-06-15 15:19:11 -04:00
optimizes_into_variable.main.SimplifyLocals-final.after.32bit.panic-unwind.mir Remove comments from mir-opt MIR dumps 2023-06-15 15:19:11 -04:00
optimizes_into_variable.main.SimplifyLocals-final.after.64bit.panic-abort.mir Remove comments from mir-opt MIR dumps 2023-06-15 15:19:11 -04:00
optimizes_into_variable.main.SimplifyLocals-final.after.64bit.panic-unwind.mir Remove comments from mir-opt MIR dumps 2023-06-15 15:19:11 -04:00
optimizes_into_variable.rs [AUTO_GENERATED] Migrate compiletest to use ui_test-style //@ directives 2024-02-22 16:04:04 +00:00
range_iter.forward_loop.PreCodegen.after.panic-abort.mir Enable by default. 2024-02-09 21:13:51 +00:00
range_iter.forward_loop.PreCodegen.after.panic-unwind.mir Enable by default. 2024-02-09 21:13:51 +00:00
range_iter.inclusive_loop.PreCodegen.after.panic-abort.mir Sandwich MIR optimizations between DSE. 2024-01-11 09:58:19 +00:00
range_iter.inclusive_loop.PreCodegen.after.panic-unwind.mir Sandwich MIR optimizations between DSE. 2024-01-11 09:58:19 +00:00
range_iter.range_inclusive_iter_next.PreCodegen.after.panic-abort.mir Turn copy into moves during DSE. 2023-07-19 09:59:12 +00:00
range_iter.range_inclusive_iter_next.PreCodegen.after.panic-unwind.mir Turn copy into moves during DSE. 2023-07-19 09:59:12 +00:00
range_iter.range_iter_next.PreCodegen.after.panic-abort.mir Enable GVN by default. 2023-12-24 20:08:57 +00:00
range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir Enable GVN by default. 2023-12-24 20:08:57 +00:00
range_iter.rs Remove some only- clauses from mir-opt tests 2024-03-18 10:07:43 -04:00
README.md Add mir-opt tests to track MIR quality. 2023-04-23 17:10:53 +00:00
simple_option_map.ezmap.PreCodegen.after.mir Remove some only- clauses from mir-opt tests 2024-03-18 10:07:43 -04:00
simple_option_map.rs Remove some only- clauses from mir-opt tests 2024-03-18 10:07:43 -04:00
slice_filter.rs Ignore less tests in debug builds 2024-02-23 18:04:01 -05:00
slice_filter.variant_a-{closure#0}.PreCodegen.after.mir Ignore less tests in debug builds 2024-02-23 18:04:01 -05:00
slice_filter.variant_b-{closure#0}.PreCodegen.after.mir Ignore less tests in debug builds 2024-02-23 18:04:01 -05:00
slice_index.rs Enable more mir-opt tests in debug builds 2024-03-22 20:14:39 -04:00
slice_index.slice_get_mut_usize.PreCodegen.after.panic-abort.mir Convert debug_assert_nounwind to intrinsics::debug_assertions 2024-02-19 20:38:09 -05:00
slice_index.slice_get_mut_usize.PreCodegen.after.panic-unwind.mir Convert debug_assert_nounwind to intrinsics::debug_assertions 2024-02-19 20:38:09 -05:00
slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir Convert debug_assert_nounwind to intrinsics::debug_assertions 2024-02-19 20:38:09 -05:00
slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir Convert debug_assert_nounwind to intrinsics::debug_assertions 2024-02-19 20:38:09 -05:00
slice_index.slice_index_range.PreCodegen.after.panic-abort.mir Also consider call and yield as MIR SSA. 2023-10-08 16:05:26 +00:00
slice_index.slice_index_range.PreCodegen.after.panic-unwind.mir Also consider call and yield as MIR SSA. 2023-10-08 16:05:26 +00:00
slice_index.slice_index_usize.PreCodegen.after.panic-abort.mir Remove comments from mir-opt MIR dumps 2023-06-15 15:19:11 -04:00
slice_index.slice_index_usize.PreCodegen.after.panic-unwind.mir Bless tests 2023-06-23 18:36:25 +01:00
slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir MIR printing: print the path of uneval'd const; refer to promoteds in a consistent way 2024-03-10 14:59:41 +01:00
slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir MIR printing: print the path of uneval'd const; refer to promoteds in a consistent way 2024-03-10 14:59:41 +01:00
slice_iter.forward_loop.PreCodegen.after.panic-abort.mir MIR printing: print the path of uneval'd const; refer to promoteds in a consistent way 2024-03-10 14:59:41 +01:00
slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir MIR printing: print the path of uneval'd const; refer to promoteds in a consistent way 2024-03-10 14:59:41 +01:00
slice_iter.range_loop.PreCodegen.after.panic-abort.mir Enable by default. 2024-02-09 21:13:51 +00:00
slice_iter.range_loop.PreCodegen.after.panic-unwind.mir Enable by default. 2024-02-09 21:13:51 +00:00
slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir MIR printing: print the path of uneval'd const; refer to promoteds in a consistent way 2024-03-10 14:59:41 +01:00
slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir MIR printing: print the path of uneval'd const; refer to promoteds in a consistent way 2024-03-10 14:59:41 +01:00
slice_iter.rs Enable more mir-opt tests in debug builds 2024-03-22 20:14:39 -04:00
slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir Turn copy into moves during DSE. 2023-07-19 09:59:12 +00:00
slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir Turn copy into moves during DSE. 2023-07-19 09:59:12 +00:00
slice_iter.slice_iter_next.PreCodegen.after.panic-abort.mir Turn copy into moves during DSE. 2023-07-19 09:59:12 +00:00
slice_iter.slice_iter_next.PreCodegen.after.panic-unwind.mir Turn copy into moves during DSE. 2023-07-19 09:59:12 +00:00
spans.outer.PreCodegen.after.panic-abort.mir Allow to run filecheck in mir-opt tests. 2023-10-19 15:51:52 +00:00
spans.outer.PreCodegen.after.panic-unwind.mir Allow to run filecheck in mir-opt tests. 2023-10-19 15:51:52 +00:00
spans.rs [AUTO_GENERATED] Migrate compiletest to use ui_test-style //@ directives 2024-02-22 16:04:04 +00:00
try_identity.new.PreCodegen.after.mir Enable by default. 2024-02-09 21:13:51 +00:00
try_identity.old.PreCodegen.after.mir Sandwich MIR optimizations between DSE. 2024-01-11 09:58:19 +00:00
try_identity.rs Remove some only- clauses from mir-opt tests 2024-03-18 10:07:43 -04:00

The goal of this directory is to track the quality of MIR that is given to codegen in a standard -O condiguration.

As such, feel free to --bless whatever changes you get here, so long as doing so doesn't add substantially more MIR.