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

Can't use const fn directly as inline assembly constant input #41337

Closed
parched opened this issue Apr 17, 2017 · 4 comments
Closed

Can't use const fn directly as inline assembly constant input #41337

parched opened this issue Apr 17, 2017 · 4 comments
Labels
A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. A-inline-assembly Area: inline asm!(..) C-bug Category: This is a bug. requires-nightly This issue requires a nightly compiler in some way.

Comments

@parched
Copy link
Contributor

parched commented Apr 17, 2017

I hoped this would work

const fn get_3() -> u32
{
    3
}

pub unsafe fn use_get_3()
{
    asm!("" : : "i"(get_3()))
}

but it generates (without optimizations)

  %0 = call i32 @_ZN8rust_out5get_317hccb90954bf88bf3cE()
  call void asm "", "i,~{dirflag},~{fpsr},~{flags}"(i32 %0)

giving error: invalid operand for inline asm constraint 'i'.

The current solution seems to be

pub unsafe fn use_three()
{
    const THREE: u32 = get_3();
    asm!("" : : "i"(THREE))
}

which generates

  call void asm "", "i,~{dirflag},~{fpsr},~{flags}"(i32 3)

like I hoped the first case would.

Could we make the first case guaranteed to work?

@nagisa nagisa added A-inline-assembly Area: inline asm!(..) A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. labels Apr 17, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 27, 2017
@Centril Centril added the requires-nightly This issue requires a nightly compiler in some way. label Oct 25, 2019
@eddyb
Copy link
Member

eddyb commented Mar 13, 2020

We could make this work the same we did for SIMD intrinsics (requiring certain arguments are constant, and promoting them to ensure codegen can always succeed):
(we just need a way to detect whether a certain inline asm input needs to be constant)

if let TerminatorKind::Call { ref func, .. } = *kind {
if let ty::FnDef(def_id, _) = func.ty(self.body, self.tcx).kind {
let fn_sig = self.tcx.fn_sig(def_id);
if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = fn_sig.abi() {
let name = self.tcx.item_name(def_id);
// FIXME(eddyb) use `#[rustc_args_required_const(2)]` for shuffles.
if name.as_str().starts_with("simd_shuffle") {
self.candidates.push(Candidate::Argument { bb: location.block, index: 2 });
return; // Don't double count `simd_shuffle` candidates
}
}
if let Some(constant_args) = args_required_const(self.tcx, def_id) {
for index in constant_args {
self.candidates.push(Candidate::Argument { bb: location.block, index });
}
}
}
}

cc @Amanieu @oli-obk @ecstatic-morse

@hanna-kruppe
Copy link
Contributor

Note that the current proposal for inline assembly includes const <expr> operands that explicitly are constant expressions, and the prototype implementation treats them more or less as you describe. I don't think it's worth doing the same for "legacy" inline asm.

@eddyb
Copy link
Member

eddyb commented Mar 13, 2020

Oh, nice, for some reason I expected if that were the case we'd get a comment on these issues stating it, I should've checked first.

@Amanieu
Copy link
Member

Amanieu commented May 22, 2020

This issue does not apply to the new asm! (RFC 2850) which has proper support for const operands.

The legacy llvm_asm! is deprecated and is no longer maintained.

@Amanieu Amanieu closed this as completed May 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-fn Area: const fn foo(..) {..}. Pure functions which can be applied at compile time. A-inline-assembly Area: inline asm!(..) C-bug Category: This is a bug. requires-nightly This issue requires a nightly compiler in some way.
Projects
None yet
Development

No branches or pull requests

7 participants