Can insns be combined across UNSPEC_VOLATILE.?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

The attached tests fails on SH4 when compiled with:

-fstack-protector-all -Os -fpic -fnon-call-exceptions sp.c -fomit-frame-pointer -S -fno-regmove

The cause is that 2 insns have been combined by ira, despite an blockage insns, causing a spill failure for R0.

so we have before ira:

(set (reg:SI 3 r3 [174])
  (plus:SI (reg/f:SI 3 r3 [173]) (reg:SI 12 r12)))

(unspec_volatile [
            (const_int 0 [0x0])
        ] 0) 287 {blockage} (nil))

set (reg:SI 5 r5 [172])
        (mem/u/c:SI (reg:SI 3 r3 [174])

combined into

(set (reg/f:SI 2 r2 [172])
        (mem/u/c:SI (plus:SI (reg/f:SI 1 r1 [173])
                (reg:SI 12 r12))

Can I assume than the unspec_volatile should prevent that ? Quickly fixing the problem with the illustrative attached patch solves it.

Many thanks

Christian
Index: ira.c
===================================================================
--- ira.c	(revision 166230)
+++ ira.c	(working copy)
@@ -2304,6 +2304,18 @@
 	     only mark all destinations as having no known equivalence.  */
 	  if (set == 0)
 	    {
+	      if (GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE)
+		{
+		  int i;
+		  /*
+		   UNSPEC_VOLATILE is considered to use and clobber all hard 
+		   registers and all of memory.  This blocks insns from being
+		   combined across this point.
+		  */
+		  for (i = FIRST_PSEUDO_REGISTER; i < reg_equiv_init_size; i++)
+		    reg_equiv[i].replace = 0;
+		}
+
 	      note_stores (PATTERN (insn), no_equiv, NULL);
 	      continue;
 	    }
int
foo (int d, int rp)
{
  if (d == 0)
    if (rp == 0)
      return 1;

  return 0;
}


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux