re PR target/64331 (regcprop propagates registers noted as REG_DEAD)
authorGeorg-Johann Lay <avr@gjlay.de>
Tue, 3 Mar 2015 11:25:04 +0000 (11:25 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Tue, 3 Mar 2015 11:25:04 +0000 (11:25 +0000)
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

gcc/ChangeLog
gcc/config/avr/avr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/avr/torture/pr64331.c [new file with mode: 0644]

index aeeda83fd07cf2597f87bb451e05003f76839654..9eef7746f5f00c67491237a04e1879af8a54fbe2 100644 (file)
@@ -1,3 +1,12 @@
+2015-03-03  Georg-Johann Lay  <avr@gjlay.de>
+
+       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  <avr@gjlay.de>
 
        Fix various problems with specs file generation.
index 07d7bafd54a5683c4bc727c0d36d7a9f00ae7832..827b2800597f17915855bdda9d139ee30e43756b 100644 (file)
@@ -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.  */
index 2b3cf0e4c151bfb14429e0400eda496027fbb689..ecc4cc42b3134ff227d26b67b222d42a1a65f527 100644 (file)
@@ -1,3 +1,8 @@
+2015-03-03  Georg-Johann Lay  <avr@gjlay.de>
+
+       PR target/64331
+       * gcc.target/avr/torture/pr64331.c: New test.
+
 2015-03-03  Martin Liska  <mliska@suse.cz>
            Jan Hubicka   <hubicka@ucw.cz>
 
diff --git a/gcc/testsuite/gcc.target/avr/torture/pr64331.c b/gcc/testsuite/gcc.target/avr/torture/pr64331.c
new file mode 100644 (file)
index 0000000..1934ccf
--- /dev/null
@@ -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;
+}