Skip to content

CodeGen: rework Aggregate implemention for rvalue_creates_operand cases #142383

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

scottmcm
Copy link
Member

@scottmcm scottmcm commented Jun 11, 2025

A non-trivial refactor pulled out from #138759
r? workingjubilee

The previous implementation I'd written here based on index_by_increasing_offset is complicated to follow and difficult to extend to non-structs.

This changes the implementation, without actually changing any codegen (thus no test changes either), to be more like the existing extract_field (

pub(crate) fn extract_field<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
&self,
fx: &mut FunctionCx<'a, 'tcx, Bx>,
bx: &mut Bx,
i: usize,
) -> Self {
let field = self.layout.field(bx.cx(), i);
let offset = self.layout.fields.offset(i);
if !bx.is_backend_ref(self.layout) && bx.is_backend_ref(field) {
if let BackendRepr::SimdVector { count, .. } = self.layout.backend_repr
&& let BackendRepr::Memory { sized: true } = field.backend_repr
&& count.is_power_of_two()
{
assert_eq!(field.size, self.layout.size);
// This is being deprecated, but for now stdarch still needs it for
// Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]);
let place = PlaceRef::alloca(bx, field);
self.val.store(bx, place.val.with_type(self.layout));
return bx.load_operand(place);
} else {
// Part of https://github.com/rust-lang/compiler-team/issues/838
bug!("Non-ref type {self:?} cannot project to ref field type {field:?}");
}
}
let val = if field.is_zst() {
OperandValue::ZeroSized
} else if field.size == self.layout.size {
assert_eq!(offset.bytes(), 0);
fx.codegen_transmute_operand(bx, *self, field).unwrap_or_else(|| {
bug!(
"Expected `codegen_transmute_operand` to handle equal-size \
field {i:?} projection from {self:?} to {field:?}"
)
})
} else {
let (in_scalar, imm) = match (self.val, self.layout.backend_repr) {
// Extract a scalar component from a pair.
(OperandValue::Pair(a_llval, b_llval), BackendRepr::ScalarPair(a, b)) => {
if offset.bytes() == 0 {
assert_eq!(field.size, a.size(bx.cx()));
(Some(a), a_llval)
} else {
assert_eq!(offset, a.size(bx.cx()).align_to(b.align(bx.cx()).abi));
assert_eq!(field.size, b.size(bx.cx()));
(Some(b), b_llval)
}
}
_ => {
span_bug!(fx.mir.span, "OperandRef::extract_field({:?}): not applicable", self)
}
};
OperandValue::Immediate(match field.backend_repr {
BackendRepr::SimdVector { .. } => imm,
BackendRepr::Scalar(out_scalar) => {
let Some(in_scalar) = in_scalar else {
span_bug!(
fx.mir.span,
"OperandRef::extract_field({:?}): missing input scalar for output scalar",
self
)
};
if in_scalar != out_scalar {
// If the backend and backend_immediate types might differ,
// flip back to the backend type then to the new immediate.
// This avoids nop truncations, but still handles things like
// Bools in union fields needs to be truncated.
let backend = bx.from_immediate(imm);
bx.to_immediate_scalar(backend, out_scalar)
} else {
imm
}
}
BackendRepr::ScalarPair(_, _) | BackendRepr::Memory { .. } => bug!(),
})
};
OperandRef { val, layout: field }
}
) in that it allows setting a particular field directly.

Notably I've found this one much easier to get right, in particular because having the OperandRef<Result<V, Scalar>> gives a really useful thing to include in ICE messages if something did happen to go wrong.

@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 Jun 11, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jun 11, 2025

These commits modify the Cargo.lock file. Unintentional changes to Cargo.lock can be introduced when switching branches and rebasing PRs.

If this was unintentional then you should revert the changes before this PR is merged.
Otherwise, you can ignore this comment.

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

Another refactor pulled out from 138759

The previous implementation I'd written here based on `index_by_increasing_offset` is complicated to follow and difficult to extend to non-structs.

