Skip to content

Remove rustc_args_required_const attribute#85110

Merged
bors merged 5 commits into
rust-lang:masterfrom
RalfJung:no-rustc_args_required_const
May 13, 2021
Merged

Remove rustc_args_required_const attribute#85110
bors merged 5 commits into
rust-lang:masterfrom
RalfJung:no-rustc_args_required_const

Conversation

@RalfJung

@RalfJung RalfJung commented May 9, 2021

Copy link
Copy Markdown
Member

Now that stdarch no longer needs it (thanks @Amanieu!), we can kill the rustc_args_required_const attribute. This means that lifetime extension of references to temporaries is the only remaining job that promotion is performing. :-)

r? @oli-obk
Fixes #69493

@rust-highfive

Copy link
Copy Markdown
Contributor

Some changes occured to the CTFE / Miri engine

cc @rust-lang/miri

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 9, 2021
@rust-log-analyzer

This comment has been minimized.

@oli-obk

oli-obk commented May 9, 2021

Copy link
Copy Markdown
Contributor

Looks like we need to do the same transformation that was done to stdarch for SIMD shuffle?

@RalfJung

RalfJung commented May 9, 2021

Copy link
Copy Markdown
Member Author

I am confused... so aho-corasick is somehow directly calling these intrinsics?

The attribute was removed from the shuffle intrinsics with rust-lang/stdarch#1113, but it looks like they were special-cased in the promotion code so they got the magic treatment even without the attribute.

@oli-obk

oli-obk commented May 9, 2021

Copy link
Copy Markdown
Contributor

codegen does have a special case for these, yea. So... we need a const item with the indices and use that as the argument? Then bump stdsimd again and then we can do this PR?

@RalfJung

RalfJung commented May 9, 2021

Copy link
Copy Markdown
Member Author

Not just codegen, but promotion has a special case where it treats them as rustc_args_required_const even when that attribute is not present.

@RalfJung

RalfJung commented May 9, 2021

Copy link
Copy Markdown
Member Author

But yeah, I think the shuffle functions in stdarch need to become rustc_legacy_const_generics as well.

@RalfJung

RalfJung commented May 9, 2021

Copy link
Copy Markdown
Member Author

@RalfJung

RalfJung commented May 9, 2021

Copy link
Copy Markdown
Member Author

Hm okay, this is a bit more tricky than I thought. The shuffle function cannot literally use the "legacy" attribute:

error: #[rustc_legacy_const_generics] functions must only have const generics

And moreover most (all?) calls are inside the same crate so the attribute does not even help...

The alternative is to fix all call sites of simd_shuffle to pass actual constants. I guess ideally the type checker would enforce this as part of a special check for these intrinsics?

@RalfJung

RalfJung commented May 9, 2021

Copy link
Copy Markdown
Member Author

I started seeing what it takes to fix this, and... it's a lot.^^ Here's my WIP patch. I don't like using inline_const (it is marked as incomplete_feature, we should not use those in the std library IMO); I feel the easiest way forward here might be a macro that generates code like

            const IDX: [u32; 32] = $idx;
            simd_shuffle32($x, $y, IDX)

The shuffle functions are AFAIK internal to stdarch, so we can pretty much do whatever we want here.

@RalfJung

RalfJung commented May 9, 2021

Copy link
Copy Markdown
Member Author

Yeah the macro approach looks pretty good, I think.

However, we'll need to figure out what to do with code like this that computes the mask based on other const-generic arguments...

@oli-obk

oli-obk commented May 10, 2021

Copy link
Copy Markdown
Contributor

However, we'll need to figure out what to do with code like this that computes the mask based on other const-generic arguments...

Oof. That is horrible. And the function is stable, too. The only way forward that we currently have is const_evaluatable_checked and that is nowhere near ready.

My proposal would be to compute all four constants as separate constants and do a runtime match on the generic arg and have four monomorphic calls this way.

You can keep the existing code by putting it in a const fn and calling that from each of the four constants

@RalfJung

RalfJung commented May 10, 2021

Copy link
Copy Markdown
Member Author

My proposal would be to compute all four constants as separate constants and do a runtime match on the generic arg and have four monomorphic calls this way.

Which "four constants"? There are 256 possible values for IMM8, aren't there?
I don't understand your proposal.^^

I think long-term the intrinsic itself should be changed to use const generics; this also ensures that we don't get these ICEs. Short-term we can model this with const generic wrapper like

pub fn simd_shuffle32<T, U, IDX: const [u32; 32]>(x: T, y: T) -> U { 
  extern "platform-intrinsic" {
    fn simd_shuffle32<T, U>(x: T, y: T, idx: [u32; 32]) -> U;
  }
  simd_shuffle32(x, y, IDX)
}

However, this complains that [u32; 32] can't be used as const generic yet (and I assume we'd need another incomplete_feature to get around that).

What I don't know is how to write functions like this that call such a const-generic shuffle-wrapper.

@oli-obk

oli-obk commented May 10, 2021

Copy link
Copy Markdown
Contributor

Which "four constants"? There are 256 possible values for IMM8, aren't there?
I don't understand your proposal.^^

Yes, but it is bitmasked to 0b11

What I don't know is how to write functions like this that call such a const-generic shuffle-wrapper.

That's what I was describing in my previous post. If you want to skip the runtime part and do it at compile time, you need the const_evaluatable_checked feature.

@RalfJung

Copy link
Copy Markdown
Member Author

That's what I was describing in my previous post.

Yeah and I did not (and do not) understand the description. ;)

But I think I found another way. :D This macro:

