Skip to content

Commit 97a633f

Browse files
committed
Auto merge of #141760 - bjorn3:intrinsic_rework_part2, r=<try>
Improve intrinsic handling in cg_ssa (part 2) * Avoid computing function type and signature for intrinsics where possible * Nicer handling of bool returning intrinsics Follow up to #141404
2 parents e0d014a + 284bec5 commit 97a633f

File tree

4 files changed

+127
-163
lines changed

4 files changed

+127
-163
lines changed

compiler/rustc_codegen_gcc/src/intrinsic/mod.rs

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc_codegen_ssa::traits::{
2323
use rustc_middle::bug;
2424
#[cfg(feature = "master")]
2525
use rustc_middle::ty::layout::FnAbiOf;
26-
use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf};
26+
use rustc_middle::ty::layout::LayoutOf;
2727
use rustc_middle::ty::{self, Instance, Ty};
2828
use rustc_span::{Span, Symbol, sym};
2929
use rustc_target::callconv::{ArgAbi, PassMode};
@@ -205,21 +205,10 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
205205
span: Span,
206206
) -> Result<(), Instance<'tcx>> {
207207
let tcx = self.tcx;
208-
let callee_ty = instance.ty(tcx, self.typing_env());
209208

210-
let (def_id, fn_args) = match *callee_ty.kind() {
211-
ty::FnDef(def_id, fn_args) => (def_id, fn_args),
212-
_ => bug!("expected fn item type, found {}", callee_ty),
213-
};
214-
215-
let sig = callee_ty.fn_sig(tcx);
216-
let sig = tcx.normalize_erasing_late_bound_regions(self.typing_env(), sig);
217-
let arg_tys = sig.inputs();
218-
let ret_ty = sig.output();
219-
let name = tcx.item_name(def_id);
209+
let name = tcx.item_name(instance.def_id());
220210
let name_str = name.as_str();
221-
222-
let llret_ty = self.layout_of(ret_ty).gcc_type(self);
211+
let fn_args = instance.args;
223212

224213
let simple = get_simple_intrinsic(self, name);
225214
let simple_func = get_simple_function(self, name);
@@ -320,8 +309,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
320309
| sym::rotate_right
321310
| sym::saturating_add
322311
| sym::saturating_sub => {
323-
let ty = arg_tys[0];
324-
match int_type_width_signed(ty, self) {
312+
match int_type_width_signed(args[0].layout.ty, self) {
325313
Some((width, signed)) => match name {
326314
sym::ctlz | sym::cttz => {
327315
let func = self.current_func.borrow().expect("func");
@@ -400,7 +388,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
400388
tcx.dcx().emit_err(InvalidMonomorphization::BasicIntegerType {
401389
span,
402390
name,
403-
ty,
391+
ty: args[0].layout.ty,
404392
});
405393
return Ok(());
406394
}
@@ -492,7 +480,14 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
492480
}
493481

494482
_ if name_str.starts_with("simd_") => {
495-
match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) {
483+
match generic_simd_intrinsic(
484+
self,
485+
name,
486+
args,
487+
result.layout.ty,
488+
result.layout.gcc_type(self),
489+
span,
490+
) {
496491
Ok(value) => value,
497492
Err(()) => return Ok(()),
498493
}
@@ -503,13 +498,10 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
503498
};
504499

505500
if result.layout.ty.is_bool() {
506-
OperandRef::from_immediate_or_packed_pair(self, value, result.layout)
507-
.val
508-
.store(self, result);
501+
let val = self.from_immediate(value);
502+
self.store_to_place(val, result.val);
509503
} else if !result.layout.ty.is_unit() {
510-
let ptr_llty = self.type_ptr_to(result.layout.gcc_type(self));
511-
let ptr = self.pointercast(result.val.llval, ptr_llty);
512-
self.store(value, ptr, result.val.align);
504+
self.store_to_place(value, result.val);
513505
}
514506
Ok(())
515507
}

compiler/rustc_codegen_gcc/src/intrinsic/simd.rs

Lines changed: 41 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ use crate::context::CodegenCx;
2828
pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
2929
bx: &mut Builder<'a, 'gcc, 'tcx>,
3030
name: Symbol,
31-
callee_ty: Ty<'tcx>,
3231
args: &[OperandRef<'tcx, RValue<'gcc>>],
3332
ret_ty: Ty<'tcx>,
3433
llret_ty: Type<'gcc>,
@@ -54,24 +53,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
5453
};
5554
}
5655

