Commit Graph

1078 Commits

Author SHA1 Message Date
Stuart Cook
ff325e0a00
Rollup merge of #138818 - khuey:138198, r=jieyouxu
Don't produce debug information for compiler-introduced-vars when desugaring assignments.

An assignment such as

(a, b) = (b, c);

desugars to the HIR

{ let (lhs, lhs) = (b, c); a = lhs; b = lhs; };

The repeated `lhs` leads to multiple Locals assigned to the same DILocalVariable. Rather than attempting to fix that, get rid of the debug info for these bindings that don't even exist in the program to begin with.

Fixes #138198

r? `@jieyouxu`
2025-03-26 19:40:28 +11:00
bors
e61403aa4c Auto merge of #138634 - saethlin:repeated-uninit, r=scottmcm,oli-obk
Lower to a memset(undef) when Rvalue::Repeat repeats uninit

Fixes https://github.com/rust-lang/rust/issues/138625.

It is technically correct to just do nothing. But if we actually do nothing, we may miss that this is de-initializing something, so instead we just lower to a single memset that writes undef. This is still superior to the memcpy loop, in both quality of code we hand to the backend and LLVM's final output.
2025-03-25 02:09:15 +00:00
bors
1df5affaca Auto merge of #133984 - DaniPopes:scmp-ucmp, r=scottmcm
Lower BinOp::Cmp to llvm.{s,u}cmp.* intrinsics

Lowers `mir::BinOp::Cmp` (`three_way_compare` intrinsic) to the corresponding LLVM `llvm.{s,u}cmp.i8.*` intrinsics.

These are the intrinsics mentioned in https://github.com/rust-lang/rust/pull/118310, which are now available in LLVM 19.

I couldn't find any follow-up PRs/discussions about this, please let me know if I missed something.

r? `@scottmcm`
2025-03-24 22:53:12 +00:00
Kyle Huey
8cab8e07bc Don't produce debug information for compiler-introduced-vars when desugaring assignments.
An assignment such as

(a, b) = (b, c);

desugars to the HIR

{ let (lhs, lhs) = (b, c); a = lhs; b = lhs; };

The repeated `lhs` leads to multiple Locals assigned to the same DILocalVariable. Rather than
attempting to fix that, get rid of the debug info for these bindings that don't even exist
in the program to begin with.

Fixes #138198
2025-03-21 17:34:45 -07:00
Ben Kimock
8e7d8ddffe Lower to a memset(undef) when Rvalue::Repeat repeats uninit 2025-03-19 23:57:49 -04:00
Jesus Checa Hidalgo
20432c9eee Use explicit cpu in some asm and codegen tests.
Some tests expect to be compiled for a specific CPU or require certain
target features to be present (or absent). These tests work fine with
default CPUs but fail in downstream builds for RHEL and Fedora, where
we use non-default CPUs such as z13 on s390x, pwr9 on ppc64le, or
x86-64-v2/x86-64-v3 on x86_64.
2025-03-19 19:45:46 +01:00
bors
493c38ba37 Auto merge of #127173 - bjorn3:mangle_rustc_std_internal_symbol, r=wesleywiser,jieyouxu
Mangle rustc_std_internal_symbols functions

