Commit be4b6a9
committed
Auto merge of #161081 - scottmcm:min-max-intrinsics, r=clarfonthey
Add intrinsics for integer minimum and maximum
I got inspired to do this when looking at `SliceOrd::compare` where I was reminded that `if a < b { a } else { b }` isn't great in MIR since it takes 4 BBs. Looking at the codegen side, it turns out we currently emit [42 lines of LLVM-IR including 4 `alloca`s](https://rust.godbolt.org/z/ha4h4nT3r) for `u16::max` (pre-optimization), which is also unnecessarily bad†.
But both LLVM and Cranelift have dedicated things for min & max:
- https://llvm.org/docs/LangRef.html#llvm-umax-intrinsic
- https://docs.rs/cranelift-codegen/latest/cranelift_codegen/ir/trait.InstBuilder.html#method.smin
so let's just use those directly!
This actually wouldn't have been worth doing originally, but a couple of things have happened to change that:
- Back in 1.0 there was only `cmp::min` & `cmp::max`, so there was no place to actually do this at all, but in 2017 they were added to `Ord` as overridable things #25663 (comment)
- LLVM originally used icmp+select for these, not a dedicated construct, but then added one and as of 2022 the intrinsic is fully usable https://www.npopov.com/2022/12/20/This-year-in-LLVM-2022.html#integer-minmax-intrinsics
- Before we had intrinsic fallback this would have been more annoying to support everywhere -- GCC, [128-bit numbers on cg_clif](bytecodealliance/wasmtime#13790), CTFE, anything out-of-tree -- but now that we can write the obvious fallback we don't need to worry about that.
- The intrinsic would have helped less when it forced extra BBs and `alloca`s in codegen anyway, but [now](rust-lang/compiler-team#970) we can keep the result in SSA without needing to make it a primitive.
† Admittedly we could clean up the gratuitous badness there without needing an intrinsic, but I like doing the intrinsic anyway because that's the only way to avoid it always being stuck in the non-SSA path from the multi-BB assignments. Even if we made it inlineable, GVN and such will still just give up on seeing the `x = if a < b { a } else { b }` because it's multiple assignments to the same Local, which is non-ideal for something primitive-like.10 files changed
Lines changed: 184 additions & 1 deletion
File tree
- compiler
- rustc_codegen_cranelift/src/intrinsics
- rustc_codegen_llvm/src
- rustc_hir_analysis/src/check
- rustc_span/src
- library
- coretests/tests
- core/src
- intrinsics
- tests/codegen-llvm/intrinsics
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
630 | 630 | | |
631 | 631 | | |
632 | 632 | | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
633 | 653 | | |
634 | 654 | | |
635 | 655 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
476 | 476 | | |
477 | 477 | | |
478 | 478 | | |
| 479 | + | |
| 480 | + | |
479 | 481 | | |
480 | 482 | | |
481 | 483 | | |
| |||
520 | 522 | | |
521 | 523 | | |
522 | 524 | | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
523 | 537 | | |
524 | 538 | | |
525 | 539 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
333 | 333 | | |
334 | 334 | | |
335 | 335 | | |
| 336 | + | |
| 337 | + | |
336 | 338 | | |
337 | 339 | | |
338 | 340 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
135 | 135 | | |
136 | 136 | | |
137 | 137 | | |
| 138 | + | |
| 139 | + | |
138 | 140 | | |
139 | 141 | | |
140 | 142 | | |
| |||
602 | 604 | | |
603 | 605 | | |
604 | 606 | | |
| 607 | + | |
605 | 608 | | |
606 | 609 | | |
607 | 610 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1145 | 1145 | | |
1146 | 1146 | | |
1147 | 1147 | | |
| 1148 | + | |
| 1149 | + | |
1148 | 1150 | | |
1149 | 1151 | | |
1150 | 1152 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2298 | 2298 | | |
2299 | 2299 | | |
2300 | 2300 | | |
| 2301 | + | |
| 2302 | + | |
| 2303 | + | |
| 2304 | + | |
| 2305 | + | |
| 2306 | + | |
| 2307 | + | |
| 2308 | + | |
| 2309 | + | |
| 2310 | + | |
| 2311 | + | |
| 2312 | + | |
| 2313 | + | |
| 2314 | + | |
| 2315 | + | |
| 2316 | + | |
| 2317 | + | |
| 2318 | + | |
| 2319 | + | |
| 2320 | + | |
| 2321 | + | |
| 2322 | + | |
| 2323 | + | |
| 2324 | + | |
| 2325 | + | |
| 2326 | + | |
| 2327 | + | |
| 2328 | + | |
| 2329 | + | |
2301 | 2330 | | |
2302 | | - | |
| 2331 | + | |
2303 | 2332 | | |
2304 | 2333 | | |
2305 | 2334 | | |
| |||
2338 | 2367 | | |
2339 | 2368 | | |
2340 | 2369 | | |
| 2370 | + | |
| 2371 | + | |
2341 | 2372 | | |
2342 | 2373 | | |
2343 | 2374 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
109 | 109 | | |
110 | 110 | | |
111 | 111 | | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1841 | 1841 | | |
1842 | 1842 | | |
1843 | 1843 | | |
| 1844 | + | |
| 1845 | + | |
| 1846 | + | |
| 1847 | + | |
| 1848 | + | |
| 1849 | + | |
| 1850 | + | |
| 1851 | + | |
| 1852 | + | |
| 1853 | + | |
| 1854 | + | |
| 1855 | + | |
| 1856 | + | |
| 1857 | + | |
| 1858 | + | |
| 1859 | + | |
| 1860 | + | |
| 1861 | + | |
| 1862 | + | |
| 1863 | + | |
| 1864 | + | |
| 1865 | + | |
| 1866 | + | |
| 1867 | + | |
| 1868 | + | |
| 1869 | + | |
| 1870 | + | |
| 1871 | + | |
1844 | 1872 | | |
1845 | 1873 | | |
1846 | 1874 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
30 | 44 | | |
31 | 45 | | |
32 | 46 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
0 commit comments