diff mbox

[SPARC] Fix PR bootstrap/66252

Message ID 12474632.5shVuavSYH@polaris
State New
Headers show

Commit Message

Eric Botcazou June 11, 2015, 3:59 p.m. UTC
This is the bootstrap comparison failure on the SPARC, triggered by a CCP 
change at the GIMPLE level exposing a latent issue in the back-end and 
resulting in the miscompilation of cse.c at -O2.  In fact it's just another 
instance of http://gcc.gnu.org/ml/gcc-patches/2012-07/msg00960.html so I have 
audited all the 32-bit DImode splitters and added earlyclobbers to most of 
them.  This will probably pessimize a little bit but the alternative would be 
to split into 3 instructions instead of 2 in problematic cases, at least for 
the arithmetic operations, so the benefit wouldn't be really obvious.

The patch also removes superfluous code for zero_extendsidi2_insn_sp32 (you 
can use a single order in all cases for SI->DI extension) and fixes a pasto in 
addx_extend_sp32 (present for more than 15 years, so the pattern has very 
likely never been used).  The twin pattern subx_extend_sp32 is OK.

Tested on SPARC/Solaris 10, applied on mainline, 5 and 4.9 branches.


2015-06-11  Eric Botcazou  <ebotcazou@adacore.com>

	PR bootstrap/66252
	* config/sparc/sparc.c (hard_regno_mode_classes): Add ??? comment.
	* config/sparc/sparc.md (*zero_extendsidi2_insn_sp32): Use single order.
	(*addx_extend_sp32): Fix pasto.
	(*subx_extend): Rename into...
	(*subx_extend_sp32): ...this.
	(*adddi3_extend_sp32): Add earlyclobber.
	(*subdi3_insn_sp32): Likewise.
	(*subdi3_extend_sp32): Likewise.
	(*and_not_di_sp32): Likewise.
	(*or_not_di_sp32): Likewise.
	(*xor_not_di_sp32): Likewise.
	(*negdi2_sp32): Likewise.
	(*one_cmpldi2_sp32): Likewise.
diff mbox

Patch

Index: config/sparc/sparc.md
===================================================================
--- config/sparc/sparc.md	(revision 224264)
+++ config/sparc/sparc.md	(working copy)
@@ -3045,30 +3045,10 @@  (define_insn_and_split "*zero_extendsidi
   "! TARGET_ARCH64"
   "#"
   "&& reload_completed"
-  [(set (match_dup 2) (match_dup 3))
-   (set (match_dup 4) (match_dup 5))]
-{
-  rtx dest1, dest2;
-
-  dest1 = gen_highpart (SImode, operands[0]);
-  dest2 = gen_lowpart (SImode, operands[0]);
-
-  /* Swap the order in case of overlap.  */
-  if (REGNO (dest1) == REGNO (operands[1]))
-    {
-      operands[2] = dest2;
-      operands[3] = operands[1];
-      operands[4] = dest1;
-      operands[5] = const0_rtx;
-    }
-  else
-    {
-      operands[2] = dest1;
-      operands[3] = const0_rtx;
-      operands[4] = dest2;
-      operands[5] = operands[1];
-    }
-}
+  [(set (match_dup 2) (match_dup 1))
+   (set (match_dup 3) (const_int 0))]
+  "operands[2] = gen_lowpart (SImode, operands[0]);
+   operands[3] = gen_highpart (SImode, operands[0]);"
   [(set_attr "length" "2")])
 
 ;; Simplify comparisons of extended values.
@@ -3760,7 +3740,7 @@  (define_insn_and_split "*addx_extend_sp3
                                (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
    (set (match_dup 4) (const_int 0))]
   "operands[3] = gen_lowpart (SImode, operands[0]);
-   operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
+   operands[4] = gen_highpart (SImode, operands[0]);"
   [(set_attr "length" "2")])
 
 (define_insn "*addx_extend_sp64"
@@ -3782,7 +3762,7 @@  (define_insn "*addxc_trunc_sp64_vis3"
   [(set_attr "type" "ialuX")])
 
 (define_insn_and_split "*adddi3_extend_sp32"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=&r")
         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
                  (match_operand:DI 2 "register_operand" "r")))
    (clobber (reg:CC CC_REG))]
@@ -3881,7 +3861,7 @@  (define_expand "subdi3"
 })
 
 (define_insn_and_split "*subdi3_insn_sp32"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=&r")
 	(minus:DI (match_operand:DI 1 "register_operand" "r")
 		  (match_operand:DI 2 "arith_double_operand" "rHI")))
    (clobber (reg:CC CC_REG))]
@@ -3937,7 +3917,7 @@  (define_insn "*subx_extend_sp64"
   "subx\t%r1, %2, %0"
   [(set_attr "type" "ialuX")])
 
-(define_insn_and_split "*subx_extend"
+(define_insn_and_split "*subx_extend_sp32"
   [(set (match_operand:DI 0 "register_operand" "=r")
 	(zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
                                             (match_operand:SI 2 "arith_operand" "rI"))
@@ -3953,7 +3933,7 @@  (define_insn_and_split "*subx_extend"
   [(set_attr "length" "2")])
 
 (define_insn_and_split "*subdi3_extend_sp32"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=&r")
       (minus:DI (match_operand:DI 1 "register_operand" "r")
                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
    (clobber (reg:CC CC_REG))]
@@ -4757,7 +4737,7 @@  (define_split
 })
 
 (define_insn_and_split "*and_not_di_sp32"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=&r")
 	(and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
 		(match_operand:DI 2 "register_operand" "r")))]
   "! TARGET_ARCH64"
@@ -4834,7 +4814,7 @@  (define_split
 })
 
 (define_insn_and_split "*or_not_di_sp32"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=&r")
 	(ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
 		(match_operand:DI 2 "register_operand" "r")))]
   "! TARGET_ARCH64"
@@ -4959,7 +4939,7 @@  (define_split
 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
 ;; Combine now canonicalizes to the rightmost expression.
 (define_insn_and_split "*xor_not_di_sp32"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=&r")
 	(not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
 			(match_operand:DI 2 "register_operand" "r"))))]
   "! TARGET_ARCH64"
@@ -5162,7 +5142,7 @@  (define_expand "negdi2"
 })
 
 (define_insn_and_split "*negdi2_sp32"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=&r")
 	(neg:DI (match_operand:DI 1 "register_operand" "r")))
    (clobber (reg:CC CC_REG))]
   "! TARGET_ARCH64"
@@ -5237,7 +5217,7 @@  (define_expand "one_cmpldi2"
   "")
 
 (define_insn_and_split "*one_cmpldi2_sp32"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand" "=&r")
 	(not:DI (match_operand:DI 1 "register_operand" "r")))]
   "! TARGET_ARCH64"
   "#"
Index: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c	(revision 224264)
+++ config/sparc/sparc.c	(working copy)
@@ -4733,10 +4733,14 @@  enum sparc_mode_class {
 #define CCFP_MODES (1 << (int) CCFP_MODE)
 
 /* Value is 1 if register/mode pair is acceptable on sparc.
+
    The funny mixture of D and T modes is because integer operations
    do not specially operate on tetra quantities, so non-quad-aligned
    registers can hold quadword quantities (except %o4 and %i4 because
-   they cross fixed registers).  */
+   they cross fixed registers).
+
+   ??? Note that, despite the settings, non-double-aligned parameter
+   registers can hold double-word quantities in 32-bit mode.  */
 
 /* This points to either the 32 bit or the 64 bit version.  */
 const int *hard_regno_mode_classes;