This reduces the risk of issues when using a staticlib or rust dylib compiled with a different rustc version in a rust program. Currently this will either (in the case of staticlib) cause a linker error due to duplicate symbol definitions, or (in the case of rust dylibs) cause rustc_std_internal_symbols functions to be silently overridden. As rust gets more commonly used inside the implementation of libraries consumed with a C interface (like Spidermonkey, Ruby YJIT (curently has to do partial linking of all rust code to hide all symbols not part of the C api), the Rusticl OpenCL implementation in mesa) this is becoming much more of an issue. With this PR the only symbols remaining with an unmangled name are rust_eh_personality (LLVM doesn't allow renaming it) and `__rust_no_alloc_shim_is_unstable`.

Helps mitigate https://github.com/rust-lang/rust/issues/104707

try-job: aarch64-gnu-debug
try-job: aarch64-apple
try-job: x86_64-apple-1
try-job: x86_64-mingw-1
try-job: i686-mingw-1
try-job: x86_64-msvc-1
try-job: i686-msvc-1
try-job: test-various
try-job: armhf-gnu
2025-03-17 22:16:22 +00:00
Matthias Krüger
8f5c09b37c
Rollup merge of #138349 - 1c3t3a:external-weak-cfi, r=rcvalle
Emit function declarations for functions with `#[linkage="extern_weak"]`

Currently, when declaring an extern weak function in Rust, we use the following syntax:
```rust
unsafe extern "C" {
   #[linkage = "extern_weak"]
   static FOO: Option<unsafe extern "C" fn() -> ()>;
}
```
This allows runtime-checking the extern weak symbol through the Option.

When emitting LLVM-IR, the Rust compiler currently emits this static as an i8, and a pointer that is initialized with the value of the global i8 and represents the nullabilty e.g.
```
`@FOO` = extern_weak global i8
`@_rust_extern_with_linkage_FOO` = internal global ptr `@FOO`
```

This approach does not work well with CFI, where we need to attach CFI metadata to a concrete function declaration, which was pointed out in https://github.com/rust-lang/rust/issues/115199.

This change switches to emitting a proper function declaration instead of a global i8. This allows CFI to work for extern_weak functions. Example:
```
`@_rust_extern_with_linkage_FOO` = internal global ptr `@FOO`
...
declare !type !61 !type !62 !type !63 !type !64 extern_weak void `@FOO(double)` unnamed_addr #6
```

We keep initializing the Rust internal symbol with the function declaration, which preserves the correct behavior for runtime checking the Option.

r? `@rcvalle`

cc `@jakos-sec`

try-job: test-various
2025-03-17 16:34:50 +01:00
bjorn3
b754ef727c Remove implicit #[no_mangle] for #[rustc_std_internal_symbol] 2025-03-17 14:08:09 +00:00
Gary Guo
292c622507 Stabilize asm_goto 2025-03-17 11:12:10 +00:00
Bastian Kersting
b30cf11b96 Emit function declarations for functions with #[linkage="extern_weak"]
Currently, when declaring an extern weak function in Rust, we use the
following syntax:
```rust
unsafe extern "C" {
   #[linkage = "extern_weak"]
   static FOO: Option<unsafe extern "C" fn() -> ()>;
}
```
This allows runtime-checking the extern weak symbol through the Option.

When emitting LLVM-IR, the Rust compiler currently emits this static
as an i8, and a pointer that is initialized with the value of the global
i8 and represents the nullabilty e.g.
```
@FOO = extern_weak global i8
@_rust_extern_with_linkage_FOO = internal global ptr @FOO
```

This approach does not work well with CFI, where we need to attach CFI
metadata to a concrete function declaration, which was pointed out in
https://github.com/rust-lang/rust/issues/115199.

This change switches to emitting a proper function declaration instead
of a global i8. This allows CFI to work for extern_weak functions.

We keep initializing the Rust internal symbol with the function
declaration, which preserves the correct behavior for runtime checking
the Option.

Co-authored-by: Jakob Koschel <jakobkoschel@google.com>
2025-03-17 08:27:53 +00:00
bors
5f3b84a421 Auto merge of #137278 - heiseish:101210-extra-codegen-tests, r=scottmcm
added some new test to check for result and options opt

Apologies for the delay. Finally have some time to get back into contributing.

## Context
- Added some tests to show optimization on result and options for 64 and 128 bits
- Relevant issue https://github.com/rust-lang/rust/issues/101210

## Some newb questions from me
- [x] My local llvm IR has `nuw` in `result_nop_match_128` etc whereas [godbolt version](https://rust.godbolt.org/z/Td9zoT5zn) doesn't have. So I put optional there, but not sure if it's desirable (maybe I'm not using the compiled llvm in the repo). I ran the test with
```bash
./x test tests/codegen/try_question_mark_nop.rs
```
- [x] Unless I'm reading it wrongly, but `option_nop_match_128` and `option_nop_traits_128` look to be **not** optimized away?

Update:
Here's the test for future reference
```rust
// CHECK-LABEL: `@option_nop_match_128`
#[no_mangle]
pub fn option_nop_match_128(x: Option<i128>) -> Option<i128> {
    // CHECK: start:
    // CHECK-NEXT: %trunc = trunc nuw i128 %0 to i1
    // CHECK-NEXT: br i1 %trunc, label %bb3, label %bb4
    // CHECK: bb3:
    // CHECK-NEXT: %2 = getelementptr inbounds {{(nuw )?}}i8, ptr %_0, i64 16
    // CHECK-NEXT: store i128 %1, ptr %2, align 16
    // CHECK: bb4:
    // CHECK-NEXT: %storemerge = phi i128 [ 1, %bb3 ], [ 0, %start ]
    // CHECK-NEXT: store i128 %storemerge, ptr %_0, align 16
    // CHECK-NEXT: ret void
    match x {
        Some(x) => Some(x),
        None => None,
    }
}
```

r? `@scottmcm`
2025-03-16 05:17:07 +00:00
许杰友 Jieyou Xu (Joe)
c05a643ca8
Rollup merge of #138472 - KonaeAkira:master, r=Mark-Simulacrum
Add codegen test for #129795

Adds test for #129795.

Min LLVM version is 20 because the optimization only happens since LLVM 20.
2025-03-16 09:40:09 +08:00
bors
523c507d26 Auto merge of #138157 - scottmcm:inline-more-tiny-things, r=oli-obk
Allow more top-down inlining for single-BB callees

This means that things like `<usize as Step>::forward_unchecked` and `<PartialOrd for f32>::le` will inline even if
we've already done a bunch of inlining to find the calls to them.

Fixes #138136

~~Draft as it's built atop #138135, which adds a mir-opt test that's a nice demonstration of this.  To see just this change, look at <48f63e3be5>~~ Rebased to be just the inlining change, as the other existing tests show it great.
2025-03-14 03:51:19 +00:00
KonaeAkira
ccde0a2203 Fix formatting (line too long) 2025-03-14 01:45:10 +01:00
bors
addae0705c Auto merge of #138391 - scottmcm:SSA-discriminants, r=WaffleLapkin
Don't `alloca` just to look at a discriminant

Today we're making LLVM do a bunch of extra work when you match on trivial stuff like `Option<bool>` or `ControlFlow<u8>`.

This PR changes that so that simple types like `Option<u32>` or `Result<(), Box<Error>>` can stay as `OperandValue::ScalarPair` and we can still read the discriminant from them, rather than needing to write them into memory to have a `PlaceValue` just to get the discriminant out.

Fixes #137503
2025-03-14 00:42:31 +00:00
KonaeAkira
82a79b99e1 Add codegen test for modulo with power-of-two divisor 2025-03-14 01:27:07 +01:00
Matthias Krüger
1827ffdef0
Rollup merge of #138346 - folkertdev:naked-asm-windows-endef, r=ChrisDenton
naked functions: on windows emit `.endef` without the symbol name

tracking issue: https://github.com/rust-lang/rust/issues/90957
fixes https://github.com/rust-lang/rust/issues/138320

The `.endef` directive does not take the name as an argument. Apparently the LLVM x86_64 parser does accept this, but on i686 it's rejected. In general `i686` does some special name mangling stuff, so it's good to include it in the naked function tests.

r? ````@ChrisDenton```` (because windows)
2025-03-13 10:58:23 +01:00
Scott McMurray
91af4aa2e2 Allow more top-down inlining for single-BB callees
This means that things like `<usize as Step>::forward_unchecked` and `<PartialOrd for f32>::le` will inline even if we've already done a bunch of inlining to find the calls to them.
2025-03-12 22:39:43 -07:00
Giang Dao
0fba203d9e added some new test to check for result and options opt 2025-03-12 20:15:14 +08:00
Scott McMurray
143f39362a Don't alloca just to look at a discriminant
Today we're making LLVM do a bunch of extra work for every enum you match on, even trivial stuff like `Option<bool>`.  Let's not.
2025-03-12 00:56:43 -07:00
Oli Scherer
cb4751d4b8 Implement #[define_opaque] attribute for functions. 2025-03-11 12:05:02 +00:00
Folkert de Vries
c0957ef45a
naked functions: on windows emit .endef without the symbol name
also add test with `fastcall`, which on i686 uses a different mangling scheme
2025-03-11 00:27:32 +01:00
Matthias Krüger
827bb5e27b
Rollup merge of #122790 - Zoxc:dllimp-rev, r=ChrisDenton
Apply dllimport in ThinLTO

This partially reverts https://github.com/rust-lang/rust/pull/103353 by properly applying `dllimport` if  `-Z dylib-lto` is passed. That PR should probably fully be reverted as it looks quite sketchy. We don't know locally if the entire crate graph would be statically linked.

This should hopefully be sufficient to make ThinLTO work for rustc on Windows.

r? ``@wesleywiser``

---

Edit: This PR is changed to just generally revert https://github.com/rust-lang/rust/pull/103353.
2025-03-09 16:41:48 +01:00
bors
446649d463 Auto merge of #137513 - scottmcm:identity-transmute, r=saethlin
Don't re-`assume` in `transmute`s that don't change niches

I noticed in nightly 2025-02-21 that `transmute` is emitting way more `assume`s than necessary for newtypes.

For example, the three transmutes in <https://rust.godbolt.org/z/fW1KaTc4o> emits
```rust
define noundef range(i32 1, 0) i32 `@repeatedly_transparent_transmute(i32` noundef range(i32 1, 0) %_1) unnamed_addr {
start:
  %0 = sub i32 %_1, 1
  %1 = icmp ule i32 %0, -2
  call void `@llvm.assume(i1` %1)
  %2 = sub i32 %_1, 1
  %3 = icmp ule i32 %2, -2
  call void `@llvm.assume(i1` %3)
  %4 = sub i32 %_1, 1
  %5 = icmp ule i32 %4, -2
  call void `@llvm.assume(i1` %5)
  %6 = sub i32 %_1, 1
  %7 = icmp ule i32 %6, -2
  call void `@llvm.assume(i1` %7)
  %8 = sub i32 %_1, 1
  %9 = icmp ule i32 %8, -2
  call void `@llvm.assume(i1` %9)
  %10 = sub i32 %_1, 1
  %11 = icmp ule i32 %10, -2
  call void `@llvm.assume(i1` %11)
  ret i32 %_1
}
```

But those are all just newtypes that don't change size or niches, so none of it's needed.

After this PR it's down to just
```rust
define noundef range(i32 1, 0) i32 `@repeatedly_transparent_transmute(i32` noundef range(i32 1, 0) %_1) unnamed_addr {
start:
  ret i32 %_1
}
```
because none of those `assume`s in the original actually did anything.

(Transmuting to something with a difference niche, though, still has the assumes -- the other tests continue to pass checking that.)
2025-03-09 01:25:48 +00:00
bors
dea1661cdb Auto merge of #137502 - compiler-errors:global-asm-aint-mir-body, r=oli-obk
Don't include global asm in `mir_keys`, fix error body synthesis

r? oli-obk

Fixes #137470
Fixes #137471
Fixes #137472
Fixes #137473

try-job: test-various
try-job: x86_64-apple-2
2025-03-08 22:23:45 +00:00
bors
efea9896f5 Auto merge of #137500 - scottmcm:trunc-br, r=saethlin
Use `trunc nuw`+`br` for 0/1 branches even in optimized builds

Rather than needing to use `switch` for them to include the `unreachable` arm.
2025-03-08 19:01:10 +00:00
Matthias Krüger
1155f01c5a
Rollup merge of #138073 - tmiasko:inline-asm-critical-edges, r=bjorn3
Break critical edges in inline asm before code generation

An inline asm terminator defines outputs along its target edges -- a
fallthrough target and labeled targets. Code generation implements this
by inserting code directly into the target blocks. This approach works
only if the target blocks don't have other predecessors.

Establish required invariant by extending existing code that breaks
critical edges before code generation.

Fixes #137867.

r? ``@bjorn3``
2025-03-07 10:12:46 +01:00
Scott McMurray
d9432acfe1 Use trunc nuw+br for 0/1 branches even in optimized builds
Rather than needing to use `switch` for them to include the `unreachable` arm
2025-03-06 22:25:49 -08:00
Michael Goulet
5339d4ef5b Fix target-feature inline test to be less flaky 2025-03-06 19:56:21 +00:00
Tomasz Miąsko
5c1733e4f4 Break critical edges in inline asm before code generation
An inline asm terminator defines outputs along its target edges -- a
fallthrough target and labeled targets. Code generation implements this
by inserting code directly into the target blocks. This approach works
only if the target blocks don't have other predecessors.

Establish required invariant by extending existing code that breaks
critical edges before code generation.
2025-03-06 20:00:24 +01:00
DaniPopes
58c10c66c1
Lower BinOp::Cmp to llvm.{s,u}cmp.* intrinsics
Lowers `mir::BinOp::Cmp` (`three_way_compare` intrinsic) to the corresponding
LLVM `llvm.{s,u}cmp.i8.*` intrinsics, added in LLVM 19.
2025-03-06 22:29:05 +08:00
Oli Scherer
a2c1211b6d Hide the end of ranges in pretty printing if it's also the maximum of the type 2025-03-06 10:50:23 +00:00
bors
fd17deacce Auto merge of #137959 - matthiaskrgr:rollup-62vjvwr, r=matthiaskrgr
Rollup of 12 pull requests

Successful merges:

 - #135767 (Future incompatibility warning `unsupported_fn_ptr_calling_conventions`: Also warn in dependencies)
 - #137852 (Remove layouting dead code for non-array SIMD types.)
 - #137863 (Fix pretty printing of unsafe binders)
 - #137882 (do not build additional stage on compiler paths)
 - #137894 (Revert "store ScalarPair via memset when one side is undef and the other side can be memset")
 - #137902 (Make `ast::TokenKind` more like `lexer::TokenKind`)
 - #137921 (Subtree update of `rust-analyzer`)
 - #137922 (A few cleanups after the removal of `cfg(not(parallel))`)
 - #137939 (fix order on shl impl)
 - #137946 (Fix docker run-local docs)
 - #137955 (Always allow rustdoc-json tests to contain long lines)
 - #137958 (triagebot.toml: Don't label `test/rustdoc-json` as A-rustdoc-search)

r? `@ghost`
`@rustbot` modify labels: rollup
2025-03-04 02:27:56 +00:00
Matthias Krüger
70b9968d1e
Rollup merge of #137894 - compiler-errors:no-scalar-pair-opt, r=oli-obk
Revert "store ScalarPair via memset when one side is undef and the other side can be memset"

cc #137892
reverts #135335

r? oli-obk
2025-03-03 20:47:12 +01:00
John Kåre Alsaker
cc39e5f266 Apply dllimport in ThinLTO 2025-03-03 13:44:53 +01:00
Matthias Krüger
15e97bd45e
Rollup merge of #137826 - karolzwolak:looping_over_ne_bytes_133528, r=DianQK
test(codegen): add looping_over_ne_bytes test for #133528

Adds test for #133528.
I renamed the function to `looping_over_ne_bytes` to better reflect that it is doing.
I also set the min llvm version to 20 as this was presumably a llvm bug that was fixed in version 20.
I didn't tie the test to any specific architecture, as we are testing llvm output.
2025-03-03 06:41:36 +01:00
Michael Goulet
5f575bc4bc Add a test 2025-03-02 18:53:49 +00:00
Michael Goulet
a59a8f9e75 Revert "Auto merge of #135335 - oli-obk:push-zxwssomxxtnq, r=saethlin"
This reverts commit a7a6c64a65, reversing
changes made to ebbe63891f.
2025-03-02 18:52:48 +00:00
Matthias Krüger
224ea37aa3
Rollup merge of #137818 - durin42:llvm-21-remove-readonly, r=jieyouxu
tests: adapt for LLVM 21 changes

Per discussion in #137799 we don't really need this readonly attribute, so let's just drop it so the test passes on LLVM 21.

Fixes #137799.
2025-03-01 16:03:15 +01:00
bors
8c392966a0 Auto merge of #137848 - matthiaskrgr:rollup-vxtrkis, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #136503 (Tweak output of const panic diagnostic)
 - #137390 (tests: fix up new test for nocapture -> capture(none) change)
 - #137617 (Introduce `feature(generic_const_parameter_types)`)
 - #137719 (Add missing case explanation for doc inlined re-export of doc hidden item)
 - #137763 (Use `mk_ty_from_kind` a bit less, clean up lifetime handling in borrowck)
 - #137769 (Do not yeet `unsafe<>` from type when formatting unsafe binder)
 - #137776 (Some `rustc_transmute` cleanups)
 - #137800 (Remove `ParamEnv::without_caller_bounds`)

r? `@ghost`
`@rustbot` modify labels: rollup
2025-03-01 11:43:19 +00:00
Matthias Krüger
11ddd56b31
Rollup merge of #137390 - durin42:llvm-21-nocapture-rename, r=nikic
tests: fix up new test for nocapture -> capture(none) change

Same change as #136287, but for a newly introduced test.

``@rustbot`` label llvm-main
r? ``@nikic``
2025-03-01 11:33:58 +01:00
bors
0c72c0d11a Auto merge of #133250 - DianQK:embed-bitcode-pgo, r=nikic
The embedded bitcode should always be prepared for LTO/ThinLTO

Fixes #115344. Fixes #117220.

There are currently two methods for generating bitcode that used for LTO. One method involves using `-C linker-plugin-lto` to emit object files as bitcode, which is the typical setting used by cargo. The other method is through `-C embed-bitcode=yes`.

When using with `-C embed-bitcode=yes -C lto=no`, we run a complete non-LTO LLVM pipeline to obtain bitcode, then the bitcode is used for LTO. We run the Call Graph Profile Pass twice on the same module.

This PR is doing something similar to LLVM's `buildFatLTODefaultPipeline`, obtaining the bitcode for embedding after running `buildThinLTOPreLinkDefaultPipeline`.

r? nikic
2025-03-01 08:22:18 +00:00
Karol Zwolak
107d7ef767 test(codegen): add looping_over_ne_bytes test for #133528 2025-02-28 22:37:56 +01:00
Augie Fackler
2d3639d559 tests: adapt for LLVM 21 changes
Per discussion in #137799 we don't really need this readonly attribute,
so let's just drop it so the test passes on LLVM 21.

Fixes #137799.
2025-02-28 14:27:22 -05:00
许杰友 Jieyou Xu (Joe)
50ed7f974b
Rollup merge of #137599 - davidtwco:use-minicore-more, r=jieyouxu
tests: use minicore more

minicore makes it much easier to add new language items to all of the existing `no_core` tests.

Most of the remaining tests that *could* use minicore either fail because..

1. LLVM IR output changes and doesn't pass the test as written. I didn't look into these further.
2. The test has revisions w/ different compilation flags, expecting some to fail, and when using minicore, minicore is compiled with those flags and fails in the expected way because of the flags rather than the test, and that's considered a failure.

But these tests can be changed and make adding new language items a lot easier.

r? ```@jieyouxu```
2025-02-28 22:29:52 +08:00
许杰友 Jieyou Xu (Joe)
50ef985be2
Rollup merge of #137551 - folkertdev:import-simd-intrinsics, r=RalfJung
import `simd_` intrinsics

In most cases, we can import the simd intrinsics rather than redeclare them. Apparently, most of these tests were written before `std::intrinsics::simd` existed.

There are a couple of exceptions where we can't yet import:

- the intrinsics are not declared as `const fn` in the standard library, causing issues in the `const-eval` tests
- the `simd_shuffle_generic` function is not exposed from `std::intrinsics`
- the `simd_fpow` and `simd_fpowi` functions are not exposed from `std::intrinsics` (removed in https://github.com/rust-lang/rust/pull/137595)
- some tests use `no_core`, and therefore cannot use `std::intrinsics`

r? ```@RalfJung```

cc ```@workingjubilee``` do you have context on why some intrinsics are not exposed?
2025-02-28 22:29:51 +08:00
许杰友 Jieyou Xu (Joe)
87cac9fdb5
Rollup merge of #137197 - scottmcm:cmp-20, r=ibraheemdev
Update some comparison codegen tests now that they pass in LLVM20

Fixes #106107

Needed one tweak to the default `PartialOrd::le` to get the test to pass.  Everything but the derived 2-field `le` test passes even without the change to the defaults in the trait.
2025-02-28 22:29:50 +08:00
Folkert de Vries
038f4e2ff6
use the right feature in codegen tests 2025-02-27 12:23:00 +01:00
Folkert de Vries
d8a067b931
remove most simd_ intrinsic declaration in tests
instead, we can just import the intrinsics from core
2025-02-27 12:22:59 +01:00