This changes the implementation, without actually changing any codegen (thus no test changes either), to be more like the existing `extract_field` (<https://github.com/rust-lang/rust/blob/2b0274c71dba0e24370ebf65593da450e2e91868/compiler/rustc_codegen_ssa/src/mir/operand.rs#L345-L425>) in that it allows setting a particular field directly.

Notably I've found this one much easier to get right, in particular because having the `OperandRef<Result<V, Scalar>>` gives a really useful thing to include in ICE messages if something did happen to go wrong.
@scottmcm scottmcm force-pushed the operandref-builder branch from b5da991 to e4f196a Compare June 18, 2025 01:59
@workingjubilee
Copy link
Member

should be nop
@bors r+ rollup

@bors
Copy link
Collaborator

bors commented Jun 18, 2025

📌 Commit e4f196a has been approved by workingjubilee

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 Jun 18, 2025
Kobzol added a commit to Kobzol/rust that referenced this pull request Jun 18, 2025
…kingjubilee

CodeGen: rework Aggregate implemention for rvalue_creates_operand cases

A non-trivial refactor pulled out from rust-lang#138759
r? workingjubilee

The previous implementation I'd written here based on `index_by_increasing_offset` is complicated to follow and difficult to extend to non-structs.

This changes the implementation, without actually changing any codegen (thus no test changes either), to be more like the existing `extract_field` (<https://github.com/rust-lang/rust/blob/2b0274c71dba0e24370ebf65593da450e2e91868/compiler/rustc_codegen_ssa/src/mir/operand.rs#L345-L425>) in that it allows setting a particular field directly.

Notably I've found this one much easier to get right, in particular because having the `OperandRef<Result<V, Scalar>>` gives a really useful thing to include in ICE messages if something did happen to go wrong.
bors added a commit that referenced this pull request Jun 18, 2025
Rollup of 12 pull requests

Successful merges:

 - #135656 (Add `-Z hint-mostly-unused` to tell rustc that most of a crate will go unused)
 - #140774 (Affirm `-Cforce-frame-pointers=off` does not override)
 - #141610 (Stabilize `feature(generic_arg_infer)`)
 - #142123 (Implement initial support for timing sections (`--json=timings`))
 - #142383 (CodeGen: rework Aggregate implemention for rvalue_creates_operand cases)
 - #142502 (rustdoc_json: improve handling of generic args)
 - #142591 (Add spawn APIs for BootstrapCommand to support deferred command execution)
 - #142606 (AsyncDrop trait without sync Drop generates an error)
 - #142619 (apply clippy::or_fun_call)
 - #142624 (Actually take `--build` into account in bootstrap)
 - #142627 (Add `StepMetadata` to describe steps)
 - #142660 (remove joboet from review rotation)

r? `@ghost`
`@rustbot` modify labels: rollup
Kobzol added a commit to Kobzol/rust that referenced this pull request Jun 18, 2025
…kingjubilee

CodeGen: rework Aggregate implemention for rvalue_creates_operand cases

A non-trivial refactor pulled out from rust-lang#138759
r? workingjubilee

The previous implementation I'd written here based on `index_by_increasing_offset` is complicated to follow and difficult to extend to non-structs.

This changes the implementation, without actually changing any codegen (thus no test changes either), to be more like the existing `extract_field` (<https://github.com/rust-lang/rust/blob/2b0274c71dba0e24370ebf65593da450e2e91868/compiler/rustc_codegen_ssa/src/mir/operand.rs#L345-L425>) in that it allows setting a particular field directly.

Notably I've found this one much easier to get right, in particular because having the `OperandRef<Result<V, Scalar>>` gives a really useful thing to include in ICE messages if something did happen to go wrong.
Kobzol added a commit to Kobzol/rust that referenced this pull request Jun 18, 2025
…kingjubilee

CodeGen: rework Aggregate implemention for rvalue_creates_operand cases

A non-trivial refactor pulled out from rust-lang#138759
r? workingjubilee

The previous implementation I'd written here based on `index_by_increasing_offset` is complicated to follow and difficult to extend to non-structs.

This changes the implementation, without actually changing any codegen (thus no test changes either), to be more like the existing `extract_field` (<https://github.com/rust-lang/rust/blob/2b0274c71dba0e24370ebf65593da450e2e91868/compiler/rustc_codegen_ssa/src/mir/operand.rs#L345-L425>) in that it allows setting a particular field directly.

Notably I've found this one much easier to get right, in particular because having the `OperandRef<Result<V, Scalar>>` gives a really useful thing to include in ICE messages if something did happen to go wrong.
bors added a commit that referenced this pull request Jun 18, 2025
Rollup of 11 pull requests

Successful merges:

 - #140774 (Affirm `-Cforce-frame-pointers=off` does not override)
 - #141610 (Stabilize `feature(generic_arg_infer)`)
 - #142383 (CodeGen: rework Aggregate implemention for rvalue_creates_operand cases)
 - #142591 (Add spawn APIs for BootstrapCommand to support deferred command execution)
 - #142619 (apply clippy::or_fun_call)
 - #142624 (Actually take `--build` into account in bootstrap)
 - #142627 (Add `StepMetadata` to describe steps)
 - #142660 (remove joboet from review rotation)
 - #142666 (Skip tidy triagebot linkcheck if `triagebot.toml` doesn't exist)
 - #142672 (Clarify bootstrap tools description)
 - #142674 (remove duplicate crash test)

r? `@ghost`
`@rustbot` modify labels: rollup
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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants