blob: 7b98041c9bb57d44a57e1ff03ce2e721da03eb7c [file] [log] [blame]
/* { dg-do compile { target x86_64-*-* } } */
#include <stdlib.h>
#include <stdio.h>
#include "libgccjit.h"
#define TEST_ESCHEWS_SET_OPTIONS
static void set_options (gcc_jit_context *ctxt, const char *argv0)
{
// Set "-O3".
gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3);
}
#define TEST_COMPILING_TO_FILE
#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER
#define OUTPUT_FILENAME "output-of-test-const-attribute.c.s"
#include "harness.h"
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
/* Let's try to inject the equivalent of:
__attribute__ ((const))
int foo (int x);
int xxx(void)
{
int x = 45;
int sum = 0;
while (x >>= 1)
sum += foo (x) * 2;
return sum;
}
*/
gcc_jit_type *int_type =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
/* Creating the `foo` function. */
gcc_jit_param *n =
gcc_jit_context_new_param (ctxt, NULL, int_type, "x");
gcc_jit_param *params[1] = {n};
gcc_jit_function *foo_func =
gcc_jit_context_new_function (ctxt, NULL,
GCC_JIT_FUNCTION_IMPORTED,
int_type,
"foo",
1, params,
0);
gcc_jit_function_add_attribute(foo_func, GCC_JIT_FN_ATTRIBUTE_CONST);
/* Creating the `xxx` function. */
gcc_jit_function *xxx_func =
gcc_jit_context_new_function (ctxt, NULL,
GCC_JIT_FUNCTION_EXPORTED,
int_type,
"xxx",
0, NULL,
0);
gcc_jit_block *block = gcc_jit_function_new_block (xxx_func, NULL);
/* Build locals: */
gcc_jit_lvalue *x =
gcc_jit_function_new_local (xxx_func, NULL, int_type, "x");
gcc_jit_lvalue *sum =
gcc_jit_function_new_local (xxx_func, NULL, int_type, "sum");
/* int x = 45 */
gcc_jit_block_add_assignment (
block, NULL,
x,
gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 45));
/* int sum = 0 */
gcc_jit_block_add_assignment (
block, NULL,
sum,
gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0));
/* while (x >>= 1) { sum += foo (x) * 2; } */
gcc_jit_block *loop_cond =
gcc_jit_function_new_block (xxx_func, "loop_cond");
gcc_jit_block *loop_body =
gcc_jit_function_new_block (xxx_func, "loop_body");
gcc_jit_block *after_loop =
gcc_jit_function_new_block (xxx_func, "after_loop");
gcc_jit_block_end_with_jump (block, NULL, loop_cond);
/* if (x >>= 1) */
/* Since gccjit doesn't (yet?) have support for `>>=` operator, we will decompose it into:
`if (x = x >> 1)` */
gcc_jit_block_add_assignment_op (
loop_cond, NULL,
x,
GCC_JIT_BINARY_OP_RSHIFT,
gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 1));
/* The condition itself */
gcc_jit_block_end_with_conditional (
loop_cond, NULL,
gcc_jit_context_new_comparison (
ctxt, NULL,
GCC_JIT_COMPARISON_NE,
gcc_jit_lvalue_as_rvalue (x),
gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0)),
after_loop,
loop_body);
/* sum += foo (x) * 2; */
gcc_jit_rvalue *arg = gcc_jit_lvalue_as_rvalue(x);
gcc_jit_block_add_assignment_op (
loop_body, NULL,
x,
GCC_JIT_BINARY_OP_PLUS,
gcc_jit_context_new_binary_op (
ctxt, NULL,
GCC_JIT_BINARY_OP_MULT, int_type,
gcc_jit_context_new_call (ctxt, NULL, foo_func, 1, &arg),
gcc_jit_context_new_rvalue_from_int (
ctxt,
int_type,
2)));
gcc_jit_block_end_with_jump (loop_body, NULL, loop_cond);
/* return sum; */
gcc_jit_block_end_with_return (after_loop, NULL, gcc_jit_lvalue_as_rvalue(sum));
}
/* { dg-final { jit-verify-output-file-was-created "" } } */
/* Check that the loop was optimized away */
/* { dg-final { jit-verify-assembler-output-not "jne" } } */