Skip to content

Commit ee93b05

Browse files
committed
Auto merge of #151598 - JonathanBrouwer:rollup-RSdwbHy, r=JonathanBrouwer
Rollup of 3 pull requests Successful merges: - #151346 (add `simd_splat` intrinsic) - #151353 (compiletest: Make `aux-crate` directive explicitly handle `--extern` modifiers) - #151571 (Fix cstring-merging test for Hexagon target) r? @ghost
2 parents 021fc25 + 85f5e7c commit ee93b05

16 files changed

Lines changed: 283 additions & 30 deletions

File tree

compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,31 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
348348
ret.write_cvalue(fx, ret_lane);
349349
}
350350

351+
sym::simd_splat => {
352+
intrinsic_args!(fx, args => (value); intrinsic);
353+
354+
if !ret.layout().ty.is_simd() {
355+
report_simd_type_validation_error(fx, intrinsic, span, ret.layout().ty);
356+
return;
357+
}
358+
let (lane_count, lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
359+
360+
if value.layout().ty != lane_ty {
361+
fx.tcx.dcx().span_fatal(
362+
span,
363+
format!(
364+
"[simd_splat] expected element type {lane_ty:?}, got {got:?}",
365+
got = value.layout().ty
366+
),
367+
);
368+
}
369+
370+
for i in 0..lane_count {
371+
let ret_lane = ret.place_lane(fx, i.into());
372+
ret_lane.write_cvalue(fx, value);
373+
}
374+
}
375+
351376
sym::simd_neg
352377
| sym::simd_bswap
353378
| sym::simd_bitreverse

compiler/rustc_codegen_gcc/src/intrinsic/simd.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,42 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
121121
return Ok(bx.vector_select(vector_mask, arg1, args[2].immediate()));
122122
}
123123

124+
#[cfg(feature = "master")]
125+
if name == sym::simd_splat {
126+
let (out_len, out_ty) = require_simd2!(ret_ty, SimdReturn);
127+
128+
require!(
129+
args[0].layout.ty == out_ty,
130+
InvalidMonomorphization::ExpectedVectorElementType {
131+
span,
132+
name,
133+
expected_element: out_ty,
134+
vector_type: ret_ty,
135+
}
136+
);
137+
138+
let vec_ty = llret_ty.unqualified().dyncast_vector().expect("vector return type");
139+
let elem_ty = vec_ty.get_element_type();
140+
141+
// Cast pointer type to usize (GCC does not support pointer SIMD vectors).
142+
let value = args[0];
143+
let scalar = if value.layout.ty.is_numeric() {
144+
value.immediate()
145+
} else if value.layout.ty.is_raw_ptr() {
146+
bx.ptrtoint(value.immediate(), elem_ty)
147+
} else {
148+
return_error!(InvalidMonomorphization::UnsupportedOperation {
149+
span,
150+
name,
151+
in_ty: ret_ty,
152+
in_elem: value.layout.ty
153+
});
154+
};
155+
156+
let elements = vec![scalar; out_len as usize];
157+
return Ok(bx.context.new_rvalue_from_vector(bx.location, llret_ty, &elements));
158+
}
159+
124160
// every intrinsic below takes a SIMD vector as its first argument
125161
require_simd!(
126162
args[0].layout.ty,

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,6 +1581,31 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
15811581
return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
15821582
}
15831583

1584+
if name == sym::simd_splat {
1585+
let (_out_len, out_ty) = require_simd!(ret_ty, SimdReturn);
1586+
1587+
require!(
1588+
args[0].layout.ty == out_ty,
1589+
InvalidMonomorphization::ExpectedVectorElementType {
1590+
span,
1591+
name,
1592+
expected_element: out_ty,
1593+
vector_type: ret_ty,
1594+
}
1595+
);
1596+
1597+
// `insertelement <N x elem> poison, elem %x, i32 0`
1598+
let poison_vec = bx.const_poison(llret_ty);
1599+
let idx0 = bx.const_i32(0);
1600+
let v0 = bx.insert_element(poison_vec, args[0].immediate(), idx0);
1601+
1602+
// `shufflevector <N x elem> v0, <N x elem> poison, <N x i32> zeroinitializer`
1603+
// The masks is all zeros, so this splats lane 0 (which has our element in it).
1604+
let splat = bx.shuffle_vector(v0, poison_vec, bx.const_null(llret_ty));
1605+
1606+
return Ok(splat);
1607+
}
1608+
15841609
// every intrinsic below takes a SIMD vector as its first argument
15851610
let (in_len, in_elem) = require_simd!(args[0].layout.ty, SimdInput);
15861611
let in_ty = args[0].layout.ty;

