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]

[PATCH] Avoid LHS paradoxical subregs in make_extranction unless TRULY_NOOP_TRUNCATION


This is the combine counterpart of the expand changes to avoid:

(set (zero_extract:DI (subreg:DI (reg:SI A)) 3 29) ...)

patterns on !TRULY_NOOP_TRUNCATION(SI, DI) targets.  This pattern has an
implicit truncation that is invalid if DI->SI truncation requires an actual
instruction.

The bug was uncovered by my next patch that transforms (and (truncate)) into
(truncate (and)).  With that change for gcc.target/mips/ins-2.c we transform:

  (set (reg/v:SI 195 [ s ])
      (ior:SI (and:SI (reg/v:SI 195 [ s ])
              (const_int 536870911 [0x1fffffff]))
          (ashift:SI (truncate:SI (reg/v:DI 196 [ a+-4 ]))
              (const_int 29 [0x1d]))))
  
into:

  (set (zero_extract:DI (subreg:DI (reg/v:SI 195 [ s ]) 0)
          (const_int 3 [0x3])
          (const_int 29 [0x1d]))
      (reg/v:DI 196 [ a+-4 ]))

So far we didn't do this because the RHS is not simplified leading to:

  Trying 7, 8 -> 9:
  Failed to match this instruction:
  (set (zero_extract:DI (subreg:DI (reg/v:SI 195 [ s ]) 0)
          (const_int 3 [0x3])
          (const_int 29 [0x1d]))
      (subreg:DI (and:SI (truncate:SI (reg/v:DI 196 [ a+-4 ]))
              (const_int 7 [0x7])) 0))

Ultimately we want the above to be transformed into:

  (set (zero_extract:SI (reg:SI A) 3 29) ...)

, which is valid on MIPS64r2.  But one step at a time...

Boostrapped and regstested on mips64octeon-linux and regtested on
mipsisa64r2-elf.

OK to install?

Adam


	* combine.c (make_extraction): Check TRULY_NOOP_TRUNCATION before
	creating LHS paradoxical subregs.  Fix surrounding returns to
	use NULL_RTX rather than 0.

Index: gcc/combine.c
===================================================================
--- gcc.orig/combine.c	2009-06-30 12:06:41.000000000 -0700
+++ gcc/combine.c	2009-06-30 12:22:10.000000000 -0700
@@ -6692,18 +6692,25 @@ make_extraction (enum machine_mode mode,
       inner = adjust_address_nv (inner, wanted_inner_mode, offset);
     }
 
-  /* If INNER is not memory, we can always get it into the proper mode.  If we
-     are changing its mode, POS must be a constant and smaller than the size
-     of the new mode.  */
+  /* If INNER is not memory, get it into the proper mode.  If we are changing
+     its mode, POS must be a constant and smaller than the size of the new
+     mode.  */
   else if (!MEM_P (inner))
     {
+      /* On the LHS, don't create paradoxical subregs implicitely truncating
+	 the register unless TRULY_NOOP_TRUNCATION.  */
+      if (in_dest
+	  && !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE (inner)),
+				     GET_MODE_BITSIZE (wanted_inner_mode)))
+	return NULL_RTX;
+
       if (GET_MODE (inner) != wanted_inner_mode
 	  && (pos_rtx != 0
 	      || orig_pos + len > GET_MODE_BITSIZE (wanted_inner_mode)))
-	return 0;
+	return NULL_RTX;
 
       if (orig_pos < 0)
-	return 0;
+	return NULL_RTX;
 
       inner = force_to_mode (inner, wanted_inner_mode,
 			     pos_rtx


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