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

Add noundef metadata for fits-in-target-pointer-size array immediate arguments #123425

Closed
wants to merge 6 commits into from

Conversation

jieyouxu
Copy link
Member

@jieyouxu jieyouxu commented Apr 3, 2024

noundef is only added if the small array immediate fits in the target pointer size and if optimizations are enabled.

Closes #123183.

@rustbot
Copy link
Collaborator

rustbot commented Apr 3, 2024

r? @TaKO8Ki

rustbot has assigned @TaKO8Ki.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@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. labels Apr 3, 2024
tests/codegen/union-abi.rs Outdated Show resolved Hide resolved
@clubby789
Copy link
Contributor

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Apr 3, 2024
@bors
Copy link
Contributor

bors commented Apr 3, 2024

⌛ Trying commit 31abdb2 with merge 6be5114...

bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 3, 2024
…<try>

Add `noundef` metadata for fits-in-target-pointer-size array immediate arguments

`noundef` is only added if the small array immediate fits in the target pointer size and if optimizations are enabled.

Closes rust-lang#123183.
@bors
Copy link
Contributor

bors commented Apr 3, 2024

☀️ Try build successful - checks-actions
Build commit: 6be5114 (6be511458bb70e6b7db8ec27a49f5a0067274688)

@rust-timer

This comment has been minimized.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (6be5114): comparison URL.

Overall result: no relevant changes - no action needed

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf.

@bors rollup=never
@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

This benchmark run did not return any relevant results for this metric.

Max RSS (memory usage)

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
0.1% [0.1%, 0.1%] 1
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-2.4% [-2.4%, -2.4%] 1
All ❌✅ (primary) 0.1% [0.1%, 0.1%] 1

Cycles

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
3.9% [3.9%, 3.9%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-2.4% [-2.4%, -2.4%] 1
All ❌✅ (primary) - - 0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 666.914s -> 667.807s (0.13%)
Artifact size: 318.16 MiB -> 318.17 MiB (0.01%)

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Apr 4, 2024
@DianQK
Copy link
Member

DianQK commented Apr 7, 2024

Is it working on the following code?

#[repr(transparent)]
pub struct Foo([u8; 4]);

#[repr(transparent)]
pub struct Baz(Foo);

#[no_mangle]
pub fn replace_repr_transparent_struct_short_array_2(r: &mut Baz, v: Baz) -> Baz {
    std::mem::replace(r, v)
}

@clubby789
Copy link
Contributor

define i32 @replace_repr_transparent_struct_short_array_2(ptr noalias nocapture noundef align 1 dereferenceable(4) %r, i32 %0) unnamed_addr #0 {
start:
  %result.sroa.0.0.copyload = load i32, ptr %r, align 1
  store i32 %0, ptr %r, align 1
  ret i32 %result.sroa.0.0.copyload
}

@jieyouxu
Copy link
Member Author

jieyouxu commented Apr 7, 2024

aaaaa right, recursive #[repr(transparent)], I have not considered that....

@jieyouxu
Copy link
Member Author

jieyouxu commented Apr 7, 2024

@rustbot author

@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 Apr 7, 2024
@jieyouxu
Copy link
Member Author

jieyouxu commented Apr 7, 2024

I made the is_transparent_array check recursive now, so it should see through nested #[repr(transparent)] cases (added a test case for that).

@rustbot ready

@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 Apr 7, 2024
tests/codegen/array-immediate-param-noundef.rs Outdated Show resolved Hide resolved
tests/codegen/array-immediate-param-noundef.rs Outdated Show resolved Hide resolved
tests/codegen/array-immediate-param-noundef.rs Outdated Show resolved Hide resolved
Copy link
Member

@DianQK DianQK left a comment

Choose a reason for hiding this comment

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

LGTM. But I believe this still requires someone with r+ privileges to take a look.

r? compiler

@rustbot rustbot assigned davidtwco and unassigned TaKO8Ki Apr 11, 2024
@davidtwco
Copy link
Member

@bors r=davidtwco,DianQK

@bors
Copy link
Contributor

bors commented Apr 16, 2024

📌 Commit 6bf21cf has been approved by davidtwco,DianQK

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 Apr 16, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 16, 2024
…davidtwco,DianQK

Add `noundef` metadata for fits-in-target-pointer-size array immediate arguments

`noundef` is only added if the small array immediate fits in the target pointer size and if optimizations are enabled.

Closes rust-lang#123183.
@bors
Copy link
Contributor

bors commented Apr 16, 2024

⌛ Testing commit 6bf21cf with merge 57a2597...

