This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[committed] Fix target/17565: asms in delay slots


The MIPS port was allowing asms to be put into delay slots if the
compiler guesses they are only one instruction long.  This is wrong
because of the possibility of it containing macros.

The problem can be reproduced as an assembler warning
in the following testcase:

int foo (int n)
{
  register int k asm ("$16") = n;
  if (k > 0)
    {
      bar ();
      asm ("li %0,0x12345678" : "=r" (k));
    }
  return k;
}

because the multi-instruction asm statement goes into the delay
slot of the call to bar().

This is reduced from a much more serious linux problem.  Linux is fond
of using empty asm statements, and since gcc estimates empty asms to be
one instruction long, they too might be put into delay slots.  This
actually has the effect of putting the following instruction into the
delay slot instead.  Since there's no assembler warning, the problem was
only detected as a run-time failure.

The fix is simple: set the asm value of "can_delay" to "no".
Tested on mipsisa64-elf, applied to mainline.

This problem goes back to at least 2.95, so it isn't technically a
regression.  On the other hand, it's the kind of bug that could trigger
for different types of code in different releases, so I'm sure there's
a testcase that fails (say) in 3.4 and not in 2.95.  Will probably ask
Mark for permission to backport to 3.4.

Richard


	PR target/17565
	* config/mips/mips.md (define_asm_attributes): Set can_delay to no.

testsuite/
	* gcc.target/mips/asm-1.c: New test.

Index: config/mips/mips.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.md,v
retrieving revision 1.306
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.306 mips.md
*** config/mips/mips.md	13 Sep 2004 19:32:05 -0000	1.306
--- config/mips/mips.md	20 Sep 2004 06:52:31 -0000
*************** (define_attr "may_clobber_hilo" "no,yes"
*** 310,316 ****
  
  ;; Describe a user's asm statement.
  (define_asm_attributes
!   [(set_attr "type" "multi")])
  
  ;; This mode macro allows 32-bit and 64-bit GPR patterns to be generated
  ;; from the same template.
--- 310,317 ----
  
  ;; Describe a user's asm statement.
  (define_asm_attributes
!   [(set_attr "type" "multi")
!    (set_attr "can_delay" "no")])
  
  ;; This mode macro allows 32-bit and 64-bit GPR patterns to be generated
  ;; from the same template.
Index: testsuite/gcc.target/mips/asm-1.c
===================================================================
RCS file: testsuite/gcc.target/mips/asm-1.c
diff -N testsuite/gcc.target/mips/asm-1.c
*** testsuite/gcc.target/mips/asm-1.c	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.target/mips/asm-1.c	20 Sep 2004 06:52:31 -0000
***************
*** 0 ****
--- 1,14 ----
+ /* PR target/17565.  GCC used to put the asm into the delay slot
+    of the call.  */
+ /* { dg-do assemble } */
+ /* { dg-options "-O" } */
+ int foo (int n)
+ {
+   register int k asm ("$16") = n;
+   if (k > 0)
+     {
+       bar ();
+       asm ("li %0,0x12345678" : "=r" (k));
+     }
+   return k;
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]