Skip to content

Commit 70586a2

Browse files
committed
fix simd_frem intrinsic implementation
The simd intrinsic handler was delegating implementation of `simd_frem` to `Builder::frem`, which wasn't able to handle vector-typed inputs. To fix this, teach this method how to handle vector inputs. Signed-off-by: Andy Sadler <[email protected]>
1 parent 6d13f94 commit 70586a2

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

src/builder.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -606,12 +606,29 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
606606
// ../../../gcc/gcc/cfgexpand.cc:6069
607607
// 0x7f0101bf9194 execute
608608
// ../../../gcc/gcc/cfgexpand.cc:6795
609-
if a.get_type().is_compatible_with(self.cx.float_type) {
609+
let a_type = a.get_type();
610+
let a_type_unqualified = a_type.unqualified();
611+
if a_type.is_compatible_with(self.cx.float_type) {
610612
let fmodf = self.context.get_builtin_function("fmodf");
611613
// FIXME(antoyo): this seems to produce the wrong result.
612614
return self.context.new_call(None, fmodf, &[a, b]);
613615
}
614-
assert_eq!(a.get_type().unqualified(), self.cx.double_type);
616+
else if let Some(vector_type) = a_type_unqualified.dyncast_vector() {
617+
assert_eq!(a_type_unqualified, b.get_type().unqualified());
618+
619+
let num_units = vector_type.get_num_units();
620+
let new_elements: Vec<_> = (0..num_units)
621+
.map(|i| {
622+
let index = self.context.new_rvalue_from_long(self.cx.type_u32(), i as _);
623+
let x = self.extract_element(a, index).to_rvalue();
624+
let y = self.extract_element(b, index).to_rvalue();
625+
self.frem(x, y)
626+
})
627+
.collect();
628+
629+
return self.context.new_rvalue_from_vector(None, a_type, &new_elements)
630+
}
631+
assert_eq!(a_type_unqualified, self.cx.double_type);
615632

616633
let fmod = self.context.get_builtin_function("fmod");
617634
return self.context.new_call(None, fmod, &[a, b]);

0 commit comments

Comments
 (0)