[SPARC] Fix PR target/85196

Message ID 3387465.v20zVnNpNe@polaris
State New
Headers show
Series
  • [SPARC] Fix PR target/85196
Related show

Commit Message

Eric Botcazou April 6, 2018, 10:29 p.m.
This fixes a regression present on the 7 and 6 branches in the form of an ICE 
on an unrecognizable insn generated for a jump table in PIC mode.  It occurs 
because the index of the table is folded to a constant at RTL expansion time 
and not at the GIMPLE level (this pessimization is fixed on the mainline).

Tested on SPARC64/Linux, applied on all active branches.


2018-04-06  Eric Botcazou  <ebotcazou@adacore.com>

	PR target/85196
	* config/sparc/sparc.c (sparc_expand_move): Deal with symbolic operands
	based on LABEL_REF.  Remove useless assertion.
	(pic_address_needs_scratch): Fix formatting.
	(sparc_legitimize_pic_address): Minor tweaks.
	(sparc_delegitimize_address): Adjust assertion accordingly.
	* config/sparc/sparc.md (movsi_pic_label_ref): Change label_ref_operand
	into symbolic_operand.
	(movsi_high_pic_label_ref): Likewise.
	(movsi_lo_sum_pic_label_ref): Likewise.
	(movdi_pic_label_ref): Likewise.
	(movdi_high_pic_label_ref): Likewise.
	(movdi_lo_sum_pic_label_ref): Likewise.


2018-04-06  Eric Botcazou  <ebotcazou@adacore.com>
	
	* g++.dg/opt/pr85196.C: New test.

-- 
Eric Botcazou

Patch

Index: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c	(revision 259025)
+++ config/sparc/sparc.c	(working copy)
@@ -2236,7 +2236,7 @@  sparc_expand_move (machine_mode mode, rt
 	}
     }
 
-  /* Fixup TLS cases.  */
+  /* Fix up TLS cases.  */
   if (TARGET_HAVE_TLS
       && CONSTANT_P (operands[1])
       && sparc_tls_referenced_p (operands [1]))
@@ -2245,15 +2245,20 @@  sparc_expand_move (machine_mode mode, rt
       return false;
     }
 
