#include #include #include "libgccjit.h" #include "harness.h" /* Reproducer for PR jit/66779. Inject the equivalent of: T FUNCNAME (T i, T j, T k) { bool comp0 = i & 0x40; bool comp1 = (j == k); if (comp0 && comp1) return 7; else return 22; } for some type T; this was segfaulting during the expansion to RTL due to missing handling for some machine modes in jit_langhook_type_for_mode. */ void create_fn (gcc_jit_context *ctxt, const char *funcname, enum gcc_jit_types jit_type) { gcc_jit_type *the_type = gcc_jit_context_get_type (ctxt, jit_type); gcc_jit_type *t_bool = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_BOOL); gcc_jit_param *param_i = gcc_jit_context_new_param (ctxt, NULL, the_type, "i"); gcc_jit_param *param_j = gcc_jit_context_new_param (ctxt, NULL, the_type, "j"); gcc_jit_param *param_k = gcc_jit_context_new_param (ctxt, NULL, the_type, "k"); gcc_jit_param *params[3] = { param_i, param_j, param_k }; gcc_jit_function *func = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, the_type, funcname, 3, params, 0); gcc_jit_block *b_entry = gcc_jit_function_new_block (func, "entry"); gcc_jit_block *b_on_true = gcc_jit_function_new_block (func, "on_true"); gcc_jit_block *b_on_false = gcc_jit_function_new_block (func, "on_false"); gcc_jit_lvalue *comp0 = gcc_jit_function_new_local (func, NULL, t_bool, "comp0"); gcc_jit_block_add_assignment ( b_entry, NULL, comp0, gcc_jit_context_new_comparison ( ctxt, NULL, GCC_JIT_COMPARISON_NE, gcc_jit_context_new_binary_op ( ctxt, NULL, GCC_JIT_BINARY_OP_BITWISE_AND, the_type, gcc_jit_param_as_rvalue (param_i), gcc_jit_context_new_rvalue_from_int (ctxt, the_type, 0x40)), gcc_jit_context_zero (ctxt, the_type))); gcc_jit_lvalue *comp1 = gcc_jit_function_new_local (func, NULL, t_bool, "comp1"); gcc_jit_block_add_assignment ( b_entry, NULL, comp1, gcc_jit_context_new_comparison (ctxt, NULL, GCC_JIT_COMPARISON_EQ, gcc_jit_param_as_rvalue (param_j), gcc_jit_param_as_rvalue (param_k))); gcc_jit_rvalue *cond = gcc_jit_context_new_binary_op (ctxt, NULL, GCC_JIT_BINARY_OP_LOGICAL_AND, t_bool, gcc_jit_lvalue_as_rvalue (comp0), gcc_jit_lvalue_as_rvalue (comp1)); gcc_jit_block_end_with_conditional (b_entry, NULL, cond, b_on_true, b_on_false); gcc_jit_block_end_with_return ( b_on_true, NULL, gcc_jit_context_new_rvalue_from_int (ctxt, the_type, 7)); gcc_jit_block_end_with_return ( b_on_false, NULL, gcc_jit_context_new_rvalue_from_int (ctxt, the_type, 22)); } void create_code (gcc_jit_context *ctxt, void *user_data) { create_fn (ctxt, "pr66779_signed_char", GCC_JIT_TYPE_SIGNED_CHAR); create_fn (ctxt, "pr66779_unsigned_char", GCC_JIT_TYPE_UNSIGNED_CHAR); create_fn (ctxt, "pr66779_short", GCC_JIT_TYPE_SHORT); create_fn (ctxt, "pr66779_unsigned_short", GCC_JIT_TYPE_UNSIGNED_SHORT); create_fn (ctxt, "pr66779_int", GCC_JIT_TYPE_INT); create_fn (ctxt, "pr66779_unsigned_int", GCC_JIT_TYPE_UNSIGNED_INT); create_fn (ctxt, "pr66779_long", GCC_JIT_TYPE_LONG); create_fn (ctxt, "pr66779_unsigned_long", GCC_JIT_TYPE_UNSIGNED_LONG); create_fn (ctxt, "pr66779_long_long", GCC_JIT_TYPE_LONG_LONG); create_fn (ctxt, "pr66779_unsigned_long_long", GCC_JIT_TYPE_UNSIGNED_LONG_LONG); create_fn (ctxt, "pr66779_size_t", GCC_JIT_TYPE_SIZE_T); } extern void verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) { typedef int (*fn_type) (int, int, int); CHECK_NON_NULL (result); /* Sanity-check the "int" case. */ fn_type fn = (fn_type)gcc_jit_result_get_code (result, "pr66779_int"); CHECK_NON_NULL (fn); CHECK_VALUE (fn (0, 0, 0), 22); CHECK_VALUE (fn (0, 0, 1), 22); CHECK_VALUE (fn (0x40, 0, 0), 7); CHECK_VALUE (fn (0x40, 0, 1), 22); CHECK_VALUE (fn (0x40, 1, 1), 7); CHECK_VALUE (fn (0x3f, 0, 0), 22); CHECK_VALUE (fn (0x3f, 1, 1), 22); }