Skip to content

Commit 965fc68

Browse files
committed
Add bypass for i1xN
1 parent 9df071b commit 965fc68

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

@@ -1676,6 +1676,46 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
16761676
self.call(self.type_func(&[src_ty], dest_ty), None, None, f, &[val], None, None)
16771677
}
16781678

1679+
fn trunc_int_to_i1_vector(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
1680+
let vector_length = self.vector_length(dest_ty) as u64;
1681+
let int_width = cmp::max(vector_length.next_power_of_two(), 8);
1682+
1683+
let bitcasted = self.bitcast(val, self.type_vector(self.type_i1(), int_width));
1684+
if vector_length == int_width {
1685+
bitcasted
1686+
} else {
1687+
let shuffle_mask =
1688+
(0..vector_length).map(|i| self.const_i32(i as i32)).collect::<Vec<_>>();
1689+
self.shuffle_vector(bitcasted, bitcasted, self.const_vector(&shuffle_mask))
1690+
}
1691+
}
1692+
1693+
fn zext_i1_vector_to_int(
1694+
&mut self,
1695+
mut val: &'ll Value,
1696+
src_ty: &'ll Type,
1697+
dest_ty: &'ll Type,
1698+
) -> &'ll Value {
1699+
let vector_length = self.vector_length(src_ty) as u64;
1700+
let int_width = cmp::max(vector_length.next_power_of_two(), 8);
1701+
1702+
if vector_length != int_width {
1703+
let shuffle_indices = match vector_length {
1704+
0 => unreachable!("zero length vectors are not allowed"),
1705+
1 => vec![0, 1, 1, 1, 1, 1, 1, 1],
1706+
2 => vec![0, 1, 2, 3, 2, 3, 2, 3],
1707+
3 => vec![0, 1, 2, 3, 4, 5, 3, 4],
1708+
4.. => (0..int_width as i32).collect(),
1709+
};
1710+
let shuffle_mask =
1711+
shuffle_indices.into_iter().map(|i| self.const_i32(i)).collect::<Vec<_>>();
1712+
val =
1713+
self.shuffle_vector(val, self.const_null(src_ty), self.const_vector(&shuffle_mask));
1714+
}
1715+
1716+
self.bitcast(val, dest_ty)
1717+
}
1718+
16791719
fn autocast(
16801720
&mut self,
16811721
llfn: &'ll Value,
@@ -1691,6 +1731,13 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
16911731
}
16921732

16931733
match self.type_kind(llvm_ty) {
1734+
TypeKind::Vector if self.element_type(llvm_ty) == self.type_i1() => {
1735+
if is_argument {
1736+
self.trunc_int_to_i1_vector(val, dest_ty)
1737+
} else {
1738+
self.zext_i1_vector_to_int(val, src_ty, dest_ty)
1739+
}
1740+
}
16941741
TypeKind::Struct => {
16951742
let mut ret = self.const_poison(dest_ty);
16961743
for (idx, (src_element_ty, dest_element_ty)) in

0 commit comments

Comments
 (0)