From 5ef20748a140d3384294a4218e6db7420cef692d Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Tue, 3 Jan 2023 15:04:41 -0500 Subject: [PATCH] libgccjit: Add missing builtins needed by optimizations gcc/jit/ChangeLog: * jit-builtins.cc (ensure_optimization_builtins_exist): Add popcount builtins. gcc/testsuite/ChangeLog: * jit.dg/all-non-failing-tests.h: New test. * jit.dg/test-popcount.c: New test. --- gcc/jit/jit-builtins.cc | 3 + gcc/testsuite/jit.dg/all-non-failing-tests.h | 10 +++ gcc/testsuite/jit.dg/test-popcount.c | 84 ++++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 gcc/testsuite/jit.dg/test-popcount.c diff --git a/gcc/jit/jit-builtins.cc b/gcc/jit/jit-builtins.cc index fdd0739789d..c84f2613f6a 100644 --- a/gcc/jit/jit-builtins.cc +++ b/gcc/jit/jit-builtins.cc @@ -609,6 +609,9 @@ builtins_manager::ensure_optimization_builtins_exist () We can't loop through all of the builtin_data array, we don't support all types yet. */ (void)get_builtin_function_by_id (BUILT_IN_TRAP); + (void)get_builtin_function_by_id (BUILT_IN_POPCOUNT); + (void)get_builtin_function_by_id (BUILT_IN_POPCOUNTL); + (void)get_builtin_function_by_id (BUILT_IN_POPCOUNTLL); } /* Playback support. */ diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h index e762563f9bd..b768c8977f0 100644 --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h @@ -268,6 +268,13 @@ #undef create_code #undef verify_code +/* test-popcount.c */ +#define create_code create_code_popcount +#define verify_code verify_code_popcount +#include "test-popcount.c" +#undef create_code +#undef verify_code + /* test-pr103562.c: We don't add this one, since it touches the optimization level of the context as a whole. */ @@ -488,6 +495,9 @@ const struct testcase testcases[] = { {"nested_loop", create_code_nested_loop, verify_code_nested_loop}, + {"popcount", + create_code_popcount, + verify_code_popcount}, {"pr66700_observing_write_through_ptr", create_code_pr66700_observing_write_through_ptr, verify_code_pr66700_observing_write_through_ptr}, diff --git a/gcc/testsuite/jit.dg/test-popcount.c b/gcc/testsuite/jit.dg/test-popcount.c new file mode 100644 index 00000000000..6ad241fd2de --- /dev/null +++ b/gcc/testsuite/jit.dg/test-popcount.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include + +#include "libgccjit.h" + +#include "harness.h" + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: +int +popcount (unsigned int x) +{ + int i = 0; + while (x) + { + x &= x - 1; + ++i; + } + return i; +} + */ + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *uint_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_INT); + + gcc_jit_param *param_x = + gcc_jit_context_new_param ( + ctxt, + NULL, + uint_type, "x"); + gcc_jit_param *params[1] = {param_x}; + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, + NULL, + GCC_JIT_FUNCTION_EXPORTED, + int_type, + "popcount", + 1, params, 0); + + gcc_jit_lvalue *x = gcc_jit_param_as_lvalue (param_x); + gcc_jit_rvalue *x_rvalue = gcc_jit_lvalue_as_rvalue (x); + gcc_jit_lvalue *i = + gcc_jit_function_new_local (func, NULL, int_type, "i"); + gcc_jit_rvalue *zero = gcc_jit_context_zero (ctxt, int_type); + + gcc_jit_block *initial = + gcc_jit_function_new_block (func, "initial"); + gcc_jit_block *while_block = + gcc_jit_function_new_block (func, "while"); + + gcc_jit_block_add_assignment (initial, NULL, i, zero); + gcc_jit_block_end_with_jump (initial, NULL, while_block); + + gcc_jit_block *after = + gcc_jit_function_new_block (func, "after"); + + gcc_jit_block *while_body = + gcc_jit_function_new_block (func, "while_body"); + gcc_jit_rvalue *uzero = gcc_jit_context_zero (ctxt, uint_type); + gcc_jit_rvalue *cmp = + gcc_jit_context_new_comparison (ctxt, NULL, GCC_JIT_COMPARISON_NE, x_rvalue, uzero); + gcc_jit_block_end_with_conditional (while_block, NULL, cmp, while_body, after); + + gcc_jit_rvalue *uone = gcc_jit_context_one (ctxt, uint_type); + gcc_jit_rvalue *sub = gcc_jit_context_new_binary_op (ctxt, NULL, GCC_JIT_BINARY_OP_MINUS, uint_type, x_rvalue, uone); + gcc_jit_block_add_assignment_op (while_body, NULL, x, GCC_JIT_BINARY_OP_BITWISE_AND, sub); + + gcc_jit_rvalue *one = gcc_jit_context_one (ctxt, int_type); + gcc_jit_block_add_assignment_op (while_body, NULL, i, GCC_JIT_BINARY_OP_PLUS, one); + gcc_jit_block_end_with_jump (while_body, NULL, while_block); + + gcc_jit_block_end_with_return(after, NULL, gcc_jit_lvalue_as_rvalue (i)); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + CHECK_NON_NULL (result); +} -- 2.43.0