compiler/rustc_codegen_ssa/src/mir/operand.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1074,8 +1074,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10741074
if constant_ty.is_simd() {
10751075
// However, some SIMD types do not actually use the vector ABI
10761076
// (in particular, packed SIMD types do not). Ensure we exclude those.
1077+
//
1078+
// We also have to exclude vectors of pointers because `immediate_const_vector`
1079+
// does not work for those.
10771080
let layout = bx.layout_of(constant_ty);
1078-
if let BackendRepr::SimdVector { .. } = layout.backend_repr {
1081+
let (_, element_ty) = constant_ty.simd_size_and_type(bx.tcx());
1082+
if let BackendRepr::SimdVector { .. } = layout.backend_repr
1083+
&& element_ty.is_numeric()
1084+
{
10791085
let (llval, ty) = self.immediate_const_vector(bx, constant);
10801086
return OperandRef {
10811087
val: OperandValue::Immediate(llval),

compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,15 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
6161
}
6262
self.copy_op(&self.project_index(&input, index)?, &dest)?;
6363
}
64+
sym::simd_splat => {
65+
let elem = &args[0];
66+
let (dest, dest_len) = self.project_to_simd(&dest)?;
67+
68+
for i in 0..dest_len {
69+
let place = self.project_index(&dest, i)?;
70+
self.copy_op(elem, &place)?;
71+
}
72+
}
6473
sym::simd_neg
6574
| sym::simd_fabs
6675
| sym::simd_ceil

compiler/rustc_hir_analysis/src/check/intrinsic.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,7 @@ pub(crate) fn check_intrinsic_type(
746746
sym::simd_extract | sym::simd_extract_dyn => {
747747
(2, 0, vec![param(0), tcx.types.u32], param(1))
748748
}
749+
sym::simd_splat => (2, 0, vec![param(1)], param(0)),
749750
sym::simd_cast
750751
| sym::simd_as
751752
| sym::simd_cast_ptr

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2141,6 +2141,7 @@ symbols! {
21412141
simd_shr,
21422142
simd_shuffle,
21432143
simd_shuffle_const_generic,
2144+
simd_splat,
21442145
simd_sub,
21452146
simd_trunc,
21462147
simd_with_exposed_provenance,

library/core/src/intrinsics/simd.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ pub const unsafe fn simd_insert_dyn<T, U>(x: T, idx: u32, val: U) -> T;
5252
#[rustc_intrinsic]
5353
pub const unsafe fn simd_extract_dyn<T, U>(x: T, idx: u32) -> U;
5454

55+
/// Creates a vector where every lane has the provided value.
56+
///
57+
/// `T` must be a vector with element type `U`.
58+
#[rustc_nounwind]
59+
#[rustc_intrinsic]
60+
pub const unsafe fn simd_splat<T, U>(value: U) -> T;
61+
5562
/// Adds two simd vectors elementwise.
5663
///
5764
/// `T` must be a vector of integers or floats.

src/doc/rustc-dev-guide/src/tests/compiletest.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,9 @@ to link to the extern crate to make the crate be available as an extern prelude.
665665
That allows you to specify the additional syntax of the `--extern` flag, such as
666666
renaming a dependency. For example, `//@ aux-crate:foo=bar.rs` will compile
667667
`auxiliary/bar.rs` and make it available under then name `foo` within the test.
668-
This is similar to how Cargo does dependency renaming.
668+
This is similar to how Cargo does dependency renaming. It is also possible to
669+
specify [`--extern` modifiers](https://github.com/rust-lang/rust/issues/98405).
670+
For example, `//@ aux-crate:noprelude:foo=bar.rs`.
669671

670672
`aux-bin` is similar to `aux-build` but will build a binary instead of a
671673
library. The binary will be available in `auxiliary/bin` relative to the working

src/doc/rustc-dev-guide/src/tests/directives.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,14 @@ Directives can generally be found by browsing the
5353

5454
See [Building auxiliary crates](compiletest.html#building-auxiliary-crates)
5555

56-
| Directive | Explanation | Supported test suites | Possible values |
57-
|-----------------------|-------------------------------------------------------------------------------------------------------|----------------------------------------|-----------------------------------------------|
58-
| `aux-bin` | Build a aux binary, made available in `auxiliary/bin` relative to test directory | All except `run-make`/`run-make-cargo` | Path to auxiliary `.rs` file |
59-
| `aux-build` | Build a separate crate from the named source file | All except `run-make`/`run-make-cargo` | Path to auxiliary `.rs` file |
60-
| `aux-crate` | Like `aux-build` but makes available as extern prelude | All except `run-make`/`run-make-cargo` | `<extern_prelude_name>=<path/to/aux/file.rs>` |
61-
| `aux-codegen-backend` | Similar to `aux-build` but pass the compiled dylib to `-Zcodegen-backend` when building the main file | `ui-fulldeps` | Path to codegen backend file |
62-
| `proc-macro` | Similar to `aux-build`, but for aux forces host and don't use `-Cprefer-dynamic`[^pm]. | All except `run-make`/`run-make-cargo` | Path to auxiliary proc-macro `.rs` file |
63-
| `build-aux-docs` | Build docs for auxiliaries as well. Note that this only works with `aux-build`, not `aux-crate`. | All except `run-make`/`run-make-cargo` | N/A |
56+
| Directive | Explanation | Supported test suites | Possible values |
57+
|-----------------------|-------------------------------------------------------------------------------------------------------|----------------------------------------|--------------------------------------------------------------------|
58+
| `aux-bin` | Build a aux binary, made available in `auxiliary/bin` relative to test directory | All except `run-make`/`run-make-cargo` | Path to auxiliary `.rs` file |
59+
| `aux-build` | Build a separate crate from the named source file | All except `run-make`/`run-make-cargo` | Path to auxiliary `.rs` file |
60+
| `aux-crate` | Like `aux-build` but makes available as extern prelude | All except `run-make`/`run-make-cargo` | `[<extern_modifiers>:]<extern_prelude_name>=<path/to/aux/file.rs>` |
61+
| `aux-codegen-backend` | Similar to `aux-build` but pass the compiled dylib to `-Zcodegen-backend` when building the main file | `ui-fulldeps` | Path to codegen backend file |
62+
| `proc-macro` | Similar to `aux-build`, but for aux forces host and don't use `-Cprefer-dynamic`[^pm]. | All except `run-make`/`run-make-cargo` | Path to auxiliary proc-macro `.rs` file |
63+
| `build-aux-docs` | Build docs for auxiliaries as well. Note that this only works with `aux-build`, not `aux-crate`. | All except `run-make`/`run-make-cargo` | N/A |
6464

6565
[^pm]: please see the [Auxiliary proc-macro section](compiletest.html#auxiliary-proc-macro) in the compiletest chapter for specifics.
6666

0 commit comments

Comments
 (0)