Skip to content

Commit 69e45d7

Browse files
authored
Rollup merge of #95740 - Amanieu:kreg0, r=nagisa
asm: Add a kreg0 register class on x86 which includes k0 Previously we only exposed a kreg register class which excludes the k0 register since it can't be used in many instructions. However k0 is a valid register and we need to have a way of marking it as clobbered for clobber_abi. Fixes #94977
2 parents 4ca19e0 + b2bc469 commit 69e45d7

File tree

8 files changed

+40
-25
lines changed

8 files changed

+40
-25
lines changed

compiler/rustc_codegen_gcc/src/asm.rs

+3
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
589589
| InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg) => "x",
590590
InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v",
591591
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => unimplemented!(),
592+
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg0) => unimplemented!(),
592593
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => unimplemented!(),
593594
InlineAsmRegClass::X86(
594595
X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg,
@@ -654,6 +655,7 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
654655
| InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => cx.type_f32(),
655656
InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg) => unimplemented!(),
656657
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => cx.type_i16(),
658+
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg0) => cx.type_i16(),
657659
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),
658660
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
659661
bug!("LLVM backend does not support SPIR-V")
@@ -784,6 +786,7 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option
784786
_ => unreachable!(),
785787
},
786788
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => None,
789+
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg0) => None,
787790
InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg) => {
788791
unreachable!("clobber-only")
789792
}

compiler/rustc_codegen_llvm/src/asm.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,9 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
602602
InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v",
603603
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => "^Yk",
604604
InlineAsmRegClass::X86(
605-
X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg,
605+
X86InlineAsmRegClass::x87_reg
606+
| X86InlineAsmRegClass::mmx_reg
607+
| X86InlineAsmRegClass::kreg0,
606608
) => unreachable!("clobber-only"),
607609
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r",
608610
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r",
@@ -687,7 +689,11 @@ fn modifier_to_llvm(
687689
_ => unreachable!(),
688690
},
689691
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => None,
690-
InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg) => {
692+
InlineAsmRegClass::X86(
693+
X86InlineAsmRegClass::x87_reg
694+
| X86InlineAsmRegClass::mmx_reg
695+
| X86InlineAsmRegClass::kreg0,
696+
) => {
691697
unreachable!("clobber-only")
692698
}
693699
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => None,
@@ -757,7 +763,11 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
757763
| InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg)
758764
| InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => cx.type_f32(),
759765
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => cx.type_i16(),
760-
InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg) => {
766+
InlineAsmRegClass::X86(
767+
X86InlineAsmRegClass::x87_reg
768+
| X86InlineAsmRegClass::mmx_reg
769+
| X86InlineAsmRegClass::kreg0,
770+
) => {
761771
unreachable!("clobber-only")
762772
}
763773
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,7 @@ symbols! {
803803
keyword,
804804
kind,
805805
kreg,
806+
kreg0,
806807
label,
807808
label_break_value,
808809
lang,

compiler/rustc_target/src/asm/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,7 @@ impl InlineAsmClobberAbi {
893893

894894
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
895895

896-
k1, k2, k3, k4, k5, k6, k7,
896+
k0, k1, k2, k3, k4, k5, k6, k7,
897897

898898
mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
899899
st0, st1, st2, st3, st4, st5, st6, st7,
@@ -908,7 +908,7 @@ impl InlineAsmClobberAbi {
908908
zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23,
909909
zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31,
910910

911-
k1, k2, k3, k4, k5, k6, k7,
911+
k0, k1, k2, k3, k4, k5, k6, k7,
912912

913913
mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
914914
st0, st1, st2, st3, st4, st5, st6, st7,
@@ -927,7 +927,7 @@ impl InlineAsmClobberAbi {
927927
zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23,
928928
zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31,
929929

930-
k1, k2, k3, k4, k5, k6, k7,
930+
k0, k1, k2, k3, k4, k5, k6, k7,
931931

932932
mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
933933
st0, st1, st2, st3, st4, st5, st6, st7,

compiler/rustc_target/src/asm/x86.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ def_reg_class! {
1414
ymm_reg,
1515
zmm_reg,
1616
kreg,
17+
kreg0,
1718
mmx_reg,
1819
x87_reg,
1920
}
@@ -38,7 +39,7 @@ impl X86InlineAsmRegClass {
3839
}
3940
Self::reg_byte => &[],
4041
Self::xmm_reg | Self::ymm_reg | Self::zmm_reg => &['x', 'y', 'z'],
41-
Self::kreg => &[],
42+
Self::kreg | Self::kreg0 => &[],
4243
Self::mmx_reg | Self::x87_reg => &[],
4344
}
4445
}
@@ -77,7 +78,7 @@ impl X86InlineAsmRegClass {
7778
256 => Some(('y', "ymm0")),
7879
_ => Some(('x', "xmm0")),
7980
},
80-
Self::kreg => None,
81+
Self::kreg | Self::kreg0 => None,
8182
Self::mmx_reg | Self::x87_reg => None,
8283
}
8384
}
@@ -95,7 +96,7 @@ impl X86InlineAsmRegClass {
9596
Self::xmm_reg => Some(('x', "xmm0")),
9697
Self::ymm_reg => Some(('y', "ymm0")),
9798
Self::zmm_reg => Some(('z', "zmm0")),
98-
Self::kreg => None,
99+
Self::kreg | Self::kreg0 => None,
99100
Self::mmx_reg | Self::x87_reg => None,
100101
}
101102
}
@@ -132,6 +133,7 @@ impl X86InlineAsmRegClass {
132133
avx512f: I8, I16;
133134
avx512bw: I32, I64;
134135
},
136+
Self::kreg0 => &[],
135137
Self::mmx_reg | Self::x87_reg => &[],
136138
}
137139
}
@@ -294,6 +296,7 @@ def_regs! {
294296
zmm29: zmm_reg = ["zmm29", "xmm29", "ymm29"] % x86_64_only,
295297
zmm30: zmm_reg = ["zmm30", "xmm30", "ymm30"] % x86_64_only,
296298
zmm31: zmm_reg = ["zmm31", "xmm31", "ymm31"] % x86_64_only,
299+
k0: kreg0 = ["k0"],
297300
k1: kreg = ["k1"],
298301
k2: kreg = ["k2"],
299302
k3: kreg = ["k3"],
@@ -323,8 +326,6 @@ def_regs! {
323326
"the stack pointer cannot be used as an operand for inline asm",
324327
#error = ["ip", "eip", "rip"] =>
325328
"the instruction pointer cannot be used as an operand for inline asm",
326-
#error = ["k0"] =>
327-
"the k0 AVX mask register cannot be used as an operand for inline asm",
328329
}
329330
}
330331