57-
let tcx = bx.tcx();
58-
let sig = tcx.normalize_erasing_late_bound_regions(
59-
ty::TypingEnv::fully_monomorphized(),
60-
callee_ty.fn_sig(tcx),
61-
);
62-
let arg_tys = sig.inputs();
63-
6456
if name == sym::simd_select_bitmask {
6557
require_simd!(
66-
arg_tys[1],
67-
InvalidMonomorphization::SimdArgument { span, name, ty: arg_tys[1] }
58+
args[1].layout.ty,
59+
InvalidMonomorphization::SimdArgument { span, name, ty: args[1].layout.ty }
6860
);
69-
let (len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
61+
let (len, _) = args[1].layout.ty.simd_size_and_type(bx.tcx());
7062

7163
let expected_int_bits = (len.max(8) - 1).next_power_of_two();
7264
let expected_bytes = len / 8 + ((len % 8 > 0) as u64);
7365

74-
let mask_ty = arg_tys[0];
66+
let mask_ty = args[0].layout.ty;
7567
let mut mask = match *mask_ty.kind() {
7668
ty::Int(i) if i.bit_width() == Some(expected_int_bits) => args[0].immediate(),
7769
ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => args[0].immediate(),
@@ -121,8 +113,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
121113
}
122114

123115
// every intrinsic below takes a SIMD vector as its first argument
124-
require_simd!(arg_tys[0], InvalidMonomorphization::SimdInput { span, name, ty: arg_tys[0] });
125-
let in_ty = arg_tys[0];
116+
require_simd!(
117+
args[0].layout.ty,
118+
InvalidMonomorphization::SimdInput { span, name, ty: args[0].layout.ty }
119+
);
120+
let in_ty = args[0].layout.ty;
126121

127122
let comparison = match name {
128123
sym::simd_eq => Some(BinOp::Eq),
@@ -134,7 +129,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
134129
_ => None,
135130
};
136131

137-
let (in_len, in_elem) = arg_tys[0].simd_size_and_type(bx.tcx());
132+
let (in_len, in_elem) = args[0].layout.ty.simd_size_and_type(bx.tcx());
138133
if let Some(cmp_op) = comparison {
139134
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
140135

@@ -401,13 +396,13 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
401396
#[cfg(feature = "master")]
402397
if name == sym::simd_insert || name == sym::simd_insert_dyn {
403398
require!(
404-
in_elem == arg_tys[2],
399+
in_elem == args[2].layout.ty,
405400
InvalidMonomorphization::InsertedType {
406401
span,
407402
name,
408403
in_elem,
409404
in_ty,
410-
out_ty: arg_tys[2]
405+
out_ty: args[2].layout.ty
411406
}
412407
);
413408

@@ -439,10 +434,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
439434
let m_elem_ty = in_elem;
440435
let m_len = in_len;
441436
require_simd!(
442-
arg_tys[1],
443-
InvalidMonomorphization::SimdArgument { span, name, ty: arg_tys[1] }
437+
args[1].layout.ty,
438+
InvalidMonomorphization::SimdArgument { span, name, ty: args[1].layout.ty }
444439
);
445-
let (v_len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
440+
let (v_len, _) = args[1].layout.ty.simd_size_and_type(bx.tcx());
446441
require!(
447442
m_len == v_len,
448443
InvalidMonomorphization::MismatchedLengths { span, name, m_len, v_len }
@@ -911,26 +906,26 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
911906
// All types must be simd vector types
912907
require_simd!(in_ty, InvalidMonomorphization::SimdFirst { span, name, ty: in_ty });
913908
require_simd!(
914-
arg_tys[1],
915-
InvalidMonomorphization::SimdSecond { span, name, ty: arg_tys[1] }
909+
args[1].layout.ty,
910+
InvalidMonomorphization::SimdSecond { span, name, ty: args[1].layout.ty }
916911
);
917912
require_simd!(
918-
arg_tys[2],
919-
InvalidMonomorphization::SimdThird { span, name, ty: arg_tys[2] }
913+
args[2].layout.ty,
914+
InvalidMonomorphization::SimdThird { span, name, ty: args[2].layout.ty }
920915
);
921916
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
922917

923918
// Of the same length:
924-
let (out_len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
925-
let (out_len2, _) = arg_tys[2].simd_size_and_type(bx.tcx());
919+
let (out_len, _) = args[1].layout.ty.simd_size_and_type(bx.tcx());
920+
let (out_len2, _) = args[2].layout.ty.simd_size_and_type(bx.tcx());
926921
require!(
927922
in_len == out_len,
928923
InvalidMonomorphization::SecondArgumentLength {
929924
span,
930925
name,
931926
in_len,
932927
in_ty,
933-
arg_ty: arg_tys[1],
928+
arg_ty: args[1].layout.ty,
934929
out_len
935930
}
936931
);
@@ -941,7 +936,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
941936
name,
942937
in_len,
943938
in_ty,
944-
arg_ty: arg_tys[2],
939+
arg_ty: args[2].layout.ty,
945940
out_len: out_len2
946941
}
947942
);
@@ -970,8 +965,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
970965

971966
// The second argument must be a simd vector with an element type that's a pointer
972967
// to the element type of the first argument
973-
let (_, element_ty0) = arg_tys[0].simd_size_and_type(bx.tcx());
974-
let (_, element_ty1) = arg_tys[1].simd_size_and_type(bx.tcx());
968+
let (_, element_ty0) = args[0].layout.ty.simd_size_and_type(bx.tcx());
969+
let (_, element_ty1) = args[1].layout.ty.simd_size_and_type(bx.tcx());
975970
let (pointer_count, underlying_ty) = match *element_ty1.kind() {
976971
ty::RawPtr(p_ty, _) if p_ty == in_elem => {
977972
(ptr_count(element_ty1), non_ptr(element_ty1))
@@ -983,7 +978,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
983978
span,
984979
name,
985980
expected_element: element_ty1,
986-
second_arg: arg_tys[1],
981+
second_arg: args[1].layout.ty,
987982
in_elem,
988983
in_ty,
989984
mutability: ExpectedPointerMutability::Not,
@@ -998,7 +993,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
998993

999994
// The element type of the third argument must be an integer type of any width:
1000995
// TODO: also support unsigned integers.
1001-
let (_, element_ty2) = arg_tys[2].simd_size_and_type(bx.tcx());
996+
let (_, element_ty2) = args[2].layout.ty.simd_size_and_type(bx.tcx());
1002997
match *element_ty2.kind() {
1003998
ty::Int(_) => (),
1004999
_ => {
@@ -1030,25 +1025,25 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
10301025
// All types must be simd vector types
10311026
require_simd!(in_ty, InvalidMonomorphization::SimdFirst { span, name, ty: in_ty });
10321027
require_simd!(
1033-
arg_tys[1],
1034-
InvalidMonomorphization::SimdSecond { span, name, ty: arg_tys[1] }
1028+
args[1].layout.ty,
1029+
InvalidMonomorphization::SimdSecond { span, name, ty: args[1].layout.ty }
10351030
);
10361031
require_simd!(
1037-
arg_tys[2],
1038-
InvalidMonomorphization::SimdThird { span, name, ty: arg_tys[2] }
1032+
args[2].layout.ty,
1033+
InvalidMonomorphization::SimdThird { span, name, ty: args[2].layout.ty }
10391034
);
10401035

10411036
// Of the same length:
1042-
let (element_len1, _) = arg_tys[1].simd_size_and_type(bx.tcx());
1043-
let (element_len2, _) = arg_tys[2].simd_size_and_type(bx.tcx());
1037+
let (element_len1, _) = args[1].layout.ty.simd_size_and_type(bx.tcx());
1038+
let (element_len2, _) = args[2].layout.ty.simd_size_and_type(bx.tcx());
10441039
require!(
10451040
in_len == element_len1,
10461041
InvalidMonomorphization::SecondArgumentLength {
10471042
span,
10481043
name,
10491044
in_len,
10501045
in_ty,
1051-
arg_ty: arg_tys[1],
1046+
arg_ty: args[1].layout.ty,
10521047
out_len: element_len1
10531048
}
10541049
);
@@ -1059,7 +1054,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
10591054
name,
10601055
in_len,
10611056
in_ty,
1062-
arg_ty: arg_tys[2],
1057+
arg_ty: args[2].layout.ty,
10631058
out_len: element_len2
10641059
}
10651060
);
@@ -1082,9 +1077,9 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
10821077

10831078
// The second argument must be a simd vector with an element type that's a pointer
10841079
// to the element type of the first argument
1085-
let (_, element_ty0) = arg_tys[0].simd_size_and_type(bx.tcx());
1086-
let (_, element_ty1) = arg_tys[1].simd_size_and_type(bx.tcx());
1087-
let (_, element_ty2) = arg_tys[2].simd_size_and_type(bx.tcx());
1080+
let (_, element_ty0) = args[0].layout.ty.simd_size_and_type(bx.tcx());
1081+
let (_, element_ty1) = args[1].layout.ty.simd_size_and_type(bx.tcx());
1082+
let (_, element_ty2) = args[2].layout.ty.simd_size_and_type(bx.tcx());
10881083
let (pointer_count, underlying_ty) = match *element_ty1.kind() {
10891084
ty::RawPtr(p_ty, mutbl) if p_ty == in_elem && mutbl == hir::Mutability::Mut => {
10901085
(ptr_count(element_ty1), non_ptr(element_ty1))
@@ -1096,7 +1091,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
10961091
span,
10971092
name,
10981093
expected_element: element_ty1,
1099-
second_arg: arg_tys[1],
1094+
second_arg: args[1].layout.ty,
11001095
in_elem,
11011096
in_ty,
11021097
mutability: ExpectedPointerMutability::Mut,
@@ -1194,8 +1189,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
11941189
return_error!(InvalidMonomorphization::ExpectedVectorElementType {
11951190
span,
11961191
name,
1197-
expected_element: arg_tys[0].simd_size_and_type(bx.tcx()).1,
1198-
vector_type: arg_tys[0],
1192+
expected_element: args[0].layout.ty.simd_size_and_type(bx.tcx()).1,
1193+
vector_type: args[0].layout.ty,
11991194
});
12001195
}
12011196
};

0 commit comments

Comments
 (0)