Skip to content

Commit 6c0b89d

Browse files
JamesbarfordRalfJung
authored andcommitted
light touch implementation of const vector
1 parent 93ea767 commit 6c0b89d

File tree

5 files changed

+31
-11
lines changed

5 files changed

+31
-11
lines changed

compiler/rustc_codegen_gcc/src/common.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,11 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
160160
self.context.new_struct_constructor(None, struct_type.as_type(), None, values)
161161
}
162162

163+
fn const_vector(&self, values: &[RValue<'gcc>]) -> RValue<'gcc> {
164+
let typ = self.type_vector(values[0].get_type(), values.len() as u64);
165+
self.context.new_rvalue_from_vector(None, typ, values)
166+
}
167+
163168
fn const_to_opt_uint(&self, _v: RValue<'gcc>) -> Option<u64> {
164169
// TODO(antoyo)
165170
None

compiler/rustc_codegen_llvm/src/common.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,10 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
224224
struct_in_context(self.llcx, elts, packed)
225225
}
226226

227+
fn const_vector(&self, elts: &[&'ll Value]) -> &'ll Value {
228+
unsafe { llvm::LLVMConstVector(elts.as_ptr(), elts.len() as c_uint) }
229+
}
230+
227231
fn const_to_opt_uint(&self, v: &'ll Value) -> Option<u64> {
228232
try_as_const_integral(v).and_then(|v| unsafe {
229233
let mut i = 0u64;

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
924924
// checked by the type-checker.
925925
if i == 2 && intrinsic.name == sym::simd_shuffle {
926926
if let mir::Operand::Constant(constant) = &arg.node {
927-
let (llval, ty) = self.simd_shuffle_indices(bx, constant);
927+
let (llval, ty) = self.immediate_const_vector(bx, constant);
928928
return OperandRef {
929929
val: Immediate(llval),
930930
layout: bx.layout_of(ty),

compiler/rustc_codegen_ssa/src/mir/constant.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_middle::mir::interpret::ErrorHandled;
22
use rustc_middle::ty::layout::HasTyCtxt;
3-
use rustc_middle::ty::{self, Ty};
3+
use rustc_middle::ty::{self, Ty, ValTree};
44
use rustc_middle::{bug, mir, span_bug};
55
use rustc_target::abi::Abi;
66

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

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

62-
/// process constant containing SIMD shuffle indices
63-
pub fn simd_shuffle_indices(
62+
/// process constant containing SIMD shuffle indices & constant vectors
63+
pub fn immediate_const_vector(
6464
&mut self,
6565
bx: &Bx,
6666
constant: &mir::ConstOperand<'tcx>,
6767
) -> (Bx::Value, Ty<'tcx>) {
6868
let ty = self.monomorphize(constant.ty());
69+
let ty_is_simd = ty.is_simd();
70+
let field_ty = if ty_is_simd {
71+
ty.simd_size_and_type(bx.tcx()).1
72+
} else {
73+
ty.builtin_index().unwrap()
74+
};
75+
6976
let val = self
7077
.eval_unevaluated_mir_constant_to_valtree(constant)
7178
.ok()
7279
.map(|x| x.ok())
7380
.flatten()
7481
.map(|val| {
75-
let field_ty = ty.builtin_index().unwrap();
76-
let values: Vec<_> = val
77-
.unwrap_branch()
78-
.iter()
82+
let field_iter = val.unwrap_branch();
83+
let first = field_iter.get(0).unwrap();
84+
let field_iter = match first {
85+
ValTree::Branch(_) => first.unwrap_branch().iter(),
86+
ValTree::Leaf(_) => field_iter.iter(),
87+
};
88+
let values: Vec<_> = field_iter
7989
.map(|field| {
8090
if let Some(prim) = field.try_to_scalar() {
8191
let layout = bx.layout_of(field_ty);
@@ -84,11 +94,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
8494
};
8595
bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout))
8696
} else {
87-
bug!("simd shuffle field {:?}", field)
97+
bug!("field is not a scalar {:?}", field)
8898
}
8999
})
90100
.collect();
91-
bx.const_struct(&values, false)
101+
if ty_is_simd { bx.const_vector(&values) } else { bx.const_struct(&values, false) }
92102
})
93103
.unwrap_or_else(|| {
94104
bx.tcx().dcx().emit_err(errors::ShuffleIndicesEvaluation { span: constant.span });

compiler/rustc_codegen_ssa/src/traits/consts.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub trait ConstMethods<'tcx>: BackendTypes {
3030

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

3435
fn const_to_opt_uint(&self, v: Self::Value) -> Option<u64>;
3536
fn const_to_opt_u128(&self, v: Self::Value, sign_ext: bool) -> Option<u128>;

0 commit comments

Comments
 (0)