final.c (shorten_branches): Do not align labels for jump tables.
authorMark Mitchell <mark@codesourcery.com>
Sat, 23 May 2009 17:56:14 +0000 (17:56 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Sat, 23 May 2009 17:56:14 +0000 (17:56 +0000)
* final.c (shorten_branches): Do not align labels for jump tables.
(final_scan_insn): Use JUMP_TABLE_DATA_P.

* gcc.dg/falign-labels-1.c: New test.

Co-Authored-By: Maxim Kuvyrkov <maxim@codesourcery.com>
From-SVN: r147824

gcc/ChangeLog
gcc/final.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/falign-labels-1.c [new file with mode: 0644]

index e64c72e..6cdbee7 100644 (file)
@@ -1,3 +1,8 @@
+2009-05-23  Mark Mitchell  <mark@codesourcery.com>
+
+       * final.c (shorten_branches): Do not align labels for jump tables.
+       (final_scan_insn): Use JUMP_TABLE_DATA_P.
+
 2009-05-23  Eric Botcazou  <ebotcazou@adacore.com>
 
        * doc/passes.texi: Standardize spelling of RTL, Tree and Tree SSA.
index 3c2e364..2f68ee8 100644 (file)
@@ -901,6 +901,7 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
       if (LABEL_P (insn))
        {
          rtx next;
+         bool next_is_jumptable;
 
          /* Merge in alignments computed by compute_alignments.  */
          log = LABEL_TO_ALIGNMENT (insn);
@@ -910,31 +911,30 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
              max_skip = LABEL_TO_MAX_SKIP (insn);
            }
 
-         log = LABEL_ALIGN (insn);
-         if (max_log < log)
+         next = next_nonnote_insn (insn);
+         next_is_jumptable = next && JUMP_TABLE_DATA_P (next);
+         if (!next_is_jumptable)
            {
-             max_log = log;
-             max_skip = LABEL_ALIGN_MAX_SKIP;
+             log = LABEL_ALIGN (insn);
+             if (max_log < log)
+               {
+                 max_log = log;
+                 max_skip = LABEL_ALIGN_MAX_SKIP;
+               }
            }
-         next = next_nonnote_insn (insn);
          /* ADDR_VECs only take room if read-only data goes into the text
             section.  */
-         if (JUMP_TABLES_IN_TEXT_SECTION
-             || readonly_data_section == text_section)
-           if (next && JUMP_P (next))
-             {
-               rtx nextbody = PATTERN (next);
-               if (GET_CODE (nextbody) == ADDR_VEC
-                   || GET_CODE (nextbody) == ADDR_DIFF_VEC)
-                 {
-                   log = ADDR_VEC_ALIGN (next);
-                   if (max_log < log)
-                     {
-                       max_log = log;
-                       max_skip = LABEL_ALIGN_MAX_SKIP;
-                     }
-                 }
-             }
+         if ((JUMP_TABLES_IN_TEXT_SECTION
+              || readonly_data_section == text_section)
+             && next_is_jumptable)
+           {
+             log = ADDR_VEC_ALIGN (next);
+             if (max_log < log)
+               {
+                 max_log = log;
+                 max_skip = LABEL_ALIGN_MAX_SKIP;
+               }
+           }
          LABEL_TO_ALIGNMENT (insn) = max_log;
          LABEL_TO_MAX_SKIP (insn) = max_skip;
          max_log = 0;
@@ -2023,48 +2023,41 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
       app_disable ();
 
       next = next_nonnote_insn (insn);
-      if (next != 0 && JUMP_P (next))
+      /* If this label is followed by a jump-table, make sure we put
+        the label in the read-only section.  Also possibly write the
+        label and jump table together.  */
+      if (next != 0 && JUMP_TABLE_DATA_P (next))
        {
-         rtx nextbody = PATTERN (next);
-
-         /* If this label is followed by a jump-table,
-            make sure we put the label in the read-only section.  Also
-            possibly write the label and jump table together.  */
-
-         if (GET_CODE (nextbody) == ADDR_VEC
-             || GET_CODE (nextbody) == ADDR_DIFF_VEC)
-           {
 #if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)
-             /* In this case, the case vector is being moved by the
-                target, so don't output the label at all.  Leave that
-                to the back end macros.  */
+         /* In this case, the case vector is being moved by the
+            target, so don't output the label at all.  Leave that
+            to the back end macros.  */
 #else
-             if (! JUMP_TABLES_IN_TEXT_SECTION)
-               {
-                 int log_align;
+         if (! JUMP_TABLES_IN_TEXT_SECTION)
+           {
+             int log_align;
 
-                 switch_to_section (targetm.asm_out.function_rodata_section
-                                    (current_function_decl));
+             switch_to_section (targetm.asm_out.function_rodata_section
+                                (current_function_decl));
 
 #ifdef ADDR_VEC_ALIGN
-                 log_align = ADDR_VEC_ALIGN (next);
+             log_align = ADDR_VEC_ALIGN (next);
 #else
-                 log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
+             log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
 #endif
-                 ASM_OUTPUT_ALIGN (file, log_align);
-               }
-             else
-               switch_to_section (current_function_section ());
+             ASM_OUTPUT_ALIGN (file, log_align);
+           }
+         else
+           switch_to_section (current_function_section ());
 
 #ifdef ASM_OUTPUT_CASE_LABEL
-             ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
-                                    next);
+         ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
+                                next);
 #else
-             targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
+         targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
 #endif
 #endif
-             break;
-           }
+         break;
        }
       if (LABEL_ALT_ENTRY_P (insn))
        output_alternate_entry_point (file, insn);
index 6fc23ed..06d2dc3 100644 (file)
@@ -1,3 +1,8 @@
+2009-05-23  Mark Mitchell  <mark@codesourcery.com>
+           Maxim Kuvyrkov  <maxim@codesourcery.com>
+
+       * gcc.dg/falign-labels-1.c: New test.
+
 2009-05-23  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/specs/rep_clause3.ads: New test.
diff --git a/gcc/testsuite/gcc.dg/falign-labels-1.c b/gcc/testsuite/gcc.dg/falign-labels-1.c
new file mode 100644 (file)
index 0000000..1e96617
--- /dev/null
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+/* { dg-options "-falign-labels=8" { target { ! { m68k*-*-* || fido*-*-* } } } } */
+
+/* On ARMv7-A CPUs, this test resulted in incorrect code generation.
+   The code generated for the switch statement expected the jump table
+   to immediately follow the jump instruction, but -falign-labels
+   caused the label preceding the table to be aligned.  */
+/* M68K and fido only support -falign-labels argument <= 2.  */
+
+volatile int x;
+
+int main(void)
+{
+  int y;
+
+  x = 0;
+
+  switch(x)
+    {
+    case 0:
+      y = 2 * x;
+      break;
+    case 1:
+      y = -3 * x;
+      break;
+    case 2:
+      y = x + 5;
+      break;
+    case 3:
+      y = x - 7;
+      break;
+    default:
+      break;
+    }
+
+  x = y;
+
+  return 0;
+}