Blame SOURCES/gcc7-pr80725.patch

9c2d31
2017-05-24  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>
9c2d31
9c2d31
	PR target/80725
9c2d31
	* config/s390/s390.c (s390_check_qrst_address): Check incoming
9c2d31
	address against address_operand predicate.
9c2d31
	* config/s390/s390.md ("*indirect_jump"): Swap alternatives.
9c2d31
9c2d31
	* gcc.target/s390/pr80725.c: New test.
9c2d31
9c2d31
--- gcc/config/s390/s390.c	(revision 248406)
9c2d31
+++ gcc/config/s390/s390.c	(revision 248407)
9c2d31
@@ -3102,6 +3102,9 @@ s390_check_qrst_address (char c, rtx op,
9c2d31
   struct s390_address addr;
9c2d31
   bool decomposed = false;
9c2d31
 
9c2d31
+  if (!address_operand (op, GET_MODE (op)))
9c2d31
+    return 0;
9c2d31
+
9c2d31
   /* This check makes sure that no symbolic address (except literal
9c2d31
      pool references) are accepted by the R or T constraints.  */
9c2d31
   if (s390_loadrelative_operand_p (op, NULL, NULL))
9c2d31
--- gcc/config/s390/s390.md	(revision 248406)
9c2d31
+++ gcc/config/s390/s390.md	(revision 248407)
9c2d31
@@ -9660,14 +9660,16 @@ (define_expand "indirect_jump"
9c2d31
     operands[0] = force_reg (Pmode, operands[0]);
9c2d31
 })
9c2d31
 
9c2d31
+; The first constraint must be an "extra address constraint" in order
9c2d31
+; to trigger address reloading in LRA/reload
9c2d31
 (define_insn "*indirect_jump"
9c2d31
   [(set (pc)
9c2d31
-	(match_operand 0 "address_operand" "a,ZR"))]
9c2d31
+	(match_operand 0 "address_operand" "ZR,a"))]
9c2d31
  ""
9c2d31
  "@
9c2d31
-  br\t%0
9c2d31
-  b\t%a0"
9c2d31
- [(set_attr "op_type" "RR,RX")
9c2d31
+  b\t%a0
9c2d31
+  br\t%0"
9c2d31
+ [(set_attr "op_type" "RX,RR")
9c2d31
   (set_attr "type"  "branch")
9c2d31
   (set_attr "atype" "agen")
9c2d31
   (set_attr "cpu_facility" "*")])
9c2d31
--- gcc/testsuite/gcc.target/s390/pr80725.c	(nonexistent)
9c2d31
+++ gcc/testsuite/gcc.target/s390/pr80725.c	(revision 248407)
9c2d31
@@ -0,0 +1,26 @@
9c2d31
+/* Regression test for PR/80725.  */
9c2d31
+
9c2d31
+/* { dg-do compile } */
9c2d31
+/* { dg-options "-O2 -march=zEC12" } */
9c2d31
+
9c2d31
+int a, e;
9c2d31
+const char b;
9c2d31
+char c;
9c2d31
+const int d;
9c2d31
+void bar (short);
9c2d31
+
9c2d31
+void
9c2d31
+foo (int x, int y)
9c2d31
+{
9c2d31
+  long f = d;
9c2d31
+  short g = 0;
9c2d31
+  while (e)
9c2d31
+    while (a < x)
9c2d31
+      {
9c2d31
+	if (y)
9c2d31
+	  goto *d;
9c2d31
+	g = b | b + g;
9c2d31
+	bar (g);
9c2d31
+	c = (char) (long) foo;
9c2d31
+      }
9c2d31
+}