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 ¶m : 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