Skip to content

Remove support for floating-point constants in asm! #85290

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

Merged
merged 2 commits into from
May 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions compiler/rustc_codegen_ssa/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,6 @@ pub fn asm_const_to_str<'tcx>(
ty::IntTy::I128 => (value as i128).to_string(),
ty::IntTy::Isize => unreachable!(),
},
ty::Float(ty::FloatTy::F32) => f32::from_bits(value as u32).to_string(),
ty::Float(ty::FloatTy::F64) => f64::from_bits(value as u64).to_string(),
_ => span_bug!(sp, "asm const has bad type {}", ty_and_layout.ty),
}
}
43 changes: 2 additions & 41 deletions compiler/rustc_passes/src/intrinsicck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ impl ExprVisitor<'tcx> {
}

fn check_asm(&self, asm: &hir::InlineAsm<'tcx>) {
for (idx, (op, op_sp)) in asm.operands.iter().enumerate() {
for (idx, (op, _)) in asm.operands.iter().enumerate() {
match *op {
hir::InlineAsmOperand::In { reg, ref expr } => {
self.check_asm_operand_type(idx, reg, expr, asm.template, None);
Expand All @@ -372,19 +372,7 @@ impl ExprVisitor<'tcx> {
);
}
}
hir::InlineAsmOperand::Const { ref anon_const } => {
let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id);
let value = ty::Const::from_anon_const(self.tcx, anon_const_def_id);
match value.ty.kind() {
ty::Int(_) | ty::Uint(_) | ty::Float(_) => {}
_ => {
let msg =
"asm `const` arguments must be integer or floating-point values";
self.tcx.sess.span_err(*op_sp, msg);
}
}
}
hir::InlineAsmOperand::Sym { .. } => {}
hir::InlineAsmOperand::Const { .. } | hir::InlineAsmOperand::Sym { .. } => {}
}
}
}
Expand All @@ -405,33 +393,6 @@ impl Visitor<'tcx> for ItemVisitor<'tcx> {
ExprVisitor { tcx: self.tcx, param_env, typeck_results }.visit_body(body);
self.visit_body(body);
}

fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
if let hir::ItemKind::GlobalAsm(asm) = item.kind {
for (op, op_sp) in asm.operands {
match *op {
hir::InlineAsmOperand::Const { ref anon_const } => {
let anon_const_def_id = self.tcx.hir().local_def_id(anon_const.hir_id);
let value = ty::Const::from_anon_const(self.tcx, anon_const_def_id);
match value.ty.kind() {
ty::Int(_) | ty::Uint(_) | ty::Float(_) => {}
_ => {
let msg = "asm `const` arguments must be integer or floating-point values";
self.tcx.sess.span_err(*op_sp, msg);
}
}
}
hir::InlineAsmOperand::In { .. }
| hir::InlineAsmOperand::Out { .. }
| hir::InlineAsmOperand::InOut { .. }
| hir::InlineAsmOperand::SplitInOut { .. }
| hir::InlineAsmOperand::Sym { .. } => unreachable!(),
}
}
}

intravisit::walk_item(self, item);
}
}

impl Visitor<'tcx> for ExprVisitor<'tcx> {
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_typeck/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,10 +554,8 @@ fn typeck_with_fallback<'tcx>(
_ => false,
}) =>
{
fcx.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::MiscVariable,
span,
})
// Inline assembly constants must be integers.
fcx.next_int_var()
}
_ => fallback(),
},
Expand Down
2 changes: 1 addition & 1 deletion src/doc/unstable-book/src/library-features/asm.md
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ Several types of operands are supported:
- Identical to `inout` except that the register allocator can reuse a register allocated to an `in` (this can happen if the compiler knows the `in` has the same initial value as the `inlateout`).
- You should only write to the register after all inputs are read, otherwise you may clobber an input.
* `const <expr>`
- `<expr>` must be an integer or floating-point constant expression.
- `<expr>` must be an integer constant expression.
- The value of the expression is formatted as a string and substituted directly into the asm template string.
* `sym <path>`
- `<path>` must refer to a `fn` or `static`.
Expand Down
22 changes: 21 additions & 1 deletion src/test/ui/asm/type-check-1.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// only-x86_64

#![feature(asm)]
#![feature(asm, global_asm)]

