Skip to content

Commit 8ead881

Browse files
authored
Merge pull request rust-lang#219 from sadlerap/float-intrinsics
simd: implement float math intrinsics
2 parents d9edc8e + 688f742 commit 8ead881

File tree

2 files changed

+42
-26
lines changed

2 files changed

+42
-26
lines changed

failing-ui-tests.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ src/test/ui/sepcomp/sepcomp-extern.rs
3030
src/test/ui/sepcomp/sepcomp-fns-backwards.rs
3131
src/test/ui/sepcomp/sepcomp-fns.rs
3232
src/test/ui/sepcomp/sepcomp-statics.rs
33-
src/test/ui/simd/intrinsic/float-math-pass.rs
3433
src/test/ui/simd/intrinsic/generic-arithmetic-pass.rs
3534
src/test/ui/simd/intrinsic/generic-as.rs
3635
src/test/ui/simd/intrinsic/generic-bitmask-pass.rs
@@ -40,7 +39,6 @@ src/test/ui/simd/issue-17170.rs
4039
src/test/ui/simd/issue-39720.rs
4140
src/test/ui/simd/issue-85915-simd-ptrs.rs
4241
src/test/ui/simd/issue-89193.rs
43-
src/test/ui/simd/libm_std_can_float.rs
4442
src/test/ui/simd/simd-bitmask.rs
4543
src/test/ui/simd/type-generic-monomorphisation-extern-nonnull-ptr.rs
4644
src/test/ui/sse2.rs

src/intrinsic/simd.rs

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use rustc_span::{Span, Symbol, sym};
1414
use rustc_target::abi::Align;
1515

1616
use crate::builder::Builder;
17-
use crate::intrinsic;
1817

1918
pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, name: Symbol, callee_ty: Ty<'tcx>, args: &[OperandRef<'tcx, RValue<'gcc>>], ret_ty: Ty<'tcx>, llret_ty: Type<'gcc>, span: Span) -> Result<RValue<'gcc>, ()> {
2019
// macros for error handling:
@@ -415,8 +414,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
415414
if let ty::Float(f) = in_elem.kind() {
416415
let elem_ty = bx.cx.type_float_from_ty(*f);
417416
match f.bit_width() {
418-
32 => ("f32", elem_ty),
419-
64 => ("f64", elem_ty),
417+
32 => ("f", elem_ty),
418+
64 => ("", elem_ty),
420419
_ => {
421420
return_error!(
422421
"unsupported element type `{}` of floating-point vector `{}`",
@@ -432,30 +431,49 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
432431

433432
let vec_ty = bx.cx.type_vector(elem_ty, in_len);
434433

435-
let (intr_name, fn_ty) =
434+
let intr_name =
436435
match name {
437-
sym::simd_ceil => ("ceil", bx.type_func(&[vec_ty], vec_ty)),
438-
sym::simd_fabs => ("fabs", bx.type_func(&[vec_ty], vec_ty)), // TODO(antoyo): pand with 170141183420855150465331762880109871103
439-
sym::simd_fcos => ("cos", bx.type_func(&[vec_ty], vec_ty)),
440-
sym::simd_fexp2 => ("exp2", bx.type_func(&[vec_ty], vec_ty)),
441-
sym::simd_fexp => ("exp", bx.type_func(&[vec_ty], vec_ty)),
442-
sym::simd_flog10 => ("log10", bx.type_func(&[vec_ty], vec_ty)),
443-
sym::simd_flog2 => ("log2", bx.type_func(&[vec_ty], vec_ty)),
444-
sym::simd_flog => ("log", bx.type_func(&[vec_ty], vec_ty)),
445-
sym::simd_floor => ("floor", bx.type_func(&[vec_ty], vec_ty)),
446-
sym::simd_fma => ("fma", bx.type_func(&[vec_ty, vec_ty, vec_ty], vec_ty)),
447-
sym::simd_fpowi => ("powi", bx.type_func(&[vec_ty, bx.type_i32()], vec_ty)),
448-
sym::simd_fpow => ("pow", bx.type_func(&[vec_ty, vec_ty], vec_ty)),
449-
sym::simd_fsin => ("sin", bx.type_func(&[vec_ty], vec_ty)),
450-
sym::simd_fsqrt => ("sqrt", bx.type_func(&[vec_ty], vec_ty)),
451-
sym::simd_round => ("round", bx.type_func(&[vec_ty], vec_ty)),
452-
sym::simd_trunc => ("trunc", bx.type_func(&[vec_ty], vec_ty)),
436+
sym::simd_ceil => "ceil",
437+
sym::simd_fabs => "fabs", // TODO(antoyo): pand with 170141183420855150465331762880109871103
438+
sym::simd_fcos => "cos",
439+
sym::simd_fexp2 => "exp2",
440+
sym::simd_fexp => "exp",
441+
sym::simd_flog10 => "log10",
442+
sym::simd_flog2 => "log2",
443+
sym::simd_flog => "log",
444+
sym::simd_floor => "floor",
445+
sym::simd_fma => "fma",
446+
sym::simd_fpowi => "__builtin_powi",
447+
sym::simd_fpow => "pow",
448+
sym::simd_fsin => "sin",
449+
sym::simd_fsqrt => "sqrt",
450+
sym::simd_round => "round",
451+
sym::simd_trunc => "trunc",
453452
_ => return_error!("unrecognized intrinsic `{}`", name),
454453
};
455-
let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str);
456-
let function = intrinsic::llvm::intrinsic(llvm_name, &bx.cx);
457-
let function: RValue<'gcc> = unsafe { std::mem::transmute(function) };
458-
let c = bx.call(fn_ty, function, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None);
454+
let builtin_name = format!("{}{}", intr_name, elem_ty_str);
455+
let funcs = bx.cx.functions.borrow();
456+
let function = funcs.get(&builtin_name).unwrap_or_else(|| panic!("unable to find builtin function {}", builtin_name));
457+
458+
// TODO(antoyo): add platform-specific behavior here for architectures that have these
459+
// intrinsics as instructions (for instance, gpus)
460+
let mut vector_elements = vec![];
461+
for i in 0..in_len {
462+
let index = bx.context.new_rvalue_from_long(bx.ulong_type, i as i64);
463+
// we have to treat fpowi specially, since fpowi's second argument is always an i32
464+
let arguments = if name == sym::simd_fpowi {
465+
vec![
466+
bx.extract_element(args[0].immediate(), index).to_rvalue(),
467+
args[1].immediate(),
468+
]
469+
} else {
470+
args.iter()
471+
.map(|arg| bx.extract_element(arg.immediate(), index).to_rvalue())
472+
.collect()
473+
};
474+
vector_elements.push(bx.context.new_call(None, *function, &arguments));
475+
}
476+
let c = bx.context.new_rvalue_from_vector(None, vec_ty, &vector_elements);
459477
Ok(c)
460478
}
461479

0 commit comments

Comments
 (0)