Skip to content

Commit cb5e319

Browse files
committed
Add bypass for i1xN
1 parent c7f8d77 commit cb5e319

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

compiler/rustc_codegen_llvm/src/abi.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,9 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
368368

369369
if llvm_element_ty == self.type_bf16() {
370370
rust_ty == self.type_vector(self.type_i16(), llvm_element_count)
371+
} else if llvm_element_ty == self.type_i1() {
372+
let int_width = cmp::max(llvm_element_count.next_power_of_two(), 8);
373+
rust_ty == self.type_ix(int_width)
371374
} else {
372375
false
373376
}

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::borrow::{Borrow, Cow};
22
use std::ops::Deref;
3-
use std::{iter, ptr};
3+
use std::{cmp, iter, ptr};
44

55
pub(crate) mod autodiff;
66

@@ -1596,6 +1596,46 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
15961596
}
15971597
}
15981598
impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1599+
fn trunc_int_to_i1_vector(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
1600+
let vector_length = self.vector_length(dest_ty) as u64;
1601+
let int_width = cmp::max(vector_length.next_power_of_two(), 8);
1602+
1603+
let bitcasted = self.bitcast(val, self.type_vector(self.type_i1(), int_width));
1604+
if vector_length == int_width {
1605+
bitcasted
1606+
} else {
1607+
let shuffle_mask =
1608+
(0..vector_length).map(|i| self.const_i32(i as i32)).collect::<Vec<_>>();
1609+
self.shuffle_vector(bitcasted, bitcasted, self.const_vector(&shuffle_mask))
1610+
}
1611+
}
1612+
1613+
fn zext_i1_vector_to_int(
1614+
&mut self,
1615+
mut val: &'ll Value,
1616+
src_ty: &'ll Type,
1617+
dest_ty: &'ll Type,
1618+
) -> &'ll Value {
1619+
let vector_length = self.vector_length(src_ty) as u64;
1620+
let int_width = cmp::max(vector_length.next_power_of_two(), 8);
1621+
1622+
if vector_length != int_width {
1623+
let shuffle_indices = match vector_length {
1624+
0 => unreachable!("zero length vectors are not allowed"),
1625+
1 => vec![0, 1, 1, 1, 1, 1, 1, 1],
1626+
2 => vec![0, 1, 2, 3, 2, 3, 2, 3],
1627+
3 => vec![0, 1, 2, 3, 4, 5, 3, 4],
1628+
4.. => (0..int_width as i32).collect(),
1629+
};
1630+
let shuffle_mask =
1631+
shuffle_indices.into_iter().map(|i| self.const_i32(i)).collect::<Vec<_>>();
1632+
val =
1633+
self.shuffle_vector(val, self.const_null(src_ty), self.const_vector(&shuffle_mask));
1634+
}
1635+
1636+
self.bitcast(val, dest_ty)
1637+
}
1638+
15991639
fn autocast(
16001640
&mut self,
16011641
llfn: &'ll Value,
@@ -1611,6 +1651,13 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
16111651
}
16121652

16131653
match self.type_kind(llvm_ty) {
1654+
TypeKind::Vector if self.element_type(llvm_ty) == self.type_i1() => {
1655+
if is_argument {
1656+
self.trunc_int_to_i1_vector(val, dest_ty)
1657+
} else {
1658+
self.zext_i1_vector_to_int(val, src_ty, dest_ty)
1659+
}
1660+
}
16141661
TypeKind::Struct => {
16151662
let mut ret = self.const_poison(dest_ty);
16161663
for (idx, (src_element_ty, dest_element_ty)) in

0 commit comments

Comments
 (0)