Skip to content

Commit 1790258

Browse files
committed
Add LLVM backend support for funnel shifts
1 parent 2048e8c commit 1790258

File tree

3 files changed

+23
-8
lines changed

3 files changed

+23
-8
lines changed

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,9 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
383383
| sym::rotate_left
384384
| sym::rotate_right
385385
| sym::saturating_add
386-
| sym::saturating_sub => {
386+
| sym::saturating_sub
387+
| sym::unchecked_funnel_shl
388+
| sym::unchecked_funnel_shr => {
387389
let ty = args[0].layout.ty;
388390
if !ty.is_integral() {
389391
tcx.dcx().emit_err(InvalidMonomorphization::BasicIntegerType {
@@ -424,18 +426,26 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
424426
sym::bitreverse => {
425427
self.call_intrinsic("llvm.bitreverse", &[llty], &[args[0].immediate()])
426428
}
427-
sym::rotate_left | sym::rotate_right => {
428-
let is_left = name == sym::rotate_left;
429-
let val = args[0].immediate();
430-
let raw_shift = args[1].immediate();
431-
// rotate = funnel shift with first two args the same
429+
sym::rotate_left
430+
| sym::rotate_right
431+
| sym::unchecked_funnel_shl
432+
| sym::unchecked_funnel_shr => {
433+
let is_left = name == sym::rotate_left || name == sym::unchecked_funnel_shl;
434+
let lhs = args[0].immediate();
435+
let (rhs, raw_shift) =
436+
if name == sym::rotate_left || name == sym::rotate_right {
437+
// rotate = funnel shift with first two args the same
438+
(lhs, args[1].immediate())
439+
} else {
440+
(args[1].immediate(), args[2].immediate())
441+
};
432442
let llvm_name = format!("llvm.fsh{}", if is_left { 'l' } else { 'r' });
433443

434444
// llvm expects shift to be the same type as the values, but rust
435445
// always uses `u32`.
436-
let raw_shift = self.intcast(raw_shift, self.val_ty(val), false);
446+
let raw_shift = self.intcast(raw_shift, self.val_ty(lhs), false);
437447

438-
self.call_intrinsic(llvm_name, &[llty], &[val, val, raw_shift])
448+
self.call_intrinsic(llvm_name, &[llty], &[lhs, rhs, raw_shift])
439449
}
440450
sym::saturating_add | sym::saturating_sub => {
441451
let is_add = name == sym::saturating_add;

compiler/rustc_hir_analysis/src/check/intrinsic.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,9 @@ pub(crate) fn check_intrinsic_type(
449449
}
450450
sym::unchecked_shl | sym::unchecked_shr => (2, 0, vec![param(0), param(1)], param(0)),
451451
sym::rotate_left | sym::rotate_right => (1, 0, vec![param(0), tcx.types.u32], param(0)),
452+
sym::unchecked_funnel_shl | sym::unchecked_funnel_shr => {
453+
(1, 0, vec![param(0), param(0), tcx.types.u32], param(0))
454+
}
452455
sym::unchecked_add | sym::unchecked_sub | sym::unchecked_mul => {
453456
(1, 0, vec![param(0), param(0)], param(0))
454457
}

compiler/rustc_span/src/symbol.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2269,6 +2269,8 @@ symbols! {
22692269
unboxed_closures,
22702270
unchecked_add,
22712271
unchecked_div,
2272+
unchecked_funnel_shl,
2273+
unchecked_funnel_shr,
22722274
unchecked_mul,
22732275
unchecked_rem,
22742276
unchecked_shl,

0 commit comments

Comments
 (0)