This is the JIT-specific part of the patch for PR jit/64166.
Implement a way to get at dumpfiles from JIT testcases.
Use it from test-sum-of-squares.c to provide a simple selftest of the
dumping functionality, and use it from test-functions.c to add
verification of the fix for PR jit/64020.
gcc/jit/ChangeLog:
PR jit/64166
* docs/topics/contexts.rst (Debugging): Add description of
gcc_jit_context_enable_dump.
* jit-playback.c: Include context.h
(class auto_argvec): New class
(auto_argvec::~auto_argvec): New function.
(gcc::jit::playback::context::compile): Convert fake_args to be
an auto_argvec, so that it can contain dynamically-allocated
strings. Construct a vec of all requested dumps, and pass it to
make_fake_args. Extract requested dumps between the calls to
toplev::main and toplev::finalize.
(gcc::jit::playback::context::make_fake_args): Convert param
"argvec" to be a vec <char *>, and gain a "requested_dumps"
param. Convert to dynamically-allocated arg strings by converting
ADD_ARG to take a copy of the arg, and add ADD_ARG_TAKE_OWNERSHIP
for args that are already a copy. Add args for all requested dumps.
(gcc::jit::playback::context::extract_any_requested_dumps): New
function.
(gcc::jit::playback::context::read_dump_file): New function.
* jit-playback.h (gcc::jit::playback::context::make_fake_args):
Convert param "argvec" to be a vec <char *>, and gain a
"requested_dumps" param.
(gcc::jit::playback::context::extract_any_requested_dumps): New
function.
(gcc::jit::playback::context::read_dump_file): New function.
* jit-recording.c (gcc::jit::recording::context::enable_dump): New
function.
(gcc::jit::recording::context::get_all_requested_dumps): New
function.
* jit-recording.h (gcc::jit::recording::requested_dump): New
struct.
(gcc::jit::recording::context::enable_dump): New function.
(gcc::jit::recording::context::get_all_requested_dumps): New
function.
(gcc::jit::recording::context::m_requested_dumps): New field.
* libgccjit.c (gcc_jit_context_enable_dump): New API entrypoint.
* libgccjit.h (gcc_jit_context_enable_dump): New API entrypoint.
* libgccjit.map (gcc_jit_context_enable_dump): New API entrypoint.
gcc/testsuite/ChangeLog:
PR jit/64166
PR jit/64020
* jit.dg/harness.h (CHECK_STRING_CONTAINS): New macro.
(check_string_contains): New function.
* jit.dg/test-error-unrecognized-dump.c: New file.
* jit.dg/test-functions.c (trig_sincos_dump): New variable.
(trig_statistics_dump): New variable.
(create_test_of_builtin_trig): Enable dumping of "sincos" and
"statistics" into "trig_sincos_dump" and "trig_statistics_dump".
(verify_test_of_builtin_trig): Verify the sincos and statistics
dumps.
* jit.dg/test-sum-of-squares.c (dump_vrp1): New variable.
(create_code): Enable dumping of "tree-vrp1" into dump_vrp1.
(verify_code): Verify the tree-vrp1 dump.
---
gcc/jit/docs/topics/contexts.rst | 47 +++++++
gcc/jit/jit-playback.c | 141 ++++++++++++++++++++-
gcc/jit/jit-playback.h | 12 +-
gcc/jit/jit-recording.c | 34 +++++
gcc/jit/jit-recording.h | 17 +++
gcc/jit/libgccjit.c | 18 +++
gcc/jit/libgccjit.h | 34 +++++
gcc/jit/libgccjit.map | 1 +
gcc/testsuite/jit.dg/harness.h | 33 +++++
.../jit.dg/test-error-unrecognized-dump.c | 27 ++++
gcc/testsuite/jit.dg/test-functions.c | 27 ++++
gcc/testsuite/jit.dg/test-sum-of-squares.c | 16 +++
12 files changed, 400 insertions(+), 7 deletions(-)
create mode 100644 gcc/testsuite/jit.dg/test-error-unrecognized-dump.c
diff --git a/gcc/jit/docs/topics/contexts.rst b/gcc/jit/docs/topics/contexts.rst
index c3f8c52..d03ccf4 100644
--- a/gcc/jit/docs/topics/contexts.rst
+++ b/gcc/jit/docs/topics/contexts.rst
@@ -152,6 +152,53 @@ Debugging
:macro:`GCC_JIT_BOOL_OPTION_DEBUGINFO` to allow stepping through the
code in a debugger.
+.. function:: void\
+ gcc_jit_context_enable_dump (gcc_jit_context *ctxt,\
+ const char *dumpname, \
+ char **out_ptr)
+
+ Enable the dumping of a specific set of internal state from the
+ compilation, capturing the result in-memory as a buffer.
+
+ Parameter "dumpname" corresponds to the equivalent gcc command-line
+ option, without the "-fdump-" prefix.
+ For example, to get the equivalent of :option:`-fdump-tree-vrp1`,
+ supply ``"tree-vrp1"``:
+
+ .. code-block:: c
+
+ static char *dump_vrp1;
+
+ void
+ create_code (gcc_jit_context *ctxt)
+ {
+ gcc_jit_context_enable_dump (ctxt, "tree-vrp1", &dump_vrp1);
+ /* (other API calls omitted for brevity) */
+ }
+
+ The context directly stores the dumpname as a ``(const char *)``, so
+ the passed string must outlive the context.
+
+ :func:`gcc_jit_context_compile` will capture the dump as a
+ dynamically-allocated buffer, writing it to ``*out_ptr``.
+
+ The caller becomes responsible for calling:
+
+ .. code-block:: c
+
+ free (*out_ptr)
+
+ each time that :func:`gcc_jit_context_compile` is called.
+ ``*out_ptr`` will be written to, either with the address of a buffer,
+ or with ``NULL`` if an error occurred.
+
+ .. warning::
+
+ This API entrypoint is likely to be less stable than the others.
+ In particular, both the precise dumpnames, and the format and content
+ of the dumps are subject to change.
+
+ It exists primarily for writing the library's own test suite.
Options
-------
diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
index ecdae80..cf50fb3 100644
--- a/gcc/jit/jit-playback.c
+++ b/gcc/jit/jit-playback.c
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimplify.h"
#include "gcc-driver-name.h"
#include "attribs.h"
+#include "context.h"
#include "jit-common.h"
#include "jit-playback.h"
@@ -1552,6 +1553,26 @@ make_tempdir_path_template ()
return result;
}
+/* A subclass of auto_vec <char *> that frees all of its elements on
+ deletion. */
+
+class auto_argvec : public auto_vec <char *>
+{
+ public:
+ ~auto_argvec ();
+};
+
+/* auto_argvec's dtor, freeing all contained strings, automatically
+ chaining up to ~auto_vec <char *>, which frees the internal buffer. */
+
+auto_argvec::~auto_argvec ()
+{
+ int i;
+ char *str;
+ FOR_EACH_VEC_ELT (*this, i, str)
+ free (str);
+}
+
/* Compile a playback::context:
- Use the context's options to cconstruct command-line options, and
@@ -1594,14 +1615,25 @@ compile ()
if (!ctxt_progname)
ctxt_progname = "libgccjit.so";
- auto_vec <const char *> fake_args;
- make_fake_args (&fake_args, ctxt_progname);
+ auto_vec <recording::requested_dump> requested_dumps;
+ m_recording_ctxt->get_all_requested_dumps (&requested_dumps);
+
+ auto_argvec fake_args;
+ make_fake_args (&fake_args, ctxt_progname, &requested_dumps);
if (errors_occurred ())
return NULL;
+ /* This runs the compiler. */
toplev toplev (false);
toplev.main (fake_args.length (),
const_cast <char **> (fake_args.address ()));
+
+ /* Extracting dumps makes use of the gcc::dump_manager, hence we
+ need to do it between toplev::main (which creates the dump manager)
+ and toplev::finalize (which deletes it). */
+ extract_any_requested_dumps (&requested_dumps);
+
+ /* Clean up the compiler. */
toplev.finalize ();
active_playback_ctxt = NULL;
@@ -1645,10 +1677,12 @@ compile ()
void
playback::context::
-make_fake_args (auto_vec <const char *> *argvec,
- const char *ctxt_progname)
+make_fake_args (vec <char *> *argvec,
+ const char *ctxt_progname,
+ vec <recording::requested_dump> *requested_dumps)
{
-#define ADD_ARG(arg) argvec->safe_push (arg)
+#define ADD_ARG(arg) argvec->safe_push (xstrdup (arg))
+#define ADD_ARG_TAKE_OWNERSHIP(arg) argvec->safe_push (arg)
ADD_ARG (ctxt_progname);
ADD_ARG (m_path_c_file);
@@ -1707,7 +1741,104 @@ make_fake_args (auto_vec <const char *> *argvec,
ADD_ARG ("-fdump-rtl-all");
ADD_ARG ("-fdump-ipa-all");
}
+
+ /* Add "-fdump-" options for any calls to
+ gcc_jit_context_enable_dump. */
+ {
+ int i;
+ recording::requested_dump *d;
+ FOR_EACH_VEC_ELT (*requested_dumps, i, d)
+ {
+ char *arg = concat ("-fdump-", d->m_dumpname, NULL);
+ ADD_ARG_TAKE_OWNERSHIP (arg);
+ }
+ }
+
#undef ADD_ARG
+#undef ADD_ARG_TAKE_OWNERSHIP
+}
+
+/* The second half of the implementation of gcc_jit_context_enable_dump.
+ Iterate through the requested dumps, reading the underlying files
+ into heap-allocated buffers, writing pointers to the buffers into
+ the char ** pointers provided by client code.
+ Client code is responsible for calling free on the results. */
+
+void
+playback::context::
+extract_any_requested_dumps (vec <recording::requested_dump> *requested_dumps)
+{
+ int i;
+ recording::requested_dump *d;
+ FOR_EACH_VEC_ELT (*requested_dumps, i, d)
+ {
+ dump_file_info *dfi;
+ char *filename;
+ char *content;
+
+ dfi = g->get_dumps ()->get_dump_file_info_by_switch (d->m_dumpname);
+ if (!dfi)
+ {
+ add_error (NULL, "unrecognized dump: %s", d->m_dumpname);
+ continue;
+ }
+
+ filename = g->get_dumps ()->get_dump_file_name (dfi);
+ content = read_dump_file (filename);
+ *(d->m_out_ptr) = content;
+ free (filename);
+ }
+}
+
+/* Helper function for playback::context::extract_any_requested_dumps
+ (itself for use in implementation of gcc_jit_context_enable_dump).
+
+ Attempt to read the complete file at the given path, returning the
+ bytes found there as a buffer.
+ The caller is responsible for calling free on the result.
+ Errors will be reported on the context, and lead to NULL being
+ returned; an out-of-memory error will terminate the process. */
+
+char *
+playback::context::read_dump_file (const char *path)
+{
+ char *result = NULL;
+ size_t total_sz = 0;
+ char buf[4096];
+ size_t sz;
+ FILE *f_in;
+
+ f_in = fopen (path, "r");
+ if (!f_in)
+ {
+ add_error (NULL, "unable to open %s for reading", path);
+ return NULL;
+ }
+
+ while ( (sz = fread (buf, 1, sizeof (buf), f_in)) )
+ {
+ size_t old_total_sz = total_sz;
+ total_sz += sz;
+ result = reinterpret_cast <char *> (xrealloc (result, total_sz + 1));
+ memcpy (result + old_total_sz, buf, sz);
+ }
+
+ if (!feof (f_in))
+ {
+ add_error (NULL, "error reading from %s", path);
+ free (result);
+ return NULL;
+ }
+
+ fclose (f_in);
+
+ if (result)
+ {
+ result[total_sz] = '\0';
+ return result;
+ }
+ else
+ return xstrdup ("");
}
/* Part of playback::context::compile ().
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index 02f08ba..b2b983a 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -236,8 +236,16 @@ private:
/* Functions for implementing "compile". */
void
- make_fake_args (auto_vec <const char *> *argvec,
- const char *ctxt_progname);
+ make_fake_args (vec <char *> *argvec,
+ const char *ctxt_progname,
+ vec <recording::requested_dump> *requested_dumps);
+
+ void
+ extract_any_requested_dumps
+ (vec <recording::requested_dump> *requested_dumps);
+
+ char *
+ read_dump_file (const char *path);
void
convert_to_dso (const char *ctxt_progname);
diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c
index 82ec399..74fd111 100644
--- a/gcc/jit/jit-recording.c
+++ b/gcc/jit/jit-recording.c
@@ -868,6 +868,27 @@ recording::context::set_bool_option (enum
gcc_jit_bool_option opt,
m_bool_options[opt] = value ? true : false;
}
+/* Add the given dumpname/out_ptr pair to this context's list of requested
+ dumps.
+
+ Implements the post-error-checking part of
+ gcc_jit_context_enable_dump. */
+
+void
+recording::context::enable_dump (const char *dumpname,
+ char **out_ptr)
+{
+ requested_dump d;
+ gcc_assert (dumpname);
+ gcc_assert (out_ptr);
+
+ d.m_dumpname = dumpname;
+ d.m_out_ptr = out_ptr;
+ *out_ptr = NULL;
+ m_requested_dumps.safe_push (d);
+}
+
+
/* This mutex guards gcc::jit::recording::context::compile, so that only
one thread can be accessing the bulk of GCC's state at once. */
@@ -1026,6 +1047,19 @@ recording::context::dump_to_file (const char *path, bool
update_locations)
}
}
+/* Copy the requested dumps within this context and all ancestors into
+ OUT. */
+
+void
+recording::context::get_all_requested_dumps (vec <recording::requested_dump>
*out)
+{
+ if (m_parent_ctxt)
+ m_parent_ctxt->get_all_requested_dumps (out);
+
+ out->reserve (m_requested_dumps.length ());
+ out->splice (m_requested_dumps);
+}
+
/* This is a pre-compilation check for the context (and any parents).
Detect errors within the context, adding errors if any are found. */
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 31fb304..d2f5ffb 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -45,6 +45,13 @@ playback_string (string *str);
playback::block *
playback_block (block *b);
+/* A recording of a call to gcc_jit_context_enable_dump. */
+struct requested_dump
+{
+ const char *m_dumpname;
+ char **m_out_ptr;
+};
+
/* A JIT-compilation context. */
class context
{
@@ -191,6 +198,10 @@ public:
set_bool_option (enum gcc_jit_bool_option opt,
int value);
+ void
+ enable_dump (const char *dumpname,
+ char **out_ptr);
+
const char *
get_str_option (enum gcc_jit_str_option opt) const
{
@@ -235,6 +246,9 @@ public:
void dump_to_file (const char *path, bool update_locations);
+ void
+ get_all_requested_dumps (vec <recording::requested_dump> *out);
+
private:
void validate ();
@@ -250,6 +264,9 @@ private:
int m_int_options[GCC_JIT_NUM_INT_OPTIONS];
bool m_bool_options[GCC_JIT_NUM_BOOL_OPTIONS];
+ /* Dumpfiles that were requested via gcc_jit_context_enable_dump. */
+ auto_vec<requested_dump> m_requested_dumps;
+
/* Recorded API usage. */
auto_vec<memento *> m_mementos;
diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index 42769e8..0f50c43 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -2004,6 +2004,24 @@ gcc_jit_context_set_bool_option (gcc_jit_context *ctxt,
/* Public entrypoint. See description in libgccjit.h.
After error-checking, the real work is done by the
+ gcc::jit::recording::context::enable_dump method in
+ jit-recording.c. */
+
+void
+gcc_jit_context_enable_dump (gcc_jit_context *ctxt,
+ const char *dumpname,
+ char **out_ptr)
+{
+ RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+ RETURN_IF_FAIL (dumpname, ctxt, NULL, "NULL dumpname");
+ RETURN_IF_FAIL (out_ptr, ctxt, NULL, "NULL out_ptr");
+
+ ctxt->enable_dump (dumpname, out_ptr);
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
gcc::jit::recording::context::compile method in
jit-recording.c. */
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index ed6390e..71628e0 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -985,6 +985,40 @@ gcc_jit_block_end_with_void_return (gcc_jit_block *block,
extern gcc_jit_context *
gcc_jit_context_new_child_context (gcc_jit_context *parent_ctxt);
+/**********************************************************************
+ Implementation support.
+ **********************************************************************/
+
+/* Enable the dumping of a specific set of internal state from the
+ compilation, capturing the result in-memory as a buffer.
+
+ Parameter "dumpname" corresponds to the equivalent gcc command-line
+ option, without the "-fdump-" prefix.
+ For example, to get the equivalent of "-fdump-tree-vrp1", supply
+ "tree-vrp1".
+ The context directly stores the dumpname as a (const char *), so the
+ passed string must outlive the context.
+
+ gcc_jit_context_compile will capture the dump as a
+ dynamically-allocated buffer, writing it to ``*out_ptr``.
+
+ The caller becomes responsible for calling
+ free (*out_ptr)
+ each time that gcc_jit_context_compile is called. *out_ptr will be
+ written to, either with the address of a buffer, or with NULL if an
+ error occurred.
+
+ This API entrypoint is likely to be less stable than the others.
+ In particular, both the precise dumpnames, and the format and content
+ of the dumps are subject to change.
+
+ It exists primarily for writing the library's own test suite. */
+
+extern void
+gcc_jit_context_enable_dump (gcc_jit_context *ctxt,
+ const char *dumpname,
+ char **out_ptr);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index d4ba7b6..0375e77 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -33,6 +33,7 @@
gcc_jit_context_acquire;
gcc_jit_context_compile;
gcc_jit_context_dump_to_file;
+ gcc_jit_context_enable_dump;
gcc_jit_context_get_builtin_function;
gcc_jit_context_get_first_error;
gcc_jit_context_get_type;
diff --git a/gcc/testsuite/jit.dg/harness.h b/gcc/testsuite/jit.dg/harness.h
index a30b66e..1493c6f 100644
--- a/gcc/testsuite/jit.dg/harness.h
+++ b/gcc/testsuite/jit.dg/harness.h
@@ -84,6 +84,9 @@ static char test[1024];
#define CHECK_STRING_STARTS_WITH(ACTUAL, EXPECTED_PREFIX) \
check_string_starts_with ((ACTUAL), (EXPECTED_PREFIX));
+#define CHECK_STRING_CONTAINS(ACTUAL, EXPECTED_SUBSTRING) \
+ check_string_contains (#ACTUAL, (ACTUAL), (EXPECTED_SUBSTRING));
+
#define CHECK(COND) \
do { \
if (COND) \
@@ -110,6 +113,11 @@ extern void
check_string_starts_with (const char *actual,
const char *expected_prefix);
+extern void
+check_string_contains (const char *name,
+ const char *actual,
+ const char *expected_substring);
+
/* Implement framework needed for turning the testcase hooks into an
executable. test-combination.c and test-threads.c each combine multiple
testcases into larger testcases, so we have COMBINED_TEST as a way of
@@ -168,6 +176,31 @@ check_string_starts_with (const char *actual,
test, actual, expected_prefix);
}
+void
+check_string_contains (const char *name,
+ const char *actual,
+ const char *expected_substring)
+{
+ if (!actual)
+ {
+ fail ("%s: %s: actual: NULL does not contain expected substring: \"%s\"",
+ test, name, expected_substring);
+ fprintf (stderr, "incorrect value\n");
+ abort ();
+ }
+
+ if (!strstr (actual, expected_substring))
+ {
+ fail ("%s: %s: actual: \"%s\" did not contain expected substring:
\"%s\"",
+ test, name, actual, expected_substring);
+ fprintf (stderr, "incorrect value\n");
+ abort ();
+ }
+
+ pass ("%s: %s: found substring: \"%s\"",
+ test, name, expected_substring);
+}
+
static void set_options (gcc_jit_context *ctxt, const char *argv0)
{
/* Set up options. */
diff --git a/gcc/testsuite/jit.dg/test-error-unrecognized-dump.c
b/gcc/testsuite/jit.dg/test-error-unrecognized-dump.c
new file mode 100644
index 0000000..0b73360
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-unrecognized-dump.c
@@ -0,0 +1,27 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+static char *dump;
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_context_enable_dump (ctxt,
+ "not-a-valid-dump-switch",
+ &dump);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_VALUE (result, NULL);
+
+ /* Verify that the correct error message was emitted. */
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "unrecognized dump: not-a-valid-dump-switch");
+}
+
diff --git a/gcc/testsuite/jit.dg/test-functions.c
b/gcc/testsuite/jit.dg/test-functions.c
index 3d03ada..45c24d6 100644
--- a/gcc/testsuite/jit.dg/test-functions.c
+++ b/gcc/testsuite/jit.dg/test-functions.c
@@ -167,6 +167,9 @@ create_test_of_builtin_strcmp (gcc_jit_context *ctxt)
gcc_jit_block_end_with_return (initial, NULL, call);
}
+static char *trig_sincos_dump;
+static char *trig_statistics_dump;
+
static void
create_test_of_builtin_trig (gcc_jit_context *ctxt)
{
@@ -178,6 +181,14 @@ create_test_of_builtin_trig (gcc_jit_context *ctxt)
}
(in theory, optimizable to sin (2 * theta))
*/
+
+ gcc_jit_context_enable_dump (ctxt,
+ "tree-sincos",
+ &trig_sincos_dump);
+ gcc_jit_context_enable_dump (ctxt,
+ "statistics",
+ &trig_statistics_dump);
+
gcc_jit_type *double_t =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE);
@@ -266,6 +277,22 @@ verify_test_of_builtin_trig (gcc_jit_context *ctxt,
gcc_jit_result *result)
CHECK_DOUBLE_VALUE (test_of_builtin_trig (M_PI_2 ), 0.0);
CHECK_DOUBLE_VALUE (test_of_builtin_trig (M_PI_4 * 3.0), -1.0);
CHECK_DOUBLE_VALUE (test_of_builtin_trig (M_PI ), 0.0);
+
+ /* PR jit/64020:
+ The "sincos" pass merges sin/cos calls into the cexpi builtin.
+ Verify that a dump of the "sincos" pass was provided, and that it
+ shows a call to the cexpi builtin on a SSA name of "theta". */
+ CHECK_NON_NULL (trig_sincos_dump);
+ CHECK_STRING_CONTAINS (trig_sincos_dump, " = __builtin_cexpi (theta_");
+ free (trig_sincos_dump);
+
+ /* Similarly, verify that the statistics dump was provided, and that
+ it shows the sincos optimization. */
+ CHECK_NON_NULL (trig_statistics_dump);
+ CHECK_STRING_CONTAINS (
+ trig_statistics_dump,
+ "sincos \"sincos statements inserted\" \"test_of_builtin_trig\" 1");
+ free (trig_statistics_dump);
}
static void
diff --git a/gcc/testsuite/jit.dg/test-sum-of-squares.c
b/gcc/testsuite/jit.dg/test-sum-of-squares.c
index d6fdcf6..46fd5c2 100644
--- a/gcc/testsuite/jit.dg/test-sum-of-squares.c
+++ b/gcc/testsuite/jit.dg/test-sum-of-squares.c
@@ -6,6 +6,8 @@
#include "harness.h"
+static char *dump_vrp1;
+
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
@@ -22,6 +24,8 @@ create_code (gcc_jit_context *ctxt, void *user_data)
}
return sum;
*/
+ gcc_jit_context_enable_dump (ctxt, "tree-vrp1", &dump_vrp1);
+
gcc_jit_type *the_type =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
gcc_jit_type *return_type = the_type;
@@ -123,4 +127,16 @@ verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
int val = loop_test (10);
note ("loop_test returned: %d", val);
CHECK_VALUE (val, 285);
+
+ CHECK_NON_NULL (dump_vrp1);
+ /* PR jit/64166
+ An example of using gcc_jit_context_enable_dump to verify a property
+ of the compile.
+
+ In this case, verify that vrp is able to deduce the
+ bounds of the iteration variable. Specifically, verify that some
+ variable is known to be in the range negative infinity to some
+ expression based on param "n" (actually n-1). */
+ CHECK_STRING_CONTAINS (dump_vrp1, ": [-INF, n_");
+ free (dump_vrp1);
}
--
1.8.5.3