From: Georg-Johann Lay Date: Tue, 3 Mar 2015 11:25:04 +0000 (+0000) Subject: re PR target/64331 (regcprop propagates registers noted as REG_DEAD) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2b4293a3907cce6e9aced9884300227c2def337c;p=gcc.git re PR target/64331 (regcprop propagates registers noted as REG_DEAD) gcc/ PR target/64331 * config/avr/avr.c (context.h, tree-pass.h): Include them. (avr_pass_data_recompute_notes): New static variable. (avr_pass_recompute_notes): New class. (avr_register_passes): New static function. (avr_option_override): Call it. gcc/testsuite/ PR target/64331 * gcc.target/avr/torture/pr64331.c: New test. From-SVN: r221143 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aeeda83fd07..9eef7746f5f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2015-03-03 Georg-Johann Lay + + PR target/64331 + * config/avr/avr.c (context.h, tree-pass.h): Include them. + (avr_pass_data_recompute_notes): New static variable. + (avr_pass_recompute_notes): New class. + (avr_register_passes): New static function. + (avr_option_override): Call it. + 2015-03-03 Georg-Johann Lay Fix various problems with specs file generation. diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 07d7bafd54a..827b2800597 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -81,6 +81,8 @@ #include "basic-block.h" #include "df.h" #include "builtins.h" +#include "context.h" +#include "tree-pass.h" /* Maximal allowed offset for an address in the LD command */ #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE)) @@ -329,6 +331,55 @@ avr_to_int_mode (rtx x) } +static const pass_data avr_pass_data_recompute_notes = +{ + RTL_PASS, // type + "", // name (will be patched) + OPTGROUP_NONE, // optinfo_flags + TV_DF_SCAN, // tv_id + 0, // properties_required + 0, // properties_provided + 0, // properties_destroyed + 0, // todo_flags_start + TODO_df_finish | TODO_df_verify // todo_flags_finish +}; + + +class avr_pass_recompute_notes : public rtl_opt_pass +{ +public: + avr_pass_recompute_notes (gcc::context *ctxt, const char *name) + : rtl_opt_pass (avr_pass_data_recompute_notes, ctxt) + { + this->name = name; + } + + virtual unsigned int execute (function*) + { + df_note_add_problem (); + df_analyze (); + + return 0; + } +}; // avr_pass_recompute_notes + + +static void +avr_register_passes (void) +{ + /* This avr-specific pass (re)computes insn notes, in particular REG_DEAD + notes which are used by `avr.c::reg_unused_after' and branch offset + computations. These notes must be correct, i.e. there must be no + dangling REG_DEAD notes; otherwise wrong code might result, cf. PR64331. + + DF needs (correct) CFG, hence right before free_cfg is the last + opportunity to rectify notes. */ + + register_pass (new avr_pass_recompute_notes (g, "avr-notes-free-cfg"), + PASS_POS_INSERT_BEFORE, "*free_cfg", 1); +} + + /* Implement `TARGET_OPTION_OVERRIDE'. */ static void @@ -411,6 +462,11 @@ avr_option_override (void) init_machine_status = avr_init_machine_status; avr_log_set_avr_log(); + + /* Register some avr-specific pass(es). There is no canonical place for + pass registration. This function is convenient. */ + + avr_register_passes (); } /* Function to set up the backend function structure. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2b3cf0e4c15..ecc4cc42b31 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-03-03 Georg-Johann Lay + + PR target/64331 + * gcc.target/avr/torture/pr64331.c: New test. + 2015-03-03 Martin Liska Jan Hubicka diff --git a/gcc/testsuite/gcc.target/avr/torture/pr64331.c b/gcc/testsuite/gcc.target/avr/torture/pr64331.c new file mode 100644 index 00000000000..1934ccfd294 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/pr64331.c @@ -0,0 +1,37 @@ +/* { dg-do run } */ + +typedef struct +{ + unsigned a, b; +} T2; + + +__attribute__((__noinline__, __noclone__)) +void foo2 (T2 *t, int x) +{ + if (x != t->a) + { + t->a = x; + + if (x && x == t->b) + t->a = 20; + } +} + + +T2 t; + +int main (void) +{ + t.a = 1; + t.b = 1234; + + foo2 (&t, 1234); + + if (t.a != 20) + __builtin_abort(); + + __builtin_exit (0); + + return 0; +}