// `#[repr(transparent)] enum` containing array. Note that `#[repr(transparent)]`
// can contain other `#[repr(transparent)]` structs or enums, which can eventually
// contain an array!
if arg.layout.ty.is_array() || is_transparent_array(cx, arg.layout) {
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand why arrays would be special here. What if this is an array of unions, or something like that?

let mut adt_layout = outermost_layout;
// Recursively walk a layout, seeing through all `#[repr(transparent)]` layers.
while adt_layout.is_transparent::<LayoutCx<'tcx, TyCtxt<'tcx>>>()
&& let Some((_, layout)) = adt_layout.non_1zst_field(cx)
Copy link
Member

Choose a reason for hiding this comment

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

Note that unions can be transparent, so wouldn't this do the wrong thing then?

Copy link
Member

Choose a reason for hiding this comment

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

At least for structs, there's not really any need to check for is_transparent. This is an optimization so we can just make use of the fact that a struct is a wrapper (i.e., non_1zst_field returns Some) even without a repr.

@RalfJung
Copy link
Member

@bors r-
because of missing tests and since at first glance it seems some of these tests may actually fail -- better safe than sorry

@bors bors 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-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Apr 16, 2024

// # Negative examples

// This inner struct is *not* `#[repr(transparent)]`, so we must not emit `noundef` for the outer
Copy link
Member

Choose a reason for hiding this comment

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

Why "must not"? With the layout we pick this would still be correct.

Copy link
Member

@RalfJung RalfJung Apr 16, 2024

Choose a reason for hiding this comment

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

This testcase is missing negative tests with transparent unions, and arrays of unions, to ensure they do not get the attribute.

@RalfJung
Copy link
Member

How do I get bors to process the next PR?
@bors force

@@ -784,6 +784,21 @@ fn fn_abi_adjust_for_abi<'tcx>(
// an LLVM aggregate type for this leads to bad optimizations,
// so we pick an appropriately sized integer type instead.
arg.cast_to(Reg { kind: RegKind::Integer, size });

// Let's see if we can add a `noundef`. This is only legal for arrays, definitely
Copy link
Member

Choose a reason for hiding this comment

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

I think the elephant in the room here is padding, isn't it? Arrays are fine as they do not have any padding. But the word "padding" does not appear anywhere in the PR diff or description, so I am confused.

@bors
Copy link
Contributor

bors commented Apr 16, 2024

☀️ Try build successful - checks-actions
Build commit: 57a2597 (57a25976fe3c471108640effc63529372c2b61ca)

@scottmcm
Copy link
Member

I agree that there's nothing particularly special about arrays here -- it might be possible for other aggregates too. I just opened the issue saying arrays because that's the place I noticed it and I was confident about. (Since [i32; 1] definitely can't be undef.)

But for example we don't put noundef on { i32, i32 } returns either right now, it looks like, and we probably could. That's probably better as a "not this PR", though.

@jieyouxu
Copy link
Member Author

Thanks for the catch, I'll revisit this PR in a few days when less busy

@jieyouxu
Copy link
Member Author

jieyouxu commented May 4, 2024

(Still busy, will have more time towards the end of this month)

@jieyouxu jieyouxu marked this pull request as draft June 8, 2024 18:25
@jieyouxu
Copy link
Member Author

jieyouxu commented Jun 9, 2024

Unfortunately I don't have the bandwidth to work on this, but other people are welcomed to pick this up.

@jieyouxu jieyouxu closed this Jun 9, 2024
@jieyouxu jieyouxu deleted the array-imm-noundef-param branch July 1, 2024 11:39
bors added a commit to rust-lang-ci/rust that referenced this pull request Jul 1, 2024
…<try>

Annotate eligible small immediate arguments with `noundef`

Retake of rust-lang#123425.

We try to annotate small (fits within target pointer width) aggregate arguments passed as immediates
(specifically casted as "appropriately sized integer type") with `noundef`.

Example:

```rs
#[no_mangle]
pub fn short_array_u64x1(v: [u64; 1]) -> [u64; 1] { v }
```

currently produces

```llvm
define i64 `@short_array_u64x1(i64` %0) ...
```

This PR changes that to

```llvm
define noundef i64 `@short_array_u64x1(i64` noundef %0) ...
```

The `noundef` attribute is added only if the immediate value has no padding. Specifically,
the conservative heuristic we use is to:

- Peel away layers of `#[repr(Rust)]` or `#[repr(transparent)]` wrappers if present
- Check for innermost simple arrays (whose element type is a primitive type) that can fit within
  target pointer width

Union immediates or otherwise anything that contains unions will not have `noundef` attribute
applied.

Closes rust-lang#123183.

cc `@/RalfJung` who pointed out various problems with the previous take, hopefully I addressed most of
them in this take.

r? `@ghost` (perf)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Array-as-Immediate array ABI is missing noundef parameter metadata
10 participants