fn main() {
unsafe {
Expand Down Expand Up @@ -39,5 +39,25 @@ fn main() {
asm!("{}", const const_bar(0));
asm!("{}", const const_bar(x));
//~^ ERROR attempt to use a non-constant value in a constant

// Const operands must be integers and must be constants.

asm!("{}", const 0);
asm!("{}", const 0i32);
asm!("{}", const 0i128);
asm!("{}", const 0f32);
//~^ ERROR mismatched types
asm!("{}", const 0 as *mut u8);
//~^ ERROR mismatched types
}
}

// Const operands must be integers and must be constants.

global_asm!("{}", const 0);
global_asm!("{}", const 0i32);
global_asm!("{}", const 0i128);
global_asm!("{}", const 0f32);
//~^ ERROR mismatched types
global_asm!("{}", const 0 as *mut u8);
//~^ ERROR mismatched types
34 changes: 32 additions & 2 deletions src/test/ui/asm/type-check-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,37 @@ LL | asm!("{}", inout(reg) v[..]);
= help: the trait `Sized` is not implemented for `[u64]`
= note: all inline asm arguments must have a statically known size

error: aborting due to 8 previous errors
error[E0308]: mismatched types
--> $DIR/type-check-1.rs:48:26
|
LL | asm!("{}", const 0f32);
| ^^^^ expected integer, found `f32`

error[E0308]: mismatched types
--> $DIR/type-check-1.rs:50:26
|
LL | asm!("{}", const 0 as *mut u8);
| ^^^^^^^^^^^^ expected integer, found *-ptr
|
= note: expected type `{integer}`
found raw pointer `*mut u8`

error[E0308]: mismatched types
--> $DIR/type-check-1.rs:60:25
|
LL | global_asm!("{}", const 0f32);
| ^^^^ expected integer, found `f32`

error[E0308]: mismatched types
--> $DIR/type-check-1.rs:62:25
|
LL | global_asm!("{}", const 0 as *mut u8);
| ^^^^^^^^^^^^ expected integer, found *-ptr
|
= note: expected type `{integer}`
found raw pointer `*mut u8`

error: aborting due to 12 previous errors

Some errors have detailed explanations: E0277, E0435.
Some errors have detailed explanations: E0277, E0308, E0435.
For more information about an error, try `rustc --explain E0277`.
18 changes: 1 addition & 17 deletions src/test/ui/asm/type-check-2.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// only-x86_64

#![feature(asm, global_asm, repr_simd, never_type)]
#![feature(asm, repr_simd, never_type)]

#[repr(simd)]
struct SimdNonCopy(f32, f32, f32, f32);
Expand All @@ -26,14 +26,6 @@ fn main() {
asm!("{}", inout(reg) v[0]);
//~^ ERROR cannot borrow `v` as mutable, as it is not declared as mutable

// Const operands must be integer or floats, and must be constants.

asm!("{}", const 0);
asm!("{}", const 0i32);
asm!("{}", const 0f32);
asm!("{}", const 0 as *mut u8);
//~^ ERROR asm `const` arguments must be integer or floating-point values

// This currently causes an ICE: https://github.com/rust-lang/rust/issues/81857
// asm!("{}", const &0);
// ERROR asm `const` arguments must be integer or floating-point values
Expand Down Expand Up @@ -90,11 +82,3 @@ fn main() {
asm!("{}", in(reg) u);
}
}

// Const operands must be integer or floats, and must be constants.

global_asm!("{}", const 0);
global_asm!("{}", const 0i32);
global_asm!("{}", const 0f32);
global_asm!("{}", const 0 as *mut u8);
//~^ ERROR asm `const` arguments must be integer or floating-point values
34 changes: 11 additions & 23 deletions src/test/ui/asm/type-check-2.stderr
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
error: asm `const` arguments must be integer or floating-point values
--> $DIR/type-check-2.rs:34:20
|
LL | asm!("{}", const 0 as *mut u8);
| ^^^^^^^^^^^^^^^^^^

error: arguments for inline assembly must be copyable
--> $DIR/type-check-2.rs:54:32
--> $DIR/type-check-2.rs:46:32
|
LL | asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `SimdNonCopy` does not implement the Copy trait

error: cannot use value of type `[closure@$DIR/type-check-2.rs:66:28: 66:38]` for inline assembly
--> $DIR/type-check-2.rs:66:28
error: cannot use value of type `[closure@$DIR/type-check-2.rs:58:28: 58:38]` for inline assembly
--> $DIR/type-check-2.rs:58:28
|
LL | asm!("{}", in(reg) |x: i32| x);
| ^^^^^^^^^^
|
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly

error: cannot use value of type `Vec<i32>` for inline assembly
--> $DIR/type-check-2.rs:68:28
--> $DIR/type-check-2.rs:60:28
|
LL | asm!("{}", in(reg) vec![0]);
| ^^^^^^^
Expand All @@ -30,51 +24,45 @@ LL | asm!("{}", in(reg) vec![0]);
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot use value of type `(i32, i32, i32)` for inline assembly
--> $DIR/type-check-2.rs:70:28
--> $DIR/type-check-2.rs:62:28
|
LL | asm!("{}", in(reg) (1, 2, 3));
| ^^^^^^^^^
|
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly

error: cannot use value of type `[i32; 3]` for inline assembly
--> $DIR/type-check-2.rs:72:28
--> $DIR/type-check-2.rs:64:28
|
LL | asm!("{}", in(reg) [1, 2, 3]);
| ^^^^^^^^^
|
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly

error: cannot use value of type `fn() {main}` for inline assembly
--> $DIR/type-check-2.rs:80:31
--> $DIR/type-check-2.rs:72:31
|
LL | asm!("{}", inout(reg) f);
| ^
|
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly

error: cannot use value of type `&mut i32` for inline assembly
--> $DIR/type-check-2.rs:83:31
--> $DIR/type-check-2.rs:75:31
|
LL | asm!("{}", inout(reg) r);
| ^
|
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly

error: asm `const` arguments must be integer or floating-point values
--> $DIR/type-check-2.rs:99:19
|
LL | global_asm!("{}", const 0 as *mut u8);
| ^^^^^^^^^^^^^^^^^^

error: asm `sym` operand must point to a fn or static
--> $DIR/type-check-2.rs:47:24
--> $DIR/type-check-2.rs:39:24
|
LL | asm!("{}", sym C);
| ^

error: asm `sym` operand must point to a fn or static
--> $DIR/type-check-2.rs:49:24
--> $DIR/type-check-2.rs:41:24
|
LL | asm!("{}", sym x);
| ^
Expand Down Expand Up @@ -109,7 +97,7 @@ LL | let v: Vec<u64> = vec![0, 1, 2];
LL | asm!("{}", inout(reg) v[0]);
| ^ cannot borrow as mutable

error: aborting due to 15 previous errors
error: aborting due to 13 previous errors

Some errors have detailed explanations: E0381, E0596.
For more information about an error, try `rustc --explain E0381`.