Skip to content

Commit

Permalink
Auto merge of #85290 - Amanieu:asm_const_int, r=nagisa
Browse files Browse the repository at this point in the history
Remove support for floating-point constants in asm!

Floating-point constants aren't very useful anyways and this simplifies
the code since the type check can now be done in typeck.

cc `@rust-lang/wg-inline-asm`

r? `@nagisa`
  • Loading branch information
bors committed May 16, 2021
2 parents f8e1e92 + 1605e0e commit 7dc9ff5
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 91 deletions.
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`.

0 comments on commit 7dc9ff5

Please sign in to comment.