src/test/codegen/asm-clobber_abi.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,29 @@
66
use std::arch::asm;
77

88
// CHECK-LABEL: @clobber_sysv64
9-
// CHECK: ={ax},={cx},={dx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
9+
// CHECK: ={ax},={cx},={dx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
1010
#[no_mangle]
1111
pub unsafe fn clobber_sysv64() {
1212
asm!("", clobber_abi("sysv64"));
1313
}
1414

1515
// CHECK-LABEL: @clobber_win64
16-
// CHECK: ={ax},={cx},={dx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
16+
// CHECK: ={ax},={cx},={dx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
1717
#[no_mangle]
1818
pub unsafe fn clobber_win64() {
1919
asm!("", clobber_abi("win64"));
2020
}
2121

2222
// CHECK-LABEL: @clobber_sysv64
23-
// CHECK: =&{dx},={ax},={cx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
23+
// CHECK: =&{dx},={ax},={cx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
2424
#[no_mangle]
2525
pub unsafe fn clobber_sysv64_edx() {
2626
let foo: i32;
2727
asm!("", out("edx") foo, clobber_abi("sysv64"));
2828
}
2929

3030
// CHECK-LABEL: @clobber_win64
31-
// CHECK: =&{dx},={ax},={cx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
31+
// CHECK: =&{dx},={ax},={cx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
3232
#[no_mangle]
3333
pub unsafe fn clobber_win64_edx() {
3434
let foo: i32;

src/test/ui/asm/x86_64/bad-reg.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ fn main() {
2929
//~^ ERROR invalid register `rsp`: the stack pointer cannot be used as an operand
3030
asm!("", in("ip") foo);
3131
//~^ ERROR invalid register `ip`: the instruction pointer cannot be used as an operand
32-
asm!("", in("k0") foo);
33-
//~^ ERROR invalid register `k0`: the k0 AVX mask register cannot be used as an operand
3432

3533
asm!("", in("st(2)") foo);
3634
//~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output
3735
asm!("", in("mm0") foo);
3836
//~^ ERROR register class `mmx_reg` can only be used as a clobber, not as an input or output
37+
asm!("", in("k0") foo);
38+
//~^ ERROR register class `kreg0` can only be used as a clobber, not as an input or output
3939
asm!("", out("st(2)") _);
4040
asm!("", out("mm0") _);
4141
asm!("{}", in(x87_reg) foo);

src/test/ui/asm/x86_64/bad-reg.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -64,24 +64,24 @@ error: invalid register `ip`: the instruction pointer cannot be used as an opera
6464
LL | asm!("", in("ip") foo);
6565
| ^^^^^^^^^^^^
6666

67-
error: invalid register `k0`: the k0 AVX mask register cannot be used as an operand for inline asm
68-
--> $DIR/bad-reg.rs:32:18
69-
|
70-
LL | asm!("", in("k0") foo);
71-
| ^^^^^^^^^^^^
72-
7367
error: register class `x87_reg` can only be used as a clobber, not as an input or output
74-
--> $DIR/bad-reg.rs:35:18
68+
--> $DIR/bad-reg.rs:33:18
7569
|
7670
LL | asm!("", in("st(2)") foo);
7771
| ^^^^^^^^^^^^^^^
7872

7973
error: register class `mmx_reg` can only be used as a clobber, not as an input or output
80-
--> $DIR/bad-reg.rs:37:18
74+
--> $DIR/bad-reg.rs:35:18
8175
|
8276
LL | asm!("", in("mm0") foo);
8377
| ^^^^^^^^^^^^^
8478

79+
error: register class `kreg0` can only be used as a clobber, not as an input or output
80+
--> $DIR/bad-reg.rs:37:18
81+
|
82+
LL | asm!("", in("k0") foo);
83+
| ^^^^^^^^^^^^
84+
8585
error: register class `x87_reg` can only be used as a clobber, not as an input or output
8686
--> $DIR/bad-reg.rs:41:20
8787
|

0 commit comments

Comments
 (0)