From: Georg-Johann Lay Date: Tue, 3 Mar 2015 11:09:30 +0000 (+0000) Subject: re PR target/64331 (regcprop propagates registers noted as REG_DEAD) X-Git-Tag: releases/gcc-4.9.3~303 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cf37c877894bc369c0266b3c321be6bb7987310c;p=thirdparty%2Fgcc.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: r221142 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b85002d1bb17..ba28a0c4058c 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 Eric Botcazou * config/ia64/ia64.c (expand_vec_perm_interleave_2): Use gen_raw_REG @@ -23,7 +32,7 @@ 2015-02-27 Andrew Pinski Naveen H.S - + * config/aarch64/aarch64.c (*aarch64_load_symref_appropriately): Check whether the destination of SYMBOL_SMALL_TPREL is Pmode. diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 5ee3e1ce9b73..3130c0cf0b26 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -51,6 +51,8 @@ #include "target-def.h" #include "params.h" #include "df.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)) @@ -285,6 +287,58 @@ 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 + false, // has_gate + true, // has_execute + TV_DF_SCAN, // tv_id + 0, // properties_required + 0, // properties_provided + 0, // properties_destroyed + 0, // todo_flags_start + // todo_flags_finish + TODO_df_finish | TODO_verify_rtl_sharing | TODO_verify_flow +}; + + +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; + } + + unsigned int execute (void) + { + 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 @@ -346,6 +400,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 bb5d5455534f..3da05efe29d7 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 Thomas Preud'homme Backport from mainline 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 000000000000..1934ccfd2947 --- /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; +}