Skip to content

Commit cc9a4cf

Browse files
committed
change implementation of rust intrinsics to use the new api
1 parent 2bdff9e commit cc9a4cf

File tree

8 files changed

+587
-1121
lines changed

8 files changed

+587
-1121
lines changed

compiler/rustc_codegen_gcc/src/builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -897,7 +897,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
897897
fn checked_binop(
898898
&mut self,
899899
oop: OverflowOp,
900-
typ: Ty<'_>,
900+
typ: Ty<'tcx>,
901901
lhs: Self::Value,
902902
rhs: Self::Value,
903903
) -> (Self::Value, Self::Value) {

compiler/rustc_codegen_llvm/src/abi.rs

Lines changed: 86 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,54 @@ pub(crate) trait FnAbiLlvmExt<'ll, 'tcx> {
328328
fn apply_attrs_callsite(&self, bx: &mut Builder<'_, 'll, 'tcx>, callsite: &'ll Value);
329329
}
330330

331+
fn equate_ty<'ll>(cx: &CodegenCx<'ll, '_>, rust_ty: &'ll Type, llvm_ty: &'ll Type) -> bool {
332+
if rust_ty == llvm_ty {
333+
return true;
334+
}
335+
match cx.type_kind(llvm_ty) {
336+
TypeKind::X86_AMX => {
337+
// we will insert casts from/to x86amx in callsite, so this is fine
338+
if cx.type_kind(rust_ty) == TypeKind::Vector {
339+
let element_count = cx.vector_length(rust_ty);
340+
let element_ty = cx.element_type(rust_ty);
341+
let element_size_bits = match cx.type_kind(element_ty) {
342+
TypeKind::Half => 16,
343+
TypeKind::Float => 32,
344+
TypeKind::Double => 64,
345+
TypeKind::FP128 => 128,
346+
TypeKind::Integer => cx.int_width(element_ty),
347+
TypeKind::Pointer => cx.int_width(cx.isize_ty),
348+
_ => bug!(
349+
"Vector element type `{element_ty:?}` not one of integer, float or pointer"
350+
),
351+
};
352+
element_size_bits * element_count as u64 == 8192
353+
} else {
354+
false
355+
}
356+
}
357+
TypeKind::BFloat => rust_ty == cx.type_i16(),
358+
TypeKind::Vector => {
359+
let element_count = cx.vector_length(llvm_ty);
360+
let element_ty = cx.element_type(llvm_ty);
361+
362+
if element_ty == cx.type_bf16() {
363+
rust_ty == cx.type_vector(cx.type_i16(), element_count as u64)
364+
} else {
365+
false
366+
}
367+
}
368+
_ => false,
369+
}
370+
}
371+
372+
macro_rules! error_exit {
373+
($($t:tt)*) => {
374+
eprintln!($($t)*);
375+
::std::process::exit(101)
376+
};
377+
}
378+
331379
impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
332380
fn llvm_return_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type {
333381
match &self.ret.mode {
@@ -405,78 +453,58 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
405453
let actual_return_ty = self.llvm_return_type(cx);
406454
let actual_argument_tys = self.llvm_argument_types(cx);
407455

408-
if name.starts_with(b"llvm.")
409-
&& let Some((intrinsic, type_params)) = cx.parse_intrinsic_name(name)
410-
{
411-
let fn_ty = cx.intrinsic_type(intrinsic, &type_params);
456+
let is_llvm_intrinsic = name.starts_with(b"llvm.");
412457

458+
if is_llvm_intrinsic && let Some((fn_ty, _)) = cx.get_intrinsic_from_name(name) {
413459
let expected_return_ty = cx.get_return_type(fn_ty);
414460
let expected_argument_tys = cx.func_params_types(fn_ty);
415461

416-
let equate_ty = |rust_ty, llvm_ty| {
417-
if rust_ty == llvm_ty {
418-
return true;
419-
}
420-
match cx.type_kind(llvm_ty) {
421-
TypeKind::X86_AMX => {
422-
// we will insert casts from/to x86amx in callsite, so this is fine
423-
if cx.type_kind(rust_ty) == TypeKind::Vector {
424-
let element_count = cx.vector_length(rust_ty);
425-
let element_ty = cx.element_type(rust_ty);
426-
let element_size_bits = match cx.type_kind(element_ty) {
427-
TypeKind::Half => 16,
428-
TypeKind::Float => 32,
429-
TypeKind::Double => 64,
430-
TypeKind::FP128 => 128,
431-
TypeKind::Integer => cx.int_width(element_ty),
432-
TypeKind::Pointer => cx.int_width(cx.isize_ty),
433-
_ => bug!(
434-
"Vector element type `{element_ty:?}` not one of integer, float or pointer"
435-
),
436-
};
437-
element_size_bits * element_count as u64 == 8192
438-
} else {
439-
false
440-
}
441-
}
442-
TypeKind::BFloat => rust_ty == cx.type_i16(),
443-
TypeKind::Vector => {
444-
let element_count = cx.vector_length(llvm_ty);
445-
let element_ty = cx.element_type(llvm_ty);
446-
447-
if element_ty == cx.type_bf16() {
448-
rust_ty == cx.type_vector(cx.type_i16(), element_count as u64)
449-
} else {
450-
false
451-
}
452-
}
453-
_ => false,
454-
}
455-
};
456-
457462
if actual_argument_tys.len() != expected_argument_tys.len() {
458-
todo!("A very friendly error msg")
463+
error_exit!(
464+
"Intrinsic signature mismatch: expected {} arguments for `{}`, found {} arguments",
465+
expected_argument_tys.len(),
466+
str::from_utf8(name).unwrap(),
467+
actual_argument_tys.len(),
468+
);
459469
}
460470

461-
if !equate_ty(actual_return_ty, expected_return_ty) {
462-
todo!("A very friendly error msg")
471+
if !equate_ty(cx, actual_return_ty, expected_return_ty) {
472+
error_exit!(
473+
"Intrinsic signature mismatch: expected {expected_return_ty:?} as return type for `{}`, found {actual_return_ty:?}",
474+
str::from_utf8(name).unwrap()
475+
);
463476
}
464-
for (actual_argument_ty, expected_argument_ty) in
465-
zip(actual_argument_tys, expected_argument_tys)
477+
for (idx, (actual_argument_ty, expected_argument_ty)) in
478+
zip(actual_argument_tys, expected_argument_tys).enumerate()
466479
{
467-
if !equate_ty(actual_argument_ty, expected_argument_ty) {
468-
todo!("A very friendly error msg")
480+
if !equate_ty(cx, actual_argument_ty, expected_argument_ty) {
481+
error_exit!(
482+
"Intrinsic signature mismatch: expected {expected_argument_ty:?} as argument {idx} for `{}`, found {actual_argument_ty:?}",
483+
str::from_utf8(name).unwrap()
484+
);
469485
}
470486
}
471487

472-
fn_ty
488+
// todo: check validity of the intrinsic via `getIntrinsicSignature`
489+
return fn_ty;
490+
}
491+
492+
let llfn = if self.c_variadic {
493+
cx.type_variadic_func(&actual_argument_tys, actual_return_ty)
473494
} else {
474-
if self.c_variadic {
475-
cx.type_variadic_func(&actual_argument_tys, actual_return_ty)
476-
} else {
477-
cx.type_func(&actual_argument_tys, actual_return_ty)
478-
}
495+
cx.type_func(&actual_argument_tys, actual_return_ty)
496+
};
497+
498+
if is_llvm_intrinsic {
499+
// either the intrinsic is invalid or it needs to be upgraded
500+
tracing::error!(
501+
"Using invalid or upgradeable intrinsic `{}`",
502+
str::from_utf8(name).unwrap()
503+
);
504+
// todo: check if it's upgradeable, otherwise error
479505
}
506+
507+
llfn
480508
}
481509

482510
fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type {

0 commit comments

Comments
 (0)