diff mbox

[committed] Fix memory constraint issue on PA

Message ID BLU437-SMTP8968D04E9FDEB17B8D0140975A0@phx.gbl
State New
Headers show

Commit Message

John David Anglin Jan. 3, 2015, 7:34 p.m. UTC
The attached change fixes a memory constraint issue found building the asterisk package on hppa-linux:
http://buildd.debian-ports.org/status/fetch.php?pkg=asterisk&arch=hppa&ver=1%3A13.1.0%7Edfsg-1&stamp=1420088700

The problem was  the `m' constraint allowed reload to substitute a register indexed memory form which is
invalid for store instructions.  This wasn't detected by the predicate but it was detected by the assembler.

The patch changes to using the `Q' constraint which doesn't allow the register indexed memory form.  The
predicate was also tightened to reject the register indexed memory and LO_SUM DLT memory address
forms that are unsuitable for stores on hppa.

Tested on hppa-unknown-linux-gnu, hppa2.0w-hp-hpux11.11 and hppa64-hp-hpux11.11 with no objserved
regressions.  Committed to trunk and 4.9 branch.

Dave
--
John David Anglin	dave.anglin@bell.net
2015-01-03  John David Anglin  <danglin@gcc.gnu.org>

	* config/pa/pa.md (decrement_and_branch_until_zero): Use `Q' constraint
	instead of `m' constraint.  Likewise for unnamed movb comparison
	patterns using reg_before_reload_operand predicate.
	* config/pa/predicates.md (reg_before_reload_operand): Tighten
	predicate to reject register index and LO_SUM DLT memory forms
	after reload.
diff mbox

Patch

Index: config/pa/pa.md
===================================================================
--- config/pa/pa.md	(revision 219114)
+++ config/pa/pa.md	(working copy)
@@ -8922,7 +8922,7 @@ 
 ;; strength reduction is used.  It is actually created when the instruction
 ;; combination phase combines the special loop test.  Since this insn
 ;; is both a jump insn and has an output, it must deal with its own
-;; reloads, hence the `m' constraints.  The `!' constraints direct reload
+;; reloads, hence the `Q' constraints.  The `!' constraints direct reload
 ;; to not choose the register alternatives in the event a reload is needed.
 (define_insn "decrement_and_branch_until_zero"
   [(set (pc)
@@ -8929,7 +8929,7 @@ 
 	(if_then_else
 	  (match_operator 2 "comparison_operator"
 	   [(plus:SI
-	      (match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*m")
+	      (match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*Q")
 	      (match_operand:SI 1 "int5_operand" "L,L,L"))
 	    (const_int 0)])
 	  (label_ref (match_operand 3 "" ""))
@@ -9018,7 +9018,7 @@ 
 	   [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
 	  (label_ref (match_operand 3 "" ""))
 	  (pc)))
-   (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*m,!*q")
+   (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
 	(match_dup 1))]
   ""
 "* return pa_output_movb (operands, insn, which_alternative, 0); "
@@ -9090,7 +9090,7 @@ 
 	   [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
 	  (pc)
 	  (label_ref (match_operand 3 "" ""))))
-   (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*m,!*q")
+   (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
 	(match_dup 1))]
   ""
 "* return pa_output_movb (operands, insn, which_alternative, 1); "
Index: config/pa/predicates.md
===================================================================
--- config/pa/predicates.md	(revision 219114)
+++ config/pa/predicates.md	(working copy)
@@ -528,20 +528,29 @@ 
 ;; This predicate is used for branch patterns that internally handle
 ;; register reloading.  We need to accept non-symbolic memory operands
 ;; after reload to ensure that the pattern is still valid if reload
-;; didn't find a hard register for the operand.
+;; didn't find a hard register for the operand.  We also reject index
+;; and lo_sum DLT address as these are invalid for move destinations.
 
 (define_predicate "reg_before_reload_operand"
   (match_code "reg,mem")
 {
+  rtx op0;
+
   if (register_operand (op, mode))
     return true;
 
-  if (reload_completed
-      && memory_operand (op, mode)
-      && !symbolic_memory_operand (op, mode))
-    return true;
+  if (!reload_in_progress && !reload_completed)
+    return false;
 
-  return false;
+  if (! MEM_P (op))
+    return false;
+
+  op0 = XEXP (op, 0);
+
+  return (memory_address_p (mode, op0)
+	  && !IS_INDEX_ADDR_P (op0)
+	  && !IS_LO_SUM_DLT_ADDR_P (op0)
+	  && !symbolic_memory_operand (op, mode));
 })
 
 ;; True iff OP is a register or const_0 operand for MODE.