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 rustc_intrinsic_const_vector_arg attribute to allow vectors to be passed as constants #118980
base: master
Are you sure you want to change the base?
Conversation
r? @wesleywiser (rustbot has picked a reviewer for you, use r? to override) |
rust-analyzer is developed in its own repository. If possible, consider making this change to rust-lang/rust-analyzer instead. cc @rust-lang/rust-analyzer These commits modify the If this was unintentional then you should revert the changes before this PR is merged. Some changes occurred in compiler/rustc_codegen_gcc |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @bjorn3
☔ The latest upstream changes (presumably #119070) made this pull request unmergeable. Please resolve the merge conflicts. |
I have narrowed the scope of this attribute to only being applicable to simd types defined in the local crate as I do not know how to check if the type is a simd type when it is not local in HIR. |
This comment has been minimized.
This comment has been minimized.
☔ The latest upstream changes (presumably #119146) made this pull request unmergeable. Please resolve the merge conflicts. |
b71f4ab
to
66d3179
Compare
This comment has been minimized.
This comment has been minimized.
… as constants This allows constant vectors using a repr(simd) type to be propagated through to the backend by reusing the functionality used to do a similar thing for the simd_shuffle intrinsic. fix rust-lang#118209
The job Click to see the possible cause of the failure (guessed by this bot)
|
☔ The latest upstream changes (presumably #120500) made this pull request unmergeable. Please resolve the merge conflicts. |
@GeorgeWort can you address the CI test failure? once that's done you can comment with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This diff is much bigger than needed. See #121225 for a PR that makes some other intrinsics require a constant argument; this should share that same check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact the even better alternative is probably to remove the simd_shuffle case entirely, and just add the new attribute to simd_shuffle.
let mut copied_constant_arguments = vec![]; | ||
'make_args: for (i, arg) in first_args.iter().enumerate() { | ||
let mut op = self.codegen_operand(bx, &arg.node); | ||
let mut op = if const_vec_arg_indexes.contains(&i) { | ||
// Force the specified argument to be constant by using const-qualification to promote any complex rvalues to constant. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is misleading. You are not promoting anything here, and you shouldn't. You are not forcing anything to be a constant either, you are relying on the fact that typecheck already already ensured that this is a constant.
fn foo2(a: i8x2, b: i8); | ||
} | ||
|
||
#[rustc_intrinsic_const_vector_arg(0)] //~ ERROR attribute should be applied to functions in `extern "unadjusted"` modules |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason this argument needs to be about const vectors?
If this were to become a general rustc_intrinsic_const_arg
, then it could also be used for simd_insert/extract.
r? @oli-obk |
{ | ||
match attr.meta_item_list() { | ||
Some(items) => { | ||
items.into_iter().for_each(|item: rustc_ast::NestedMetaItem| match item { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
items.into_iter().for_each(|item: rustc_ast::NestedMetaItem| match item { | |
items.into_iter().for_each(|item| match item { |
rustc_ast::NestedMetaItem::Lit(rustc_ast::MetaItemLit { | ||
kind: rustc_ast::LitKind::Int(index, _), | ||
.. | ||
}) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prefer using item.lit()
kind: rustc_ast::LitKind::Int(index, _), | ||
.. | ||
}) => { | ||
if index >= args.len() as u128 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to avoid checking the index separately from indexing, use
if index >= args.len() as u128 { | |
let Some(arg) = args.get(index.get().try_into().unwrap()) { |
let (llval, ty) = self.early_evaluate_const_vector(bx, constant); | ||
let llval = llval.unwrap_or_else(|| { | ||
bx.tcx().dcx().emit_err(errors::ShuffleIndicesEvaluation { | ||
span: constant.span, | ||
}); | ||
// We've errored, so we don't have to produce working code. | ||
let llty = bx.backend_type(bx.layout_of(ty)); | ||
bx.const_undef(llty) | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deduplicate this with the other use sites
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually, just do this inside early_evaluate_const_vector
like it was done before this PR and remove ShuffleIndicesEvaluation
if let Some(def) = def | ||
&& let Some(attr) = | ||
bx.tcx().get_attr(def.def_id(), sym::rustc_intrinsic_const_vector_arg) | ||
{ | ||
attr.meta_item_list() | ||
.iter() | ||
.flatten() | ||
.map(|item: &NestedMetaItem| match item { | ||
NestedMetaItem::Lit(MetaItemLit { | ||
kind: LitKind::Int(index, _), .. | ||
}) => index.get() as usize, | ||
_ => span_bug!(item.span(), "attribute argument must be an integer"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
create a helper for this and use it in both attr parsing sites
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While you're here can you explain to me why bx.tcx().get_attr
on line 923 causes the failure I'm seeing in CI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get_attr
within the same crate will create a dependency edge from the calling query to the HIR. It's not a query. Since this is only allowed on intrinsics, we could (after #120675) store it in the ty::IntrinsicDef
struct, so it gets encoded in metadata (so is checked across crates, too), and so it doesn't cause this undesirable dep graph edge
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This attribute is intended for architecture specific intrinsics as used here rather than rust-intrinsics like simd_shuffle
so I don't think that could be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should all at some point go through the intrinsic
query, they just don't do it yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, is there an issue/PR for this that I can mark this PR as blocked on?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#120675 is what needs to land first
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So that means that all of the intrinsic functions in files like this will need to be marked with #[rustc_intrinsic]
? Is there already a PR for this or is that work that will need to be done to enable features such as those provided in this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That won't be necessary immediately. We can move incrementally. The current system will keep on working, it's just that the attribute will be processed early to be returned by the intrinsic
query as a field. It doesn't matter how the intrinsic is declared.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternatively you can encode this information in codegen_fn_attrs
, I think that should also avoid the dep graph edges
@@ -2082,6 +2087,112 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | |||
false | |||
} | |||
|
|||
fn check_rustc_intrinsic_const_vector_arg( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems unnecessary. Just ICEing the compiler when the attribute is misused is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it okay to ICE here while other rustc intrinsics have a check function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other intrinsics don't need these check functions. Some people just really like adding them.^^ But it's a bunch of extra work to write and maintain that code, and not really for any good reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the original reason the platform intrinsics had checks in the first place was to allow exposing extern "platform-intrinsics"
on stable: https://rust-lang.github.io/rfcs/1199-simd-infrastructure.html That plan didn't end up making it and stdarch was introduced later. And much later portable-simd was introduced which internally used platform-intrinsics.
This allows constant vectors using a repr(simd) type to be propagated
through to the backend by reusing the functionality used to do a similar
thing for the simd_shuffle intrinsic.
fix #118209