From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15030 invoked by alias); 7 Jan 2015 20:13:56 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 15010 invoked by uid 89); 7 Jan 2015 20:13:55 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Wed, 07 Jan 2015 20:13:54 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t07KDqxf032339 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 7 Jan 2015 15:13:52 -0500 Received: from c64.redhat.com (vpn-227-171.phx2.redhat.com [10.3.227.171]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t07KDpx0013958; Wed, 7 Jan 2015 15:13:51 -0500 From: David Malcolm To: jit@gcc.gnu.org, gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH, committed] Add test of handling arithmetic-overflow from JIT Date: Wed, 07 Jan 2015 20:13:00 -0000 Message-Id: <1420662149-33381-1-git-send-email-dmalcolm@redhat.com> X-IsSubscribed: yes X-SW-Source: 2015-01/txt/msg00340.txt.bz2 New testcase to verify that libgccjit client code can handle arithmeti overflow. This testcase brings jit.sum from: # of expected passes 5158 to: # of expected passes 6121 Committed to trunk as r219320. FWIW my motivation for this testcase was due to implementing "INT_*_OVF" operations within an experimental backend for PyPy I'm hacking on: https://bitbucket.org/pypy/pypy/branch/libgccjit-backend where I hope to use libgccjit within PyPy's JIT for turning traced loops into machine code; the commit in question there was: https://bitbucket.org/pypy/pypy/commits/dfab06318973a8b8a5393708519269280dab395e gcc/testsuite/ChangeLog: * jit.dg/test-arith-overflow.c: New test case. * jit.dg/all-non-failing-tests.h: Add test-arith-overflow.c. * jit.dg/test-combination.c (create_code): Likewise. (verify_code): Likewise. * jit.dg/test-threads.c (testcases): Likewise. --- gcc/testsuite/jit.dg/all-non-failing-tests.h | 7 + gcc/testsuite/jit.dg/test-arith-overflow.c | 223 +++++++++++++++++++++++++++ gcc/testsuite/jit.dg/test-combination.c | 2 + gcc/testsuite/jit.dg/test-threads.c | 3 + 4 files changed, 235 insertions(+) create mode 100644 gcc/testsuite/jit.dg/test-arith-overflow.c diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h index 10d7199..beb3d13 100644 --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h @@ -22,6 +22,13 @@ #undef create_code #undef verify_code +/* test-arith-overflow.c */ +#define create_code create_code_arith_overflow +#define verify_code verify_code_arith_overflow +#include "test-arith-overflow.c" +#undef create_code +#undef verify_code + /* test-array-as-pointer.c */ #define create_code create_code_array_as_pointer #define verify_code verify_code_array_as_pointer diff --git a/gcc/testsuite/jit.dg/test-arith-overflow.c b/gcc/testsuite/jit.dg/test-arith-overflow.c new file mode 100644 index 0000000..8d130b2 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-arith-overflow.c @@ -0,0 +1,223 @@ +#include +#include +#include +#include + +#include "libgccjit.h" + +#include "harness.h" + +static void +create_overflow_fn (gcc_jit_context *ctxt, + gcc_jit_type *type, + const char *funcname, + const char *builtin_name) +{ + /* Create the equivalent of this C: + + int + test_overflow_T_OP (T x, T y, int *ovf) + { + T result; + result = x OP y; + *ovf = ...; // did overflow happen? + return result; + } + + */ + gcc_jit_type *t_bool = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_BOOL); + gcc_jit_type *t_bool_star = + gcc_jit_type_get_pointer (t_bool); + + gcc_jit_param *x = + gcc_jit_context_new_param ( + ctxt, + NULL, + type, "x"); + gcc_jit_param *y = + gcc_jit_context_new_param ( + ctxt, + NULL, + type, "y"); + gcc_jit_param *ovf = + gcc_jit_context_new_param ( + ctxt, + NULL, + t_bool_star, "ovf"); + gcc_jit_param *params[3] = {x, y, ovf}; + + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, + NULL, + GCC_JIT_FUNCTION_EXPORTED, + type, + funcname, + 3, params, 0); + + gcc_jit_lvalue *result = + gcc_jit_function_new_local (func, NULL, type, "result"); + + gcc_jit_block *b_initial = + gcc_jit_function_new_block (func, "initial"); + + /* The builtins are listed in builtins.def as being variadic, but + the have these signatures: + bool __builtin_add_overflow (type1 a, type2 b, type3 *res); + bool __builtin_sub_overflow (type1 a, type2 b, type3 *res); + bool __builtin_mul_overflow (type1 a, type2 b, type3 *res); */ + + gcc_jit_function *builtin_fn = + gcc_jit_context_get_builtin_function (ctxt, builtin_name); + + /* Construct a call of the form: + (returns bool) __builtin_add_overflow (x, y, &result). */ + gcc_jit_rvalue *args[3] = {gcc_jit_param_as_rvalue (x), + gcc_jit_param_as_rvalue (y), + gcc_jit_lvalue_get_address (result, NULL)}; + gcc_jit_rvalue *call = + gcc_jit_context_new_call (ctxt, + NULL, + builtin_fn, + 3, args); + + /* "*ovf = BUILTIN_CALL ();" */ + gcc_jit_block_add_assignment ( + b_initial, NULL, + gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (ovf), + NULL), + call); + + /* "return result;" */ + gcc_jit_block_end_with_return ( + b_initial, NULL, + gcc_jit_lvalue_as_rvalue (result)); +} + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* int */ + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + create_overflow_fn (ctxt, int_type, + "test_overflow_int_add", + "__builtin_add_overflow"); + create_overflow_fn (ctxt, int_type, + "test_overflow_int_sub", + "__builtin_sub_overflow"); + create_overflow_fn (ctxt, int_type, + "test_overflow_int_mul", + "__builtin_mul_overflow"); + + /* uint */ + gcc_jit_type *uint_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_INT); + create_overflow_fn (ctxt, uint_type, + "test_overflow_uint_add", + "__builtin_add_overflow"); + create_overflow_fn (ctxt, uint_type, + "test_overflow_uint_sub", + "__builtin_sub_overflow"); + create_overflow_fn (ctxt, uint_type, + "test_overflow_uint_mul", + "__builtin_mul_overflow"); +} + +void +verify_int_overflow_fn (gcc_jit_result *jit_result, + const char *funcname, + int x, int y, + int expected_result, + int expected_ovf) +{ + CHECK_NON_NULL (jit_result); + typedef int (*overflow_fn_type) (int, int, int *); + overflow_fn_type fn = + (overflow_fn_type)gcc_jit_result_get_code (jit_result, funcname); + CHECK_NON_NULL (fn); + + /* Call the function: */ + int actual_ovf = 0; + int actual_result = fn (x, y, &actual_ovf); + note ("%s (%d, %d) returned: %d with ovf: %d", + funcname, x, y, actual_result, actual_ovf); + CHECK_VALUE (actual_result, expected_result); + CHECK_VALUE (actual_ovf, expected_ovf); +} + +void +verify_uint_overflow_fn (gcc_jit_result *jit_result, + const char *funcname, + unsigned int x, unsigned int y, + unsigned int expected_result, + int expected_ovf) +{ + CHECK_NON_NULL (jit_result); + typedef unsigned int (*overflow_fn_type) (unsigned int, unsigned int, int *); + overflow_fn_type fn = + (overflow_fn_type)gcc_jit_result_get_code (jit_result, funcname); + CHECK_NON_NULL (fn); + + /* Call the function: */ + int actual_ovf = 0; + unsigned int actual_result = fn (x, y, &actual_ovf); + note ("%s (%d, %d) returned: %d with ovf: %d", + funcname, x, y, actual_result, actual_ovf); + CHECK_VALUE (actual_result, expected_result); + CHECK_VALUE (actual_ovf, expected_ovf); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + verify_int_overflow_fn (result, "test_overflow_int_add", + 5, 15, + 20, 0); + verify_int_overflow_fn (result, "test_overflow_int_add", + INT_MAX, 1, + INT_MIN, 1); + verify_int_overflow_fn (result, "test_overflow_int_sub", + 5, 15, + -10, 0); + verify_int_overflow_fn (result, "test_overflow_int_sub", + INT_MIN, 1, + INT_MAX, 1); + verify_int_overflow_fn (result, "test_overflow_int_mul", + 5, 15, + 75, 0); + verify_int_overflow_fn (result, "test_overflow_int_mul", + INT_MAX, 1, + INT_MAX, 0); + verify_int_overflow_fn (result, "test_overflow_int_mul", + INT_MAX, 2, + -2, 1); + + verify_uint_overflow_fn (result, "test_overflow_uint_add", + 5, 15, + 20, 0); + verify_uint_overflow_fn (result, "test_overflow_uint_add", + INT_MAX, 1, + (((unsigned int)INT_MAX) + 1), 0); + verify_uint_overflow_fn (result, "test_overflow_uint_add", + UINT_MAX, 1, + 0, 1); + verify_uint_overflow_fn (result, "test_overflow_uint_sub", + 5, 15, + (UINT_MAX - 9), 1); + verify_uint_overflow_fn (result, "test_overflow_uint_sub", + INT_MIN, 1, + ((unsigned int)INT_MIN - 1), 0); + verify_uint_overflow_fn (result, "test_overflow_uint_mul", + 5, 15, + 75, 0); + verify_uint_overflow_fn (result, "test_overflow_uint_mul", + INT_MAX, 1, + INT_MAX, 0); + verify_uint_overflow_fn (result, "test_overflow_uint_mul", + INT_MAX, 2, + (unsigned int)INT_MAX * 2, 0); + verify_uint_overflow_fn (result, "test_overflow_uint_mul", + UINT_MAX, 2, + -2/*(unsigned int)INT_MAX * 2*/, 1); +} diff --git a/gcc/testsuite/jit.dg/test-combination.c b/gcc/testsuite/jit.dg/test-combination.c index 06ba902..e99f4d0 100644 --- a/gcc/testsuite/jit.dg/test-combination.c +++ b/gcc/testsuite/jit.dg/test-combination.c @@ -17,6 +17,7 @@ create_code (gcc_jit_context *ctxt, void * user_data) { create_code_accessing_struct (ctxt, user_data); create_code_accessing_union (ctxt, user_data); + create_code_arith_overflow (ctxt, user_data); create_code_array_as_pointer (ctxt, user_data); create_code_arrays (ctxt, user_data); create_code_calling_external_function (ctxt, user_data); @@ -44,6 +45,7 @@ verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) { verify_code_accessing_struct (ctxt, result); verify_code_accessing_union (ctxt, result); + verify_code_arith_overflow (ctxt, result); verify_code_array_as_pointer (ctxt, result); verify_code_arrays (ctxt, result); verify_code_calling_external_function (ctxt, result); diff --git a/gcc/testsuite/jit.dg/test-threads.c b/gcc/testsuite/jit.dg/test-threads.c index 7c248cc..cd5ef6a 100644 --- a/gcc/testsuite/jit.dg/test-threads.c +++ b/gcc/testsuite/jit.dg/test-threads.c @@ -107,6 +107,9 @@ const struct testcase testcases[] = { {"accessing_union", create_code_accessing_union, verify_code_accessing_union}, + {"arith_overflow", + create_code_arith_overflow, + verify_code_arith_overflow}, {"array_as_pointer", create_code_array_as_pointer, verify_code_array_as_pointer}, -- 1.8.5.3