#[allow(unused_macros)]
macro_rules! simd_shuffle8_param {
    ($x:expr, $y:expr, <const $imm:ident : $ty:ty> $idx:expr $(,)?) => {{
        struct ConstParam<const $imm: $ty>;
        impl<const $imm: $ty> ConstParam<$imm> {
            const IDX: [u32; 8] = $idx;
        }

        simd_shuffle8($x, $y, ConstParam::<$imm>::IDX)
    }}
}

Lets me write callers like

pub unsafe fn _mm256_shuffle_epi32<const MASK: i32>(a: __m256i) -> __m256i {
    static_assert_imm8!(MASK);
    let r: i32x8 = simd_shuffle8_param!(
        a.as_i32x8(),
        a.as_i32x8(),
        <const MASK: i32> [
            MASK as u32 & 0b11,
            (MASK as u32 >> 2) & 0b11,
            (MASK as u32 >> 4) & 0b11,
            (MASK as u32 >> 6) & 0b11,
            (MASK as u32 & 0b11) + 4,
            ((MASK as u32 >> 2) & 0b11) + 4,
            ((MASK as u32 >> 4) & 0b11) + 4,
            ((MASK as u32 >> 6) & 0b11) + 4,
        ],
    );
    transmute(r)
}

@RalfJung

Copy link
Copy Markdown
Member Author

With this patch to stdarch, the bootstrap build completes again (or at least, aho-corasick builds; the full build is still ongoing).

@oli-obk @Amanieu would that be an okay avenue to take here?

@RalfJung

RalfJung commented May 10, 2021

Copy link
Copy Markdown
Member Author

@oli-obk I'd also like to have a reasonable error instead of the ICE when a shuffle argument is not a constant.

Currently, such an error is emitted here:

let msg = format!("argument {} is required to be a constant", index + 1);

But with promotion not having anything to do here any more, that makes little sense. What would be the right place to do that check? I thought it might be

pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {

but that function only checks the signature used in the extern block; we need something that checks each use site.

@Amanieu

Amanieu commented May 11, 2021

Copy link
Copy Markdown
Member

The patch to stdarch LGTM, but it looks incomplete (missing the ARM/AArch64 intrinsics for example).

@RalfJung

Copy link
Copy Markdown
Member Author

Yeah I just wanted to get rustc to build for now. Once I figured out how to best make rustc error when the argument is not a const, I will apply this throughout stdarch.

@oli-obk

oli-obk commented May 11, 2021

Copy link
Copy Markdown
Contributor

but that function only checks the signature used in the extern block; we need something that checks each use site.

mir validation perhaps? or just codegen, which is already checking that i thought

@RalfJung

Copy link
Copy Markdown
Member Author

Checking during codegen means we only check this when stdarch is used; I'd rather get the build errors in stdarch itself than waiting until some crate runs into the ICE.^^

MIR validation runs a lot, doesn't it? Seems excessive.
I was thinking of putting it into the lower-intrinsics pass, since at least that is already intrinsics-related...^^

@oli-obk

oli-obk commented May 11, 2021

Copy link
Copy Markdown
Contributor

Checking during codegen means we only check this when stdarch is used; I'd rather get the build errors in stdarch itself than waiting until some crate runs into the ICE.^^

MIR validation runs a lot, doesn't it? Seems excessive.
I was thinking of putting it into the lower-intrinsics pass, since at least that is already intrinsics-related...^^

Yea, that opt is always run, even without optimizations, so 👍

@RalfJung

Copy link
Copy Markdown
Member Author

Yea, that opt is always run, even without optimizations, so +1

All right, done.

The stdarch PR is on its way at rust-lang/stdarch#1160, but some arch/neon intrinsics still need to be adjusted (they are auto-generated and the generating tool needs some changes).

@RalfJung RalfJung force-pushed the no-rustc_args_required_const branch from e75a319 to 51f3e0b Compare May 11, 2021 09:57
@rust-log-analyzer

This comment has been minimized.

@bors

bors commented May 11, 2021

Copy link
Copy Markdown
Collaborator

☔ The latest upstream changes (presumably #85109) made this pull request unmergeable. Please resolve the merge conflicts.

@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 May 12, 2021
@RalfJung

Copy link
Copy Markdown
Member Author

@bors rollup=iffy

@bors

bors commented May 13, 2021

Copy link
Copy Markdown
Collaborator

⌛ Testing commit bc2b62b1012d447e90fd5556cd84694593a987c7 with merge fcb1f66ecdd8af9435334dde4ceef8e1b2efd145...

@rust-log-analyzer

This comment has been minimized.

@bors

bors commented May 13, 2021

Copy link
Copy Markdown
Collaborator

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 13, 2021
@RalfJung

Copy link
Copy Markdown
Member Author

Needs rust-lang/stdarch#1162

@RalfJung RalfJung force-pushed the no-rustc_args_required_const branch from bc2b62b to c61e8fa Compare May 13, 2021 13:01
@RalfJung

Copy link
Copy Markdown
Member Author

@bors r=oli-obk

@bors

bors commented May 13, 2021

Copy link
Copy Markdown
Collaborator

📌 Commit c61e8fa has been approved by oli-obk

@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 May 13, 2021
@bors

bors commented May 13, 2021

Copy link
Copy Markdown
Collaborator

⌛ Testing commit c61e8fa with merge d2df620...

@bors

bors commented May 13, 2021

Copy link
Copy Markdown
Collaborator

☀️ Test successful - checks-actions
Approved by: oli-obk
Pushing d2df620 to master...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove special-case for simd_shuffle intrinsics in promotion

7 participants