about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAntoni Boucher <bouanto@zoho.com>2024-09-27 12:07:24 -0400
committerAntoni Boucher <bouanto@zoho.com>2024-09-27 12:07:34 -0400
commit11f4f160d3a10d2c4e6f49c173f0344f9b9f09ae (patch)
tree9d5eb23763948bed1ac50462c0ad939dd30814f4
parent1e8354a461486bb543741d9343ce170af554e7eb (diff)
downloadrust-11f4f160d3a10d2c4e6f49c173f0344f9b9f09ae.tar.gz
rust-11f4f160d3a10d2c4e6f49c173f0344f9b9f09ae.zip
Implement a hack for an intrinsic mapping where we need to output a different builtin based on an argument
-rw-r--r--src/builder.rs1
-rw-r--r--src/intrinsic/llvm.rs34
2 files changed, 33 insertions, 2 deletions
diff --git a/src/builder.rs b/src/builder.rs
index e001e59177d..9936bc1f5f2 100644
--- a/src/builder.rs
+++ b/src/builder.rs
@@ -370,6 +370,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
         let args = {
             let function_address_names = self.function_address_names.borrow();
             let original_function_name = function_address_names.get(&func_ptr);
+            func_ptr = llvm::adjust_function(self.context, &func_name, func_ptr, args);
             llvm::adjust_intrinsic_arguments(
                 self,
                 gcc_func,
diff --git a/src/intrinsic/llvm.rs b/src/intrinsic/llvm.rs
index 4aed955627d..b1fed82507d 100644
--- a/src/intrinsic/llvm.rs
+++ b/src/intrinsic/llvm.rs
@@ -1,12 +1,42 @@
 use std::borrow::Cow;
 
-use gccjit::CType;
+use gccjit::{CType, Context};
 use gccjit::{Function, FunctionPtrType, RValue, ToRValue, UnaryOp};
 use rustc_codegen_ssa::traits::BuilderMethods;
 
 use crate::builder::Builder;
 use crate::context::CodegenCx;
 
+pub fn adjust_function<'gcc>(
+    context: &'gcc Context<'gcc>,
+    func_name: &str,
+    func_ptr: RValue<'gcc>,
+    args: &[RValue<'gcc>],
+) -> RValue<'gcc> {
+    // FIXME: we should not need this hack: this is required because both _mm_fcmadd_sch
+    // and _mm_mask3_fcmadd_round_sch calls llvm.x86.avx512fp16.mask.vfcmadd.csh and we
+    // seem to need to map this one LLVM intrinsic to 2 different GCC builtins.
+    match func_name {
+        "__builtin_ia32_vfcmaddcsh_mask3_round" => {
+            if format!("{:?}", args[3]).ends_with("255") {
+                return context
+                    .get_target_builtin_function("__builtin_ia32_vfcmaddcsh_mask_round")
+                    .get_address(None);
+            }
+        }
+        "__builtin_ia32_vfmaddcsh_mask3_round" => {
+            if format!("{:?}", args[3]).ends_with("255") {
+                return context
+                    .get_target_builtin_function("__builtin_ia32_vfmaddcsh_mask_round")
+                    .get_address(None);
+            }
+        }
+        _ => (),
+    }
+
+    func_ptr
+}
+
 pub fn adjust_intrinsic_arguments<'a, 'b, 'gcc, 'tcx>(
     builder: &Builder<'a, 'gcc, 'tcx>,
     gcc_func: FunctionPtrType<'gcc>,
@@ -1198,7 +1228,7 @@ pub fn intrinsic<'gcc, 'tcx>(name: &str, cx: &CodegenCx<'gcc, 'tcx>) -> Function
         "llvm.x86.avx512fp16.mask.vfcmul.csh" => "__builtin_ia32_vfcmulcsh_mask_round",
         "llvm.x86.avx512fp16.mask.vfmadd.cph.512" => "__builtin_ia32_vfmaddcph512_mask3_round",
         "llvm.x86.avx512fp16.maskz.vfmadd.cph.512" => "__builtin_ia32_vfmaddcph512_maskz_round",
-        "llvm.x86.avx512fp16.mask.vfmadd.csh" => "__builtin_ia32_vfmaddcsh_mask_round",
+        "llvm.x86.avx512fp16.mask.vfmadd.csh" => "__builtin_ia32_vfmaddcsh_mask3_round",
         "llvm.x86.avx512fp16.maskz.vfmadd.csh" => "__builtin_ia32_vfmaddcsh_maskz_round",
         "llvm.x86.avx512fp16.mask.vfcmadd.cph.512" => "__builtin_ia32_vfcmaddcph512_mask3_round",
         "llvm.x86.avx512fp16.maskz.vfcmadd.cph.512" => "__builtin_ia32_vfcmaddcph512_maskz_round",