Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
28e0907
nontemporal_store: make sure that the intrinsic is truly just a hint
RalfJung Jul 24, 2024
697787a
RISC-V also has sane nontemporal stores
RalfJung Jul 25, 2024
a282e52
Unify run button display with "copy code" button and with mdbook buttons
GuillaumeGomez Jul 30, 2024
be71bd9
Update GUI tests for code example buttons
GuillaumeGomez Jul 30, 2024
e2da2fb
Update rustdoc tests
GuillaumeGomez Jul 30, 2024
59cb159
Prevent clicking on a link or on a button to toggle the code example …
GuillaumeGomez Jul 30, 2024
27ca35a
const vector passed to codegen
Jamesbarford Aug 8, 2024
03ee7b5
Move verbose help parsing to `main`
Kobzol Aug 9, 2024
5431a93
Pass `Flags` to `Config::parse` explicitly
Kobzol Aug 9, 2024
f83b085
rustc_attr: remove redundant `#[allow(rustc::untranslatable_diagnosti…
GrigorenkoPV Aug 7, 2024
43f3a21
rustc_const_eval: remove redundant `#[allow(rustc::untranslatable_dia…
GrigorenkoPV Aug 7, 2024
3a18c6b
rustc_const_eval: make message about "const stable" translatable
GrigorenkoPV Aug 7, 2024
a11922d
rustc_const_eval: make LazyLock suggestion translatable
GrigorenkoPV Aug 7, 2024
c36b21a
rustc_attr: make "compact `cfg(target(..))` is unstable" translatable
GrigorenkoPV Aug 7, 2024
334a097
rustc_ast_lowering: make "using `_` for array lengths is unstable" tr…
GrigorenkoPV Aug 7, 2024
290df4f
rustc_ast_lowering: make "yield syntax is experimental" translatable
GrigorenkoPV Aug 7, 2024
6760298
rustc_ast_lowering: make asm-related unstability messages translatable
GrigorenkoPV Aug 7, 2024
48413cf
rustc_borrowck: make dereference suggestion translatable
GrigorenkoPV Aug 8, 2024
446e03e
rustc_borrowck: make suggestion to move closure translatable
GrigorenkoPV Aug 8, 2024
1b6cc24
rustc_borrowck: make some suggestion about static lifetimes translatable
GrigorenkoPV Aug 8, 2024
1481ab3
rustc_borrowck: make "implicit static" suff translatable
GrigorenkoPV Aug 8, 2024
f43cdce
rustc_borrowck: fmt
GrigorenkoPV Aug 8, 2024
fbc2459
rustc_expand: remove some redundant `#[allow(rustc::untranslatable_di…
GrigorenkoPV Aug 8, 2024
1373074
rustc_expand: make a message translatable
GrigorenkoPV Aug 8, 2024
cbae581
rustc_interface: remove a redundant `#[allow(rustc::untranslatable_di…
GrigorenkoPV Aug 8, 2024
2babab6
rustc_lint: remove some redundant `#[allow(rustc::untranslatable_diag…
GrigorenkoPV Aug 8, 2024
d548636
rustc_metadata: remove a redundant `#[allow(rustc::untranslatable_dia…
GrigorenkoPV Aug 8, 2024
007cc2c
rustc_metadata: make "link {arg,cfg} is unstable" translatable
GrigorenkoPV Aug 8, 2024
fcdb374
rustc_passes: remove a redundant `#[allow(rustc::untranslatable_diagn…
GrigorenkoPV Aug 9, 2024
f09a2b0
rustc_passes: make some messages in check_attr translatable
GrigorenkoPV Aug 9, 2024
03b6c2f
Fix and enable disabled codegen-units tests
saethlin Aug 10, 2024
141d9dc
remove unused imports from rmake tests
lqd Aug 10, 2024
f4cb0de
remove other warnings from rmake tests
lqd Aug 10, 2024
dcd6170
use `rfs` in rustdoc io rmake test
lqd Aug 11, 2024
c361c92
Use assert_matches around the compiler
compiler-errors Aug 11, 2024
46b4c5a
Fix bug in `Parser::look_ahead`.
nnethercote Aug 12, 2024
8542cd6
std: do not overwrite style in `get_backtrace_style`
joboet Aug 4, 2024
75743dc
make the codegen test also cover an ill-behaved arch, and add links
RalfJung Aug 12, 2024
095ca33
Rollup merge of #128149 - RalfJung:nontemporal_store, r=jieyouxu,Aman…
GuillaumeGomez Aug 12, 2024
c6e3385
Rollup merge of #128394 - GuillaumeGomez:run-button, r=t-rustdoc
GuillaumeGomez Aug 12, 2024
aea5087
Rollup merge of #128537 - Jamesbarford:118980-const-vector, r=RalfJun…
GuillaumeGomez Aug 12, 2024
aa6f240
Rollup merge of #128632 - joboet:dont_overwrite_style, r=Amanieu
GuillaumeGomez Aug 12, 2024
355a232
Rollup merge of #128878 - Kobzol:refactor-flags, r=onur-ozkan
GuillaumeGomez Aug 12, 2024
ea74eff
Rollup merge of #128886 - GrigorenkoPV:untranslatable-diagnostic, r=n…
GuillaumeGomez Aug 12, 2024
5b6379a
Rollup merge of #128929 - saethlin:enable-codegen-units-tests, r=comp…
GuillaumeGomez Aug 12, 2024
bb35b88
Rollup merge of #128937 - lqd:clean-rmake-tests, r=jieyouxu
GuillaumeGomez Aug 12, 2024
7c6dca9
Rollup merge of #128978 - compiler-errors:assert-matches, r=jieyouxu
GuillaumeGomez Aug 12, 2024
99a785d
Rollup merge of #128994 - nnethercote:fix-Parser-look_ahead-more, r=c…
GuillaumeGomez Aug 12, 2024
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
5 changes: 5 additions & 0 deletions compiler/rustc_codegen_gcc/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
self.context.new_struct_constructor(None, struct_type.as_type(), None, values)
}

fn const_vector(&self, values: &[RValue<'gcc>]) -> RValue<'gcc> {
let typ = self.type_vector(values[0].get_type(), values.len() as u64);
self.context.new_rvalue_from_vector(None, typ, values)
}

fn const_to_opt_uint(&self, _v: RValue<'gcc>) -> Option<u64> {
// TODO(antoyo)
None
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_codegen_llvm/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,6 @@ impl<'ll> CodegenCx<'ll, '_> {
unsafe { llvm::LLVMConstArray2(ty, elts.as_ptr(), len) }
}

pub fn const_vector(&self, elts: &[&'ll Value]) -> &'ll Value {
let len = c_uint::try_from(elts.len()).expect("LLVMConstVector elements len overflow");
unsafe { llvm::LLVMConstVector(elts.as_ptr(), len) }
}

pub fn const_bytes(&self, bytes: &[u8]) -> &'ll Value {
bytes_in_context(self.llcx, bytes)
}
Expand Down Expand Up @@ -221,6 +216,11 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
struct_in_context(self.llcx, elts, packed)
}

fn const_vector(&self, elts: &[&'ll Value]) -> &'ll Value {
let len = c_uint::try_from(elts.len()).expect("LLVMConstVector elements len overflow");
unsafe { llvm::LLVMConstVector(elts.as_ptr(), len) }
}

fn const_to_opt_uint(&self, v: &'ll Value) -> Option<u64> {
try_as_const_integral(v).and_then(|v| unsafe {
let mut i = 0u64;
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -923,8 +923,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// third argument must be constant. This is
// checked by the type-checker.
if i == 2 && intrinsic.name == sym::simd_shuffle {
// FIXME: the simd_shuffle argument is actually an array,
// not a vector, so we need this special hack to make sure
// it is passed as an immediate. We should pass the
// shuffle indices as a vector instead to avoid this hack.
if let mir::Operand::Constant(constant) = &arg.node {
let (llval, ty) = self.simd_shuffle_indices(bx, constant);
let (llval, ty) = self.immediate_const_vector(bx, constant);
return OperandRef {
val: Immediate(llval),
layout: bx.layout_of(ty),
Expand Down
39 changes: 29 additions & 10 deletions compiler/rustc_codegen_ssa/src/mir/constant.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::layout::HasTyCtxt;
use rustc_middle::ty::{self, Ty};
use rustc_middle::ty::{self, Ty, ValTree};
use rustc_middle::{bug, mir, span_bug};
use rustc_target::abi::Abi;

Expand Down Expand Up @@ -28,7 +28,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
.expect("erroneous constant missed by mono item collection")
}

/// This is a convenience helper for `simd_shuffle_indices`. It has the precondition
/// This is a convenience helper for `immediate_const_vector`. It has the precondition
/// that the given `constant` is an `Const::Unevaluated` and must be convertible to
/// a `ValTree`. If you want a more general version of this, talk to `wg-const-eval` on zulip.
///
Expand Down Expand Up @@ -59,23 +59,42 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.cx.tcx().const_eval_resolve_for_typeck(ty::ParamEnv::reveal_all(), uv, constant.span)
}

/// process constant containing SIMD shuffle indices
pub fn simd_shuffle_indices(
/// process constant containing SIMD shuffle indices & constant vectors
pub fn immediate_const_vector(
&mut self,
bx: &Bx,
constant: &mir::ConstOperand<'tcx>,
) -> (Bx::Value, Ty<'tcx>) {
let ty = self.monomorphize(constant.ty());
let ty_is_simd = ty.is_simd();
// FIXME: ideally we'd assert that this is a SIMD type, but simd_shuffle
// in its current form relies on a regular array being passed as an
// immediate argument. This hack can be removed once that is fixed.
let field_ty = if ty_is_simd {
ty.simd_size_and_type(bx.tcx()).1
} else {
ty.builtin_index().unwrap()
};

let val = self
.eval_unevaluated_mir_constant_to_valtree(constant)
.ok()
.map(|x| x.ok())
.flatten()
.map(|val| {
let field_ty = ty.builtin_index().unwrap();
let values: Vec<_> = val
.unwrap_branch()
.iter()
// Depending on whether this is a SIMD type with an array field
// or a type with many fields (one for each elements), the valtree
// is either a single branch with N children, or a root node
// with exactly one child which then in turn has many children.
// So we look at the first child to determine whether it is a
// leaf or whether we have to go one more layer down.
let branch_or_leaf = val.unwrap_branch();
let first = branch_or_leaf.get(0).unwrap();
let field_iter = match first {
ValTree::Branch(_) => first.unwrap_branch().iter(),
ValTree::Leaf(_) => branch_or_leaf.iter(),
};
let values: Vec<_> = field_iter
.map(|field| {
if let Some(prim) = field.try_to_scalar() {
let layout = bx.layout_of(field_ty);
Expand All @@ -84,11 +103,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
};
bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout))
} else {
bug!("simd shuffle field {:?}", field)
bug!("field is not a scalar {:?}", field)
}
})
.collect();
bx.const_struct(&values, false)
if ty_is_simd { bx.const_vector(&values) } else { bx.const_struct(&values, false) }
})
.unwrap_or_else(|| {
bx.tcx().dcx().emit_err(errors::ShuffleIndicesEvaluation { span: constant.span });
Expand Down
19 changes: 18 additions & 1 deletion compiler/rustc_codegen_ssa/src/mir/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.codegen_consume(bx, place.as_ref())
}

mir::Operand::Constant(ref constant) => self.eval_mir_constant_to_operand(bx, constant),
mir::Operand::Constant(ref constant) => {
let constant_ty = self.monomorphize(constant.ty());
// Most SIMD vector constants should be passed as immediates.
// (In particular, some intrinsics really rely on this.)
if constant_ty.is_simd() {
// However, some SIMD types do not actually use the vector ABI
// (in particular, packed SIMD types do not). Ensure we exclude those.
let layout = bx.layout_of(constant_ty);
if let Abi::Vector { .. } = layout.abi {
let (llval, ty) = self.immediate_const_vector(bx, constant);
return OperandRef {
val: OperandValue::Immediate(llval),
layout: bx.layout_of(ty),
};
}
}
self.eval_mir_constant_to_operand(bx, constant)
}
}
}
}
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/traits/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub trait ConstMethods<'tcx>: BackendTypes {

fn const_str(&self, s: &str) -> (Self::Value, Self::Value);
fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value;
fn const_vector(&self, elts: &[Self::Value]) -> Self::Value;

fn const_to_opt_uint(&self, v: Self::Value) -> Option<u64>;
fn const_to_opt_u128(&self, v: Self::Value, sign_ext: bool) -> Option<u128>;
Expand Down
107 changes: 107 additions & 0 deletions tests/codegen/const-vector.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
//@ compile-flags: -C no-prepopulate-passes -Copt-level=0

// This test checks that constants of SIMD type are passed as immediate vectors.
// We ensure that both vector representations (struct with fields and struct wrapping array) work.
#![crate_type = "lib"]
#![feature(abi_unadjusted)]
#![feature(const_trait_impl)]
#![feature(repr_simd)]
#![feature(rustc_attrs)]
#![feature(simd_ffi)]
#![allow(non_camel_case_types)]

// Setting up structs that can be used as const vectors
#[repr(simd)]
#[derive(Clone)]
pub struct i8x2(i8, i8);

#[repr(simd)]
#[derive(Clone)]
pub struct i8x2_arr([i8; 2]);

#[repr(simd)]
#[derive(Clone)]
pub struct f32x2(f32, f32);

#[repr(simd)]
#[derive(Clone)]
pub struct f32x2_arr([f32; 2]);

#[repr(simd, packed)]
#[derive(Copy, Clone)]
pub struct Simd<T, const N: usize>([T; N]);

// The following functions are required for the tests to ensure
// that they are called with a const vector

extern "unadjusted" {
#[no_mangle]
fn test_i8x2(a: i8x2);
}

extern "unadjusted" {
#[no_mangle]
fn test_i8x2_two_args(a: i8x2, b: i8x2);
}

extern "unadjusted" {
#[no_mangle]
fn test_i8x2_mixed_args(a: i8x2, c: i32, b: i8x2);
}

extern "unadjusted" {
#[no_mangle]
fn test_i8x2_arr(a: i8x2_arr);
}

extern "unadjusted" {
#[no_mangle]
fn test_f32x2(a: f32x2);
}

extern "unadjusted" {
#[no_mangle]
fn test_f32x2_arr(a: f32x2_arr);
}

extern "unadjusted" {
#[no_mangle]
fn test_simd(a: Simd<i32, 4>);
}

extern "unadjusted" {
#[no_mangle]
fn test_simd_unaligned(a: Simd<i32, 3>);
}

// Ensure the packed variant of the simd struct does not become a const vector
// if the size is not a power of 2
// CHECK: %"Simd<i32, 3>" = type { [3 x i32] }

pub fn do_call() {
unsafe {
// CHECK: call void @test_i8x2(<2 x i8> <i8 32, i8 64>
test_i8x2(const { i8x2(32, 64) });

// CHECK: call void @test_i8x2_two_args(<2 x i8> <i8 32, i8 64>, <2 x i8> <i8 8, i8 16>
test_i8x2_two_args(const { i8x2(32, 64) }, const { i8x2(8, 16) });

// CHECK: call void @test_i8x2_mixed_args(<2 x i8> <i8 32, i8 64>, i32 43, <2 x i8> <i8 8, i8 16>
test_i8x2_mixed_args(const { i8x2(32, 64) }, 43, const { i8x2(8, 16) });

// CHECK: call void @test_i8x2_arr(<2 x i8> <i8 32, i8 64>
test_i8x2_arr(const { i8x2_arr([32, 64]) });

// CHECK: call void @test_f32x2(<2 x float> <float 0x3FD47AE140000000, float 0x3FE47AE140000000>
test_f32x2(const { f32x2(0.32, 0.64) });

// CHECK: void @test_f32x2_arr(<2 x float> <float 0x3FD47AE140000000, float 0x3FE47AE140000000>
test_f32x2_arr(const { f32x2_arr([0.32, 0.64]) });

// CHECK: call void @test_simd(<4 x i32> <i32 2, i32 4, i32 6, i32 8>
test_simd(const { Simd::<i32, 4>([2, 4, 6, 8]) });

// CHECK: call void @test_simd_unaligned(%"Simd<i32, 3>" %1
test_simd_unaligned(const { Simd::<i32, 3>([2, 4, 6]) });
}
}