-  /* Fixup PIC cases.  */
+  /* Fix up PIC cases.  */
   if (flag_pic && CONSTANT_P (operands[1]))
     {
       if (pic_address_needs_scratch (operands[1]))
 	operands[1] = sparc_legitimize_pic_address (operands[1], NULL_RTX);
 
       /* We cannot use the mov{si,di}_pic_label_ref patterns in all cases.  */
-      if (GET_CODE (operands[1]) == LABEL_REF
-	  && can_use_mov_pic_label_ref (operands[1]))
+      if ((GET_CODE (operands[1]) == LABEL_REF
+	   && can_use_mov_pic_label_ref (operands[1]))
+	  || (GET_CODE (operands[1]) == CONST
+	      && GET_CODE (XEXP (operands[1], 0)) == PLUS
+	      && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
+	      && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT
+	      && can_use_mov_pic_label_ref (XEXP (XEXP (operands[1], 0), 0))))
 	{
 	  if (mode == SImode)
 	    {
@@ -2263,7 +2268,6 @@  sparc_expand_move (machine_mode mode, rt
 
 	  if (mode == DImode)
 	    {
-	      gcc_assert (TARGET_ARCH64);
 	      emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
 	      return true;
 	    }
@@ -4280,10 +4284,11 @@  int
 pic_address_needs_scratch (rtx x)
 {
   /* An address which is a symbolic plus a non SMALL_INT needs a temp reg.  */
-  if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS
+  if (GET_CODE (x) == CONST
+      && GET_CODE (XEXP (x, 0)) == PLUS
       && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
-      && ! SMALL_INT (XEXP (XEXP (x, 0), 1)))
+      && !SMALL_INT (XEXP (XEXP (x, 0), 1)))
     return 1;
 
   return 0;
@@ -4750,16 +4755,15 @@  sparc_legitimize_tls_address (rtx addr)
 static rtx
 sparc_legitimize_pic_address (rtx orig, rtx reg)
 {
-  bool gotdata_op = false;
-
   if (GET_CODE (orig) == SYMBOL_REF
       /* See the comment in sparc_expand_move.  */
       || (GET_CODE (orig) == LABEL_REF && !can_use_mov_pic_label_ref (orig)))
     {
+      bool gotdata_op = false;
       rtx pic_ref, address;
       rtx_insn *insn;
 
-      if (reg == 0)
+      if (!reg)
 	{
 	  gcc_assert (can_create_pseudo_p ());
 	  reg = gen_reg_rtx (Pmode);
@@ -4770,8 +4774,7 @@  sparc_legitimize_pic_address (rtx orig,
 	  /* If not during reload, allocate another temp reg here for loading
 	     in the address, so that these instructions can be optimized
 	     properly.  */
-	  rtx temp_reg = (! can_create_pseudo_p ()
-			  ? reg : gen_reg_rtx (Pmode));
+	  rtx temp_reg = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : reg;
 
 	  /* Must put the SYMBOL_REF inside an UNSPEC here so that cse
 	     won't get confused into thinking that these two instructions
@@ -4787,6 +4790,7 @@  sparc_legitimize_pic_address (rtx orig,
 	      emit_insn (gen_movsi_high_pic (temp_reg, orig));
 	      emit_insn (gen_movsi_lo_sum_pic (temp_reg, temp_reg, orig));
 	    }
+
 	  address = temp_reg;
 	  gotdata_op = true;
 	}
@@ -4827,7 +4831,7 @@  sparc_legitimize_pic_address (rtx orig,
 	  && sparc_pic_register_p (XEXP (XEXP (orig, 0), 0)))
 	return orig;
 
-      if (reg == 0)
+      if (!reg)
 	{
 	  gcc_assert (can_create_pseudo_p ());
 	  reg = gen_reg_rtx (Pmode);
@@ -4935,7 +4939,11 @@  sparc_delegitimize_address (rtx x)
       && XINT (XEXP (XEXP (x, 1), 1), 1) == UNSPEC_MOVE_PIC_LABEL)
     {
       x = XVECEXP (XEXP (XEXP (x, 1), 1), 0, 0);
-      gcc_assert (GET_CODE (x) == LABEL_REF);
+      gcc_assert (GET_CODE (x) == LABEL_REF
+		  || (GET_CODE (x) == CONST
+		      && GET_CODE (XEXP (x, 0)) == PLUS
+		      && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF
+		      && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT));
     }
 
   return x;
Index: config/sparc/sparc.md
===================================================================
--- config/sparc/sparc.md	(revision 259025)
+++ config/sparc/sparc.md	(working copy)
@@ -1758,7 +1758,7 @@  (define_insn "movsi_pic_gotdata_op"
 
 (define_expand "movsi_pic_label_ref"
   [(set (match_dup 3) (high:SI
-     (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
+     (unspec:SI [(match_operand:SI 1 "symbolic_operand" "")
 		 (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
    (set (match_dup 4) (lo_sum:SI (match_dup 3)
      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
@@ -1784,7 +1784,7 @@  (define_expand "movsi_pic_label_ref"
 (define_insn "*movsi_high_pic_label_ref"
   [(set (match_operand:SI 0 "register_operand" "=r")
       (high:SI
-        (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
+        (unspec:SI [(match_operand:SI 1 "symbolic_operand" "")
 		    (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
   "flag_pic"
   "sethi\t%%hi(%a2-(%a1-.)), %0")
@@ -1792,7 +1792,7 @@  (define_insn "*movsi_high_pic_label_ref"
 (define_insn "*movsi_lo_sum_pic_label_ref"
   [(set (match_operand:SI 0 "register_operand" "=r")
       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
-        (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
+        (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")
 		    (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
   "flag_pic"
   "or\t%1, %%lo(%a3-(%a2-.)), %0")
@@ -1896,7 +1896,7 @@  (define_insn "*movdi_insn_sp64"
 
 (define_expand "movdi_pic_label_ref"
   [(set (match_dup 3) (high:DI
-     (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
+     (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")
                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
    (set (match_dup 4) (lo_sum:DI (match_dup 3)
      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
@@ -1922,7 +1922,7 @@  (define_expand "movdi_pic_label_ref"
 (define_insn "*movdi_high_pic_label_ref"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (high:DI
-          (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
+          (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")
                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
   "TARGET_ARCH64 && flag_pic"
   "sethi\t%%hi(%a2-(%a1-.)), %0")
@@ -1930,7 +1930,7 @@  (define_insn "*movdi_high_pic_label_ref"
 (define_insn "*movdi_lo_sum_pic_label_ref"
   [(set (match_operand:DI 0 "register_operand" "=r")
       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
-        (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
+        (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
   "TARGET_ARCH64 && flag_pic"
   "or\t%1, %%lo(%a3-(%a2-.)), %0")