diff options
author | David Malcolm <dmalcolm@redhat.com> | 2015-06-30 20:39:50 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2015-06-30 20:39:50 +0000 |
commit | ec5d0088148d1d6218f5f503d1c8e67a529dfacd (patch) | |
tree | c7cf3f33890bd8579a8afa8a850a326bc0b1fd58 /gcc/testsuite | |
parent | 6a3603e356e14096e9554ceef57916fd03d9072b (diff) | |
download | gcc-ec5d0088148d1d6218f5f503d1c8e67a529dfacd.zip gcc-ec5d0088148d1d6218f5f503d1c8e67a529dfacd.tar.gz gcc-ec5d0088148d1d6218f5f503d1c8e67a529dfacd.tar.bz2 |
jit: add switch statements
gcc/ChangeLog:
* typed-splay-tree.h: New file.
gcc/jit/ChangeLog:
* docs/cp/topics/functions.rst (Blocks): Add switch statements to
list of ways to terminate a block.
(gccjit::block::end_with_switch): Add function description.
(gccjit::case_): Add class.
(gccjit::context::new_case): Add function description.
* docs/cp/topics/objects.rst: Add "case_" to class hierarchy.
* docs/topics/compatibility.rst (LIBGCCJIT_ABI_3): New.
* docs/topics/functions.rst (Blocks): Add switch statements to
list of ways to terminate a block.
(gcc_jit_block_end_with_switch): Add function description.
(gcc_jit_case): Add type.
(gcc_jit_context_new_case): Add function description.
(gcc_jit_case_as_object): Add function description.
* docs/topics/objects.rst: Add gcc_jit_case to class hierarchy.
* docs/_build/texinfo/libgccjit.texi: Regenerate.
* jit-common.h (gcc::jit::recording::case_): Add forward decl.
(gcc::jit::playback::case_): Add forward decl.
* jit-playback.c (add_case): New function.
(gcc::jit::playback::block::add_switch): New function.
* jit-playback.h (gcc::jit::playback::case_): New struct.
(gcc::jit::playback::block::get_function): New method.
(gcc::jit::playback::block::add_switch): New method.
* jit-recording.c: Within namespace gcc::jit...
(recording::context::new_case): New method.
(recording::function::validate): Update for change to
get_successor_blocks.
(recording::block::end_with_switch): New method.
(recording::block::get_successor_blocks): Update to support an
arbitrary number of successor blocks.
(recording::block::dump_edges_to_dot): Likewise.
(memento_of_new_rvalue_from_const <int>::get_wide_int): New.
(memento_of_new_rvalue_from_const <long>::get_wide_int): New.
(memento_of_new_rvalue_from_const <double>::get_wide_int): New.
(memento_of_new_rvalue_from_const <void *>::get_wide_int): New.
(recording::statement::get_successor_blocks): Update to support an
arbitrary number of successor blocks.
(recording::conditional::get_successor_blocks): Likewise.
(recording::jump::get_successor_blocks): Likewise.
(recording::return_::get_successor_blocks): Likewise.
(recording::case_::write_reproducer): New.
(recording::case_::make_debug_string): New.
(recording::switch_::switch_): New.
(recording::switch_::replay_into): New.
(recording::switch_::get_successor_blocks): New.
(recording::switch_::make_debug_string): New.
(recording::switch_::write_reproducer): New.
* jit-recording.h: Within namespace gcc::jit::recording...
(context::new_case): New.
(rvalue::is_constant): New.
(rvalue::get_wide_int): New.
(block::end_with_switch): New.
(block::get_successor_blocks): Update to support an arbitrary
number of successor blocks.
(memento_of_new_rvalue_from_const::is_constant): New.
(memento_of_new_rvalue_from_const::get_wide_int): New.
(statement::get_successor_blocks): Update to support an arbitrary
number of successor blocks.
(conditional::get_successor_blocks): Likewise.
(jump::get_successor_blocks): Likewise.
(return_::get_successor_blocks): Likewise.
(case_): New subclass of memento.
(switch_): New subclass of statement.
* libgccjit++.h (gccjit::case_): New subclass of gccjit::object.
(gccjit::context::new_case): New method.
(gccjit::block::end_with_switch): New method.
(gccjit::case_::case): New ctors.
(gccjit::case_::get_inner_case): New method.
* libgccjit.c: Include "typed-splay-tree.h"
(struct gcc_jit_case): New.
(gcc_jit_context_new_case): New function.
(gcc_jit_case_as_object): New function.
(valid_dest_for_switch): New function.
(valid_case_for_switch): New function.
(class api_call_validator): New class.
(class case_range_validator): New class.
(case_range_validator::case_range_validator): New.
(case_range_validator::validate): New.
(case_range_validator::case_compare): New.
(case_range_validator::get_wide_int): new.
(gcc_jit_block_end_with_switch): New.
* libgccjit.h: Add gcc_jit_case to class hierarchy comment.
(gcc_jit_case): New typedef.
(gcc_jit_context_new_case): New function.
(gcc_jit_case_as_object): New function.
(gcc_jit_block_end_with_switch): New function.
(LIBGCCJIT_HAVE_SWITCH_STATEMENTS): New.
* libgccjit.map: Add gcc_jit_block_end_with_switch,
gcc_jit_case_as_object and gcc_jit_context_new_case.
gcc/testsuite/ChangeLog:
* jit.dg/all-non-failing-tests.h: Add test-switch.c.
* jit.dg/test-error-gcc_jit_block_end_with_switch-NULL-case.c: New
testcase.
* jit.dg/test-error-gcc_jit_block_end_with_switch-mismatching-case-type.c:
New testcase.
* jit.dg/test-error-gcc_jit_block_end_with_switch-overlapping-ranges.c:
New testcase.
* jit.dg/test-error-gcc_jit_context_new_case-non-const-label.c:
New testcase.
* jit.dg/test-error-gcc_jit_context_new_case-non-integer-type.c:
New testcase.
* jit.dg/test-error-gcc_jit_context_new_case-reversed-endpoints.c:
New testcase.
* jit.dg/test-switch.c: New testcase.
* jit.dg/test-switch.cc: New testcase.
From-SVN: r225207
Diffstat (limited to 'gcc/testsuite')
10 files changed, 778 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3b4879d..80be58e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,23 @@ 2015-06-30 David Malcolm <dmalcolm@redhat.com> + * jit.dg/all-non-failing-tests.h: Add test-switch.c. + * jit.dg/test-error-gcc_jit_block_end_with_switch-NULL-case.c: New + testcase. + * jit.dg/test-error-gcc_jit_block_end_with_switch-mismatching-case-type.c: + New testcase. + * jit.dg/test-error-gcc_jit_block_end_with_switch-overlapping-ranges.c: + New testcase. + * jit.dg/test-error-gcc_jit_context_new_case-non-const-label.c: + New testcase. + * jit.dg/test-error-gcc_jit_context_new_case-non-integer-type.c: + New testcase. + * jit.dg/test-error-gcc_jit_context_new_case-reversed-endpoints.c: + New testcase. + * jit.dg/test-switch.c: New testcase. + * jit.dg/test-switch.cc: New testcase. + +2015-06-30 David Malcolm <dmalcolm@redhat.com> + PR jit/66546 * jit.dg/all-non-failing-tests.h: Add note about test-validly-unreachable-block.c. diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h index 67a16de..36a6160 100644 --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h @@ -175,6 +175,13 @@ #undef create_code #undef verify_code +/* test-switch.c */ +#define create_code create_code_switch +#define verify_code verify_code_switch +#include "test-switch.c" +#undef create_code +#undef verify_code + /* test-types.c */ #define create_code create_code_types #define verify_code verify_code_types @@ -281,6 +288,9 @@ const struct testcase testcases[] = { {"sum_of_squares", create_code_sum_of_squares, verify_code_sum_of_squares}, + {"switch", + create_code_switch, + verify_code_switch}, {"types", create_code_types, verify_code_types}, diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-NULL-case.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-NULL-case.c new file mode 100644 index 0000000..07a9848 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-NULL-case.c @@ -0,0 +1,66 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#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 + test_switch (int x) + { + switch (x) + { + case x: + return 3; + + default: + return 10; + } + } + and verify that we get a sane error about the non-const + case. + */ + gcc_jit_type *t_int = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *return_type = t_int; + gcc_jit_param *x = + gcc_jit_context_new_param (ctxt, NULL, t_int, "x"); + gcc_jit_param *params[1] = {x}; + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + return_type, + "test_switch", + 1, params, 0); + + gcc_jit_block *b_initial = + gcc_jit_function_new_block (func, "initial"); + + gcc_jit_block *b_default = + gcc_jit_function_new_block (func, "default"); + + gcc_jit_case *cases[1] = { + NULL + }; + + gcc_jit_block_end_with_switch ( + b_initial, NULL, + gcc_jit_param_as_rvalue (x), + b_default, + 1, + cases); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + CHECK_VALUE (result, NULL); + + CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt), + "gcc_jit_block_end_with_switch: NULL case 0"); +} diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-mismatching-case-type.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-mismatching-case-type.c new file mode 100644 index 0000000..cc907ce --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-mismatching-case-type.c @@ -0,0 +1,83 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#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 + test_switch (int x) + { + switch (x) + { + case (long long)0 ... (long long)5: + return 3; + default: + return 10; + } + } + and verify that the floating-point case is an error. + */ + gcc_jit_type *t_int = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *t_long_long = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_LONG_LONG); + gcc_jit_type *return_type = t_int; + gcc_jit_param *x = + gcc_jit_context_new_param (ctxt, NULL, t_int, "x"); + gcc_jit_param *params[1] = {x}; + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + return_type, + "test_switch", + 1, params, 0); + + gcc_jit_block *b_initial = + gcc_jit_function_new_block (func, "initial"); + + gcc_jit_block *b_default = + gcc_jit_function_new_block (func, "default"); + gcc_jit_block *b_case_0 = + gcc_jit_function_new_block (func, "case_0"); + + /* Note the erroneous use of "t_float" here. */ + gcc_jit_case *cases[1] = { + gcc_jit_context_new_case ( + ctxt, + gcc_jit_context_new_rvalue_from_int (ctxt, t_long_long, 0), + gcc_jit_context_new_rvalue_from_int (ctxt, t_long_long, 5), + b_case_0) + }; + + gcc_jit_block_end_with_switch ( + b_initial, NULL, + gcc_jit_param_as_rvalue (x), + b_default, + 1, + cases); + + gcc_jit_block_end_with_return ( + b_case_0, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3)); + gcc_jit_block_end_with_return ( + b_default, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10)); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + CHECK_VALUE (result, NULL); + + CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt), + "gcc_jit_block_end_with_switch:" + " mismatching types between case and expression:" + " cases[0]->min_value: (long long)0 (type: long long)" + " expr: x (type: int)"); +} diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-overlapping-ranges.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-overlapping-ranges.c new file mode 100644 index 0000000..40655c2 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_block_end_with_switch-overlapping-ranges.c @@ -0,0 +1,95 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#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 + test_switch (int x) + { + switch (x) + { + case 0 ... 5: + return 3; + + case 5 ... 10: + return 4; + + default: + return 10; + } + } + and verify that we get an error about the overlapping + ranges. + */ + gcc_jit_type *t_int = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *return_type = t_int; + gcc_jit_param *x = + gcc_jit_context_new_param (ctxt, NULL, t_int, "x"); + gcc_jit_param *params[1] = {x}; + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + return_type, + "test_switch", + 1, params, 0); + + gcc_jit_block *b_initial = + gcc_jit_function_new_block (func, "initial"); + + gcc_jit_block *b_default = + gcc_jit_function_new_block (func, "default"); + gcc_jit_block *b_case_0_5 = + gcc_jit_function_new_block (func, "case_0_5"); + gcc_jit_block *b_case_5_10 = + gcc_jit_function_new_block (func, "case_5_10"); + + gcc_jit_case *cases[2] = { + gcc_jit_context_new_case ( + ctxt, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 0), + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 5), + b_case_0_5), + gcc_jit_context_new_case ( + ctxt, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 5), + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10), + b_case_5_10) + }; + + gcc_jit_block_end_with_switch ( + b_initial, NULL, + gcc_jit_param_as_rvalue (x), + b_default, + 2, + cases); + + gcc_jit_block_end_with_return ( + b_case_0_5, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3)); + gcc_jit_block_end_with_return ( + b_case_5_10, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 4)); + gcc_jit_block_end_with_return ( + b_default, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10)); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + CHECK_VALUE (result, NULL); + + CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt), + "gcc_jit_block_end_with_switch:" + " duplicate (or overlapping) cases values:" + " case 1: case (int)5 ... (int)10: goto case_5_10;" + " overlaps case (int)0 ... (int)5: goto case_0_5;"); +} diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-non-const-label.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-non-const-label.c new file mode 100644 index 0000000..3953818 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-non-const-label.c @@ -0,0 +1,80 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#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 + test_switch (int x) + { + switch (x) + { + case x: + return 3; + + default: + return 10; + } + } + and verify that we get a sane error about the non-const + case. + */ + gcc_jit_type *t_int = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *return_type = t_int; + gcc_jit_param *x = + gcc_jit_context_new_param (ctxt, NULL, t_int, "x"); + gcc_jit_param *params[1] = {x}; + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + return_type, + "test_switch", + 1, params, 0); + + gcc_jit_block *b_initial = + gcc_jit_function_new_block (func, "initial"); + + gcc_jit_block *b_default = + gcc_jit_function_new_block (func, "default"); + gcc_jit_block *b_case_x = + gcc_jit_function_new_block (func, "case_x"); + + /* Erroneous use of non-const x for a case. */ + gcc_jit_case *cases[1] = { + gcc_jit_context_new_case ( + ctxt, + gcc_jit_param_as_rvalue (x), + gcc_jit_param_as_rvalue (x), + b_case_x) + }; + + gcc_jit_block_end_with_switch ( + b_initial, NULL, + gcc_jit_param_as_rvalue (x), + b_default, + 1, + cases); + gcc_jit_block_end_with_return ( + b_case_x, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3)); + gcc_jit_block_end_with_return ( + b_default, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10)); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + CHECK_VALUE (result, NULL); + + CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt), + "gcc_jit_context_new_case:" + " min_value is not a constant: x"); +} diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-non-integer-type.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-non-integer-type.c new file mode 100644 index 0000000..5d44286 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-non-integer-type.c @@ -0,0 +1,81 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#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 + test_switch (int x) + { + switch (x) + { + case 0.f ... 5.f: + return 3; + default: + return 10; + } + } + and verify that the floating-point case is an error. + */ + gcc_jit_type *t_int = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *t_float = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT); + gcc_jit_type *return_type = t_int; + gcc_jit_param *x = + gcc_jit_context_new_param (ctxt, NULL, t_int, "x"); + gcc_jit_param *params[1] = {x}; + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + return_type, + "test_switch", + 1, params, 0); + + gcc_jit_block *b_initial = + gcc_jit_function_new_block (func, "initial"); + + gcc_jit_block *b_default = + gcc_jit_function_new_block (func, "default"); + gcc_jit_block *b_case_0 = + gcc_jit_function_new_block (func, "case_0"); + + /* Note the erroneous use of "t_float" here. */ + gcc_jit_case *cases[1] = { + gcc_jit_context_new_case ( + ctxt, + gcc_jit_context_new_rvalue_from_int (ctxt, t_float, 0), + gcc_jit_context_new_rvalue_from_int (ctxt, t_float, 5), + b_case_0) + }; + + gcc_jit_block_end_with_switch ( + b_initial, NULL, + gcc_jit_param_as_rvalue (x), + b_default, + 1, + cases); + + gcc_jit_block_end_with_return ( + b_case_0, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3)); + gcc_jit_block_end_with_return ( + b_default, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10)); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + CHECK_VALUE (result, NULL); + + CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt), + "gcc_jit_context_new_case:" + " min_value: (float)0 (type: float) is not of integer type"); +} diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-reversed-endpoints.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-reversed-endpoints.c new file mode 100644 index 0000000..a84d9f3 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_case-reversed-endpoints.c @@ -0,0 +1,80 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#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 + test_switch (int x) + { + switch (x) + { + case 5 ... 0: + return 3; + + default: + return 10; + } + } + and verify that we get an error about the reversed endpoints + in the range. + */ + gcc_jit_type *t_int = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *return_type = t_int; + gcc_jit_param *x = + gcc_jit_context_new_param (ctxt, NULL, t_int, "x"); + gcc_jit_param *params[1] = {x}; + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + return_type, + "test_switch", + 1, params, 0); + + gcc_jit_block *b_initial = + gcc_jit_function_new_block (func, "initial"); + + gcc_jit_block *b_default = + gcc_jit_function_new_block (func, "default"); + gcc_jit_block *b_case_5_0 = + gcc_jit_function_new_block (func, "case_5_0"); + + gcc_jit_case *cases[1] = { + gcc_jit_context_new_case ( + ctxt, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 5), + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 0), + b_case_5_0) + }; + + gcc_jit_block_end_with_switch ( + b_initial, NULL, + gcc_jit_param_as_rvalue (x), + b_default, + 1, + cases); + + gcc_jit_block_end_with_return ( + b_case_5_0, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3)); + gcc_jit_block_end_with_return ( + b_default, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10)); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + CHECK_VALUE (result, NULL); + + CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt), + "gcc_jit_context_new_case:" + " min_value: (int)5 > max_value: (int)0"); +} diff --git a/gcc/testsuite/jit.dg/test-switch.c b/gcc/testsuite/jit.dg/test-switch.c new file mode 100644 index 0000000..74088c8 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-switch.c @@ -0,0 +1,147 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "libgccjit.h" + +#include "harness.h" + +/* Quote from here in docs/topics/functions.rst. */ + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + int + test_switch (int x) + { + switch (x) + { + case 0 ... 5: + return 3; + + case 25 ... 27: + return 4; + + case -42 ... -17: + return 83; + + case 40: + return 8; + + default: + return 10; + } + } + */ + gcc_jit_type *t_int = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *return_type = t_int; + gcc_jit_param *x = + gcc_jit_context_new_param (ctxt, NULL, t_int, "x"); + gcc_jit_param *params[1] = {x}; + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + return_type, + "test_switch", + 1, params, 0); + + gcc_jit_block *b_initial = + gcc_jit_function_new_block (func, "initial"); + + gcc_jit_block *b_default = + gcc_jit_function_new_block (func, "default"); + gcc_jit_block *b_case_0_5 = + gcc_jit_function_new_block (func, "case_0_5"); + gcc_jit_block *b_case_25_27 = + gcc_jit_function_new_block (func, "case_25_27"); + gcc_jit_block *b_case_m42_m17 = + gcc_jit_function_new_block (func, "case_m42_m17"); + gcc_jit_block *b_case_40 = + gcc_jit_function_new_block (func, "case_40"); + + gcc_jit_case *cases[4] = { + gcc_jit_context_new_case ( + ctxt, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 0), + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 5), + b_case_0_5), + gcc_jit_context_new_case ( + ctxt, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 25), + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 27), + b_case_25_27), + gcc_jit_context_new_case ( + ctxt, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -42), + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, -17), + b_case_m42_m17), + gcc_jit_context_new_case ( + ctxt, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40), + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 40), + b_case_40) + }; + gcc_jit_block_end_with_switch ( + b_initial, NULL, + gcc_jit_param_as_rvalue (x), + b_default, + 4, cases); + + gcc_jit_block_end_with_return ( + b_case_0_5, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 3)); + gcc_jit_block_end_with_return ( + b_case_25_27, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 4)); + gcc_jit_block_end_with_return ( + b_case_m42_m17, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 83)); + gcc_jit_block_end_with_return ( + b_case_40, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 8)); + gcc_jit_block_end_with_return ( + b_default, NULL, + gcc_jit_context_new_rvalue_from_int (ctxt, t_int, 10)); +} + +/* Quote up to here in docs/topics/functions.rst. */ + +static int +c_test_switch (int x) +{ + switch (x) + { + case 0 ... 5: + return 3; + case 25 ... 27: + return 4; + case -42 ... -17: + return 83; + case 40: + return 8; + default: + return 10; + } +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + typedef int (*test_switch_type) (int); + CHECK_NON_NULL (result); + test_switch_type test_switch = + (test_switch_type)gcc_jit_result_get_code (result, "test_switch"); + CHECK_NON_NULL (test_switch); + + int i; + + for (i = -255; i < 255; i++) + { + int val = test_switch (i); + int exp = c_test_switch (i); + if (val != exp) + fail ("test_switch (%i) returned: %i; expected; %i", i, val, exp); + } +} diff --git a/gcc/testsuite/jit.dg/test-switch.cc b/gcc/testsuite/jit.dg/test-switch.cc new file mode 100644 index 0000000..862f7a8 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-switch.cc @@ -0,0 +1,118 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "libgccjit++.h" + +#include "harness.h" + +/* Quote from here in docs/cp/topics/functions.rst. */ + +void +create_code (gcc_jit_context *c_ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + int + test_switch (int x) + { + switch (x) + { + case 0 ... 5: + return 3; + + case 25 ... 27: + return 4; + + case -42 ... -17: + return 83; + + case 40: + return 8; + + default: + return 10; + } + } + */ + gccjit::context ctxt (c_ctxt); + gccjit::type t_int = ctxt.get_type (GCC_JIT_TYPE_INT); + gccjit::type return_type = t_int; + gccjit::param x = ctxt.new_param (t_int, "x"); + std::vector <gccjit::param> params; + params.push_back (x); + gccjit::function func = ctxt.new_function (GCC_JIT_FUNCTION_EXPORTED, + return_type, + "test_switch", + params, 0); + + gccjit::block b_initial = func.new_block ("initial"); + + gccjit::block b_default = func.new_block ("default"); + gccjit::block b_case_0_5 = func.new_block ("case_0_5"); + gccjit::block b_case_25_27 = func.new_block ("case_25_27"); + gccjit::block b_case_m42_m17 = func.new_block ("case_m42_m17"); + gccjit::block b_case_40 = func.new_block ("case_40"); + + std::vector <gccjit::case_> cases; + cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 0), + ctxt.new_rvalue (t_int, 5), + b_case_0_5)); + cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 25), + ctxt.new_rvalue (t_int, 27), + b_case_25_27)); + cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, -42), + ctxt.new_rvalue (t_int, -17), + b_case_m42_m17)); + cases.push_back (ctxt.new_case (ctxt.new_rvalue (t_int, 40), + ctxt.new_rvalue (t_int, 40), + b_case_40)); + b_initial.end_with_switch (x, + b_default, + cases); + + b_case_0_5.end_with_return (ctxt.new_rvalue (t_int, 3)); + b_case_25_27.end_with_return (ctxt.new_rvalue (t_int, 4)); + b_case_m42_m17.end_with_return (ctxt.new_rvalue (t_int, 83)); + b_case_40.end_with_return (ctxt.new_rvalue (t_int, 8)); + b_default.end_with_return (ctxt.new_rvalue (t_int, 10)); +} + +/* Quote up to here in docs/cp/topics/functions.rst. */ + +static int +c_test_switch (int x) +{ + switch (x) + { + case 0 ... 5: + return 3; + case 25 ... 27: + return 4; + case -42 ... -17: + return 83; + case 40: + return 8; + default: + return 10; + } +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + typedef int (*test_switch_type) (int); + CHECK_NON_NULL (result); + test_switch_type test_switch = + (test_switch_type)gcc_jit_result_get_code (result, "test_switch"); + CHECK_NON_NULL (test_switch); + + int i; + + for (i = -255; i < 255; i++) + { + int val = test_switch (i); + int exp = c_test_switch (i); + if (val != exp) + fail ("test_switch (%i) returned: %i; expected; %i", i, val, exp); + } +} |