Skip to content

Commit 6bf4273

Browse files
committed
Implement simd_masked_load for cranelift
1 parent a4f0f09 commit 6bf4273

File tree

1 file changed

+51
-0
lines changed
  • compiler/rustc_codegen_cranelift/src/intrinsics

1 file changed

+51
-0
lines changed

compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Codegen `extern "platform-intrinsic"` intrinsics.
22
3+
use cranelift_codegen::ir::immediates::Offset32;
34
use rustc_middle::ty::GenericArgsRef;
45
use rustc_span::Symbol;
56
use rustc_target::abi::Endian;
@@ -1008,6 +1009,56 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
10081009
}
10091010
}
10101011

1012+
sym::simd_masked_load => {
1013+
intrinsic_args!(fx, args => (val, ptr, mask); intrinsic);
1014+
1015+
let (val_lane_count, val_lane_ty) = val.layout().ty.simd_size_and_type(fx.tcx);
1016+
// let (ptr, ptr_value) = ptr.try_to_ptr().expect("simd_masked_load ptr");
1017+
let (mask_lane_count, _mask_lane_ty) = mask.layout().ty.simd_size_and_type(fx.tcx);
1018+
let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
1019+
assert_eq!(val_lane_count, mask_lane_count);
1020+
assert_eq!(val_lane_count, ret_lane_count);
1021+
1022+
let lane_clif_ty = fx.clif_type(val_lane_ty).unwrap();
1023+
let ret_lane_layout = fx.layout_of(ret_lane_ty);
1024+
let ptr_val = ptr.load_scalar(fx);
1025+
1026+
for lane_idx in 0..ret_lane_count {
1027+
let val_lane = val.value_lane(fx, lane_idx).load_scalar(fx);
1028+
let mask_lane = mask.value_lane(fx, lane_idx).load_scalar(fx);
1029+
1030+
let if_enabled = fx.bcx.create_block();
1031+
let if_disabled = fx.bcx.create_block();
1032+
let next = fx.bcx.create_block();
1033+
let res_lane = fx.bcx.append_block_param(next, lane_clif_ty);
1034+
1035+
fx.bcx.ins().brif(mask_lane, if_enabled, &[], if_disabled, &[]);
1036+
fx.bcx.seal_block(if_enabled);
1037+
fx.bcx.seal_block(if_disabled);
1038+
1039+
fx.bcx.switch_to_block(if_enabled);
1040+
let offset = lane_idx as i32 * lane_clif_ty.bytes() as i32;
1041+
let res = fx.bcx.ins().load(
1042+
lane_clif_ty,
1043+
MemFlags::trusted(),
1044+
ptr_val,
1045+
Offset32::new(offset),
1046+
);
1047+
fx.bcx.ins().jump(next, &[res]);
1048+
1049+
fx.bcx.switch_to_block(if_disabled);
1050+
fx.bcx.ins().jump(next, &[val_lane]);
1051+
1052+
fx.bcx.seal_block(next);
1053+
fx.bcx.switch_to_block(next);
1054+
1055+
fx.bcx.ins().nop();
1056+
1057+
ret.place_lane(fx, lane_idx)
1058+
.write_cvalue(fx, CValue::by_val(res_lane, ret_lane_layout));
1059+
}
1060+
}
1061+
10111062
sym::simd_scatter => {
10121063
intrinsic_args!(fx, args => (val, ptr, mask); intrinsic);
10131064

0 commit comments

Comments
 (0)