From: Yap Zhi Heng <[email protected]>

Similar to the previous commit, but for FORWARD_ARGUMENTS cases in 
CompileExternItem::visit
(ExternalFunctionItem). Compiled 006t.original output from compiling 
llvm_builtins.rs for only
the enabled FORWARD_ARGUMENT cases ():

```
u8 llvm_addcarryx_u32 (const u8 a, const u32 b, const u32 c, u8 * const 
{ref-all} d)
{
  return (u8) __builtin_ia32_addcarryx_u32 ((unsigned char) a, (u32) b, (u32) 
c, (u32 *) d);
}

u8 llvm_addcarryx_u64 (const u8 a, const u64 b, const u64 c, u8 * const 
{ref-all} d)
{
  return (u8) __builtin_ia32_addcarryx_u64 ((unsigned char) a, (unsigned long) 
b, (unsigned long) c, (unsigned long *) d);
}
```

vcvtph2ps and vcvtps2ph functions are not supported yet as gccrs doesn't 
support SIMD types yet.

gcc/rust/ChangeLog:

        * backend/rust-builtins.cc 
(BuiltinsContext::register_llvm_to_gcc_builtin): Add entries
        for vcvtph2ps & vcvtps2ph cases (currently unused due to the reason 
mentioned above).
        * backend/rust-compile-extern.h 
(CompileExternItem::visit(HIR::ExternalFunctionItem)):
        Remove placeholder function in the FORWARD_ARGUMENTS case under 
compilation of UNADJUSTED
        ABI.
        (CompileExternItem::compile_x86_forwarding_adapter): New function to 
adapt LLVM's addcarryx
        function signatures by simply forwarding the parameters and return var 
without changes.

gcc/testsuite/ChangeLog:

        * rust/compile/llvm_builtins.rs: Enable addcarryx cases, add TODO 
comment for vcvtph2ps &
        vcvtps2ph cases.

Signed-off-by: Yap Zhi Heng <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/502e99e435b6f5129a981a68a3debd95b03f7e1e

The commit has NOT been mentioned in any issue.

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4809

 gcc/rust/backend/rust-builtins.cc           | 12 ++-
 gcc/rust/backend/rust-compile-extern.h      | 88 +++++++++++++++++++--
 gcc/testsuite/rust/compile/llvm_builtins.rs | 10 ++-
 3 files changed, 100 insertions(+), 10 deletions(-)

diff --git a/gcc/rust/backend/rust-builtins.cc 
b/gcc/rust/backend/rust-builtins.cc
index 0d08cdf3d..12ae27e20 100644
--- a/gcc/rust/backend/rust-builtins.cc
+++ b/gcc/rust/backend/rust-builtins.cc
@@ -416,7 +416,17 @@ BuiltinsContext::register_llvm_to_gcc_builtin ()
      {"__builtin_ia32_addcarryx_u64", LlvmBuiltinAdapter::FORWARD_ARGUMENTS}},
     {"llvm.x86.subborrow.64",
      {"__builtin_ia32_sbb_u64",
-      LlvmBuiltinAdapter::OUTPUT_POINTER_STATUS_VALUE}}};
+      LlvmBuiltinAdapter::OUTPUT_POINTER_STATUS_VALUE}},
+
+    {"llvm.x86.vcvtph2ps.128",
+     {"__builtin_ia32_vcvtph2ps", LlvmBuiltinAdapter::FORWARD_ARGUMENTS}},
+    {"llvm.x86.vcvtph2ps.256",
+     {"__builtin_ia32_vcvtph2ps256", LlvmBuiltinAdapter::FORWARD_ARGUMENTS}},
+    {"llvm.x86.vcvtps2ph.128",
+     {"__builtin_ia32_vcvtps2ph", LlvmBuiltinAdapter::FORWARD_ARGUMENTS}},
+    {"llvm.x86.vcvtps2ph.256",
+     {"__builtin_ia32_vcvtps2ph256", LlvmBuiltinAdapter::FORWARD_ARGUMENTS}},
+  };
 }
 
 void
diff --git a/gcc/rust/backend/rust-compile-extern.h 
b/gcc/rust/backend/rust-compile-extern.h
index f9aecef5b..b2237b77c 100644
--- a/gcc/rust/backend/rust-compile-extern.h
+++ b/gcc/rust/backend/rust-compile-extern.h
@@ -171,10 +171,9 @@ public:
              function.get_locus ());
            break;
          case LlvmBuiltinAdapter::FORWARD_ARGUMENTS:
-           // TODO placeholder
-           adapter_tree = compile_x86_output_pointer_adapter (
-             ctx, fntype, resolved, OutputTupleOrder::STATUS_VALUE,
-             function.get_locus ());
+           adapter_tree
+             = compile_x86_forwarding_adapter (ctx, fntype, resolved,
+                                               function.get_locus ());
            break;
          }
 
@@ -262,7 +261,7 @@ private:
    * @param order whether the LLVM built-in returns (value, status) or (status,
    * value)
    * @param locus
-   * @return tree
+   * @return tree the resultant wrapper function
    */
   static tree compile_x86_output_pointer_adapter (Context *ctx,
                                                  TyTy::FnType *fntype,
@@ -393,6 +392,85 @@ private:
     return fndecl;
   }
 
+  /**
+   * Compiles a 1-to-1 wrapper for LLVM built-ins that wraps around GCC
+   * built-ins.
+   *
+   * @param ctx
+   * @param fntype the LLVM built-in function type
+   * @param gcc_builtin the GCC built-in function
+   * @param locus
+   * @return tree the resultant wrapper function
+   */
+  static tree compile_x86_forwarding_adapter (Context *ctx,
+                                             TyTy::FnType *fntype,
+                                             tree gcc_builtin,
+                                             location_t locus)
+  {
+    tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
+
+    const auto &path = fntype->get_ident ().path;
+    std::string ir_name = path.get () + fntype->subst_as_string ();
+    std::string asm_name = ctx->mangle_item (fntype, path);
+
+    // start building the wrapper function
+    tree fndecl
+      = Backend::function (compiled_fn_type, ir_name, asm_name, 0, locus);
+
+    TREE_PUBLIC (fndecl) = 0;
+    DECL_ARTIFICIAL (fndecl) = 1;
+    DECL_EXTERNAL (fndecl) = 0;
+    DECL_DECLARED_INLINE_P (fndecl) = 1;
+
+    // compile params for the rust wrapper
+    std::vector<Bvariable *> param_vars;
+    param_vars.reserve (fntype->get_params ().size ());
+    for (auto &param : fntype->get_params ())
+      {
+       auto &pattern = param.get_pattern ();
+       tree type = TyTyResolveCompile::compile (ctx, param.get_type ());
+       Bvariable *variable
+         = CompileFnParam::compile (ctx, fndecl, pattern, type,
+                                    pattern.get_locus ());
+       param_vars.emplace_back (variable);
+      }
+
+    if (!Backend::function_set_parameters (fndecl, param_vars))
+      return error_mark_node;
+
+    // forward the rust params, convert each into the corresponding gcc
+    // built-in param type
+    std::vector<tree> call_arguments;
+    call_arguments.reserve (param_vars.size ());
+    tree gcc_argument_types = TYPE_ARG_TYPES (TREE_TYPE (gcc_builtin));
+    for (Bvariable *param : param_vars)
+      {
+       tree argument = param->get_tree (locus);
+       tree expected_type = TREE_VALUE (gcc_argument_types);
+       argument = Backend::convert_expression (expected_type, argument, locus);
+       call_arguments.emplace_back (argument);
+       gcc_argument_types = TREE_CHAIN (gcc_argument_types);
+      }
+
+    tree builtin_call
+      = build_call_expr_loc_array (locus, gcc_builtin,
+                                  static_cast<int> (call_arguments.size ()),
+                                  call_arguments.data ());
+    tree wrapper_ret_type = TREE_TYPE (DECL_RESULT (fndecl));
+
+    builtin_call
+      = Backend::convert_expression (wrapper_ret_type, builtin_call, locus);
+    tree block = Backend::block (fndecl, NULL_TREE, {}, locus, locus);
+    ctx->push_block (block);
+    ctx->add_statement (
+      Backend::return_statement (fndecl, builtin_call, locus));
+    tree body = ctx->pop_block ();
+    DECL_SAVED_TREE (fndecl) = body;
+
+    ctx->push_function (fndecl);
+    return fndecl;
+  }
+
   TyTy::BaseType *concrete;
   tree reference;
   location_t ref_locus;
diff --git a/gcc/testsuite/rust/compile/llvm_builtins.rs 
b/gcc/testsuite/rust/compile/llvm_builtins.rs
index 6503c0be2..7f44eb02f 100644
--- a/gcc/testsuite/rust/compile/llvm_builtins.rs
+++ b/gcc/testsuite/rust/compile/llvm_builtins.rs
@@ -19,17 +19,19 @@ extern "unadjusted" {
 
     #[link_name = "llvm.x86.addcarry.32"]
     fn llvm_addcarry_u32(a: u8, b: u32, c: u32) -> (u8, u32);
-    // #[link_name = "llvm.x86.addcarryx.u32"]
-    // fn llvm_addcarryx_u32(a: u8, b: u32, c: u32, d: *mut u8) -> u8;
+    #[link_name = "llvm.x86.addcarryx.u32"]
+    fn llvm_addcarryx_u32(a: u8, b: u32, c: u32, d: *mut u8) -> u8;
     #[link_name = "llvm.x86.subborrow.32"]
     fn llvm_subborrow_u32(a: u8, b: u32, c: u32) -> (u8, u32);
     #[link_name = "llvm.x86.addcarry.64"]
     fn llvm_addcarry_u64(a: u8, b: u64, c: u64) -> (u8, u64);
-    // #[link_name = "llvm.x86.addcarryx.u64"]
-    // fn llvm_addcarryx_u64(a: u8, b: u64, c: u64, d: *mut u8) -> u8;
+    #[link_name = "llvm.x86.addcarryx.u64"]
+    fn llvm_addcarryx_u64(a: u8, b: u64, c: u64, d: *mut u8) -> u8;
     #[link_name = "llvm.x86.subborrow.64"]
     fn llvm_subborrow_u64(a: u8, b: u64, c: u64) -> (u8, u64);
 
+    // TODO implement the SIMD types (i16x8, f32x4, f32x8) before
+    // enabling these tests
     // #[link_name = "llvm.x86.vcvtph2ps.128"]
     // fn llvm_vcvtph2ps_128(a: i16x8) -> f32x4;
     // #[link_name = "llvm.x86.vcvtph2ps.256"]
-- 
2.55.0

Reply via email to