Skip to content

Commit 44e3ea3

Browse files
authored
Merge pull request rust-lang#229 from rust-lang/fix/fmaddsub
Fix/fmaddsub
2 parents 235414e + 74dac5d commit 44e3ea3

File tree

4 files changed

+31
-7
lines changed

4 files changed

+31
-7
lines changed

src/base.rs

+3
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ pub fn compile_codegen_unit<'tcx>(tcx: TyCtxt<'tcx>, cgu_name: Symbol, supports_
126126
context.add_command_line_option("-fdata-sections");
127127
}
128128

129+
if env::var("CG_GCCJIT_DUMP_RTL").as_deref() == Ok("1") {
130+
context.add_command_line_option("-fdump-rtl-vregs");
131+
}
129132
if env::var("CG_GCCJIT_DUMP_TREE_ALL").as_deref() == Ok("1") {
130133
context.add_command_line_option("-fdump-tree-all");
131134
}

src/builder.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
280280
let func_name = format!("{:?}", func_ptr);
281281
let previous_arg_count = args.len();
282282
let orig_args = args;
283-
let args = llvm::adjust_intrinsic_arguments(&self, gcc_func, args.into(), &func_name);
283+
let args = {
284+
let function_address_names = self.function_address_names.borrow();
285+
let original_function_name = function_address_names.get(&func_ptr);
286+
llvm::adjust_intrinsic_arguments(&self, gcc_func, args.into(), &func_name, original_function_name)
287+
};
284288
let args_adjusted = args.len() != previous_arg_count;
285289
let args = self.check_ptr_call("call", func_ptr, &*args);
286290

src/context.rs

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub struct CodegenCx<'gcc, 'tcx> {
3333
// TODO(bjorn3): Can this field be removed?
3434
pub current_func: RefCell<Option<Function<'gcc>>>,
3535
pub normal_function_addresses: RefCell<FxHashSet<RValue<'gcc>>>,
36+
pub function_address_names: RefCell<FxHashMap<RValue<'gcc>, String>>,
3637

3738
pub functions: RefCell<FxHashMap<String, Function<'gcc>>>,
3839
pub intrinsics: RefCell<FxHashMap<String, Function<'gcc>>>,
@@ -192,6 +193,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
192193
context,
193194
current_func: RefCell::new(None),
194195
normal_function_addresses: Default::default(),
196+
function_address_names: Default::default(),
195197
functions: RefCell::new(functions),
196198
intrinsics: RefCell::new(FxHashMap::default()),
197199

@@ -345,6 +347,7 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
345347
// FIXME(antoyo): the rustc API seems to call get_fn_addr() when not needed (e.g. for FFI).
346348

347349
self.normal_function_addresses.borrow_mut().insert(ptr);
350+
self.function_address_names.borrow_mut().insert(ptr, func_name.to_string());
348351

349352
ptr
350353
}

src/intrinsic/llvm.rs

+20-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_codegen_ssa::traits::BuilderMethods;
55

66
use crate::{context::CodegenCx, builder::Builder};
77

8-
pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc, 'tcx>, gcc_func: FunctionPtrType<'gcc>, mut args: Cow<'b, [RValue<'gcc>]>, func_name: &str) -> Cow<'b, [RValue<'gcc>]> {
8+
pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc, 'tcx>, gcc_func: FunctionPtrType<'gcc>, mut args: Cow<'b, [RValue<'gcc>]>, func_name: &str, original_function_name: Option<&String>) -> Cow<'b, [RValue<'gcc>]> {
99
// Some LLVM intrinsics do not map 1-to-1 to GCC intrinsics, so we add the missing
1010
// arguments here.
1111
if gcc_func.get_param_count() != args.len() {
@@ -277,11 +277,23 @@ pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(builder: &Builder<'a, 'gcc
277277
let c = builder.context.new_rvalue_from_vector(None, arg3_type, &[new_args[2]; 2]);
278278
args = vec![a, b, c, new_args[3]].into();
279279
},
280-
"__builtin_ia32_vfmaddsubpd256" | "__builtin_ia32_vfmaddsubps" | "__builtin_ia32_vfmaddsubps256" => {
281-
let mut new_args = args.to_vec();
282-
let arg3 = &mut new_args[2];
283-
*arg3 = builder.context.new_unary_op(None, UnaryOp::Minus, arg3.get_type(), *arg3);
284-
args = new_args.into();
280+
"__builtin_ia32_vfmaddsubpd256" | "__builtin_ia32_vfmaddsubps" | "__builtin_ia32_vfmaddsubps256"
281+
| "__builtin_ia32_vfmaddsubpd" => {
282+
if let Some(original_function_name) = original_function_name {
283+
match &**original_function_name {
284+
"llvm.x86.fma.vfmsubadd.pd.256" | "llvm.x86.fma.vfmsubadd.ps" | "llvm.x86.fma.vfmsubadd.ps.256"
285+
| "llvm.x86.fma.vfmsubadd.pd" => {
286+
// NOTE: since both llvm.x86.fma.vfmsubadd.ps and llvm.x86.fma.vfmaddsub.ps maps to
287+
// __builtin_ia32_vfmaddsubps, only add minus if this comes from a
288+
// subadd LLVM intrinsic, e.g. _mm256_fmsubadd_pd.
289+
let mut new_args = args.to_vec();
290+
let arg3 = &mut new_args[2];
291+
*arg3 = builder.context.new_unary_op(None, UnaryOp::Minus, arg3.get_type(), *arg3);
292+
args = new_args.into();
293+
},
294+
_ => (),
295+
}
296+
}
285297
},
286298
"__builtin_ia32_ldmxcsr" => {
287299
// The builtin __builtin_ia32_ldmxcsr takes an integer value while llvm.x86.sse.ldmxcsr takes a pointer,
@@ -583,6 +595,8 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function
583595
"llvm.fshr.v32i16" => "__builtin_ia32_vpshrdv_v32hi",
584596
"llvm.fshr.v16i16" => "__builtin_ia32_vpshrdv_v16hi",
585597
"llvm.fshr.v8i16" => "__builtin_ia32_vpshrdv_v8hi",
598+
"llvm.x86.fma.vfmadd.sd" => "__builtin_ia32_vfmaddsd3",
599+
"llvm.x86.fma.vfmadd.ss" => "__builtin_ia32_vfmaddss3",
586600

587601
// The above doc points to unknown builtins for the following, so override them:
588602
"llvm.x86.avx2.gather.d.d" => "__builtin_ia32_gathersiv4si",

0 commit comments

Comments
 (0)