S/390: Merge movdi_larl into movdi_64
authorIlya Leoshkevich <iii@linux.ibm.com>
Thu, 25 Oct 2018 14:23:31 +0000 (14:23 +0000)
committerIlya Leoshkevich <iii@gcc.gnu.org>
Thu, 25 Oct 2018 14:23:31 +0000 (14:23 +0000)
Consider the following RTL:

(insn (set (mem/f/c:DI (reg/f:DI 60))
           (const:DI (plus:DI (symbol_ref:DI ("*.LANCHOR0"))
                              (const_int 8)))))

generated by cse2 pass.  It is matched to movdi_64, resulting in
the following inefficient code:

larl %r5,.L6 # Load literal pool@
lg %r1,.L7-.L6(%r5) # Load .LANCHOR0+8
stgrl %r1,.LANCHOR0
br %r14

Matching it to movdi_larl improves the code, eliminating one
instruction and the literal pool entry:

larl %r1,.LANCHOR0+8
stgrl %r1,.LANCHOR0
br %r14

Taking it one step further, there is no reason to keep movdi_64 and
movdi_larl separate, since this could potentially improve code in other
ways by giving lra one more alternative to choose from.

gcc/ChangeLog:

2018-10-25  Ilya Leoshkevich  <iii@linux.ibm.com>

* config/s390/constraints.md (ZL): New constraint.
* config/s390/s390.c (legitimate_pic_operand_p): Accept LARL
operands.
* config/s390/s390.md (movdi_larl): Remove.
(movdi_64): Add the LARL alternative.

gcc/testsuite/ChangeLog:

2018-10-25  Ilya Leoshkevich  <iii@linux.ibm.com>

* gcc.target/s390/global-array-almost-huge-element.c: New test.
* gcc.target/s390/global-array-almost-negative-huge-element.c: New test.
* gcc.target/s390/global-array-element-pic.c: New test.
* gcc.target/s390/global-array-even-element.c: New test.
* gcc.target/s390/global-array-huge-element.c: New test.
* gcc.target/s390/global-array-negative-huge-element.c: New test.
* gcc.target/s390/global-array-odd-element.c: New test.

From-SVN: r265490

12 files changed:
gcc/ChangeLog
gcc/config/s390/constraints.md
gcc/config/s390/s390.c
gcc/config/s390/s390.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/s390/global-array-almost-huge-element.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/global-array-almost-negative-huge-element.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/global-array-element-pic.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/global-array-even-element.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/global-array-huge-element.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/global-array-negative-huge-element.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/global-array-odd-element.c [new file with mode: 0644]

index 00ba522e43942e2614ae440807430815f402814d..22db60649df8952345d1c01efd16d35d60be56e5 100644 (file)
@@ -3,6 +3,14 @@
        * tree-if-conv.c: Include tree-ssa-sccvn.h.
        (tree_if_conversion): Run CSE on the if-converted loop body.
 
+2018-10-25  Ilya Leoshkevich  <iii@linux.ibm.com>
+
+       * config/s390/constraints.md (ZL): New constraint.
+       * config/s390/s390.c (legitimate_pic_operand_p): Accept LARL
+       operands.
+       * config/s390/s390.md (movdi_larl): Remove.
+       (movdi_64): Add the LARL alternative.
+
 2018-10-25  Ilya Leoshkevich  <iii@linux.ibm.com>
 
        PR bootstrap/87747
index b8ba8510096caf3acc829ee17cec647c1be42dfb..63c7fd368bec334ba6288a4dce17ef4f5a25a894 100644 (file)
@@ -89,6 +89,7 @@
 ;;    ZR -- Pointer with index register and short displacement.
 ;;    ZS -- Pointer without index register but with long displacement.
 ;;    ZT -- Pointer with index register and long displacement.
+;;    ZL -- LARL operand when in 64-bit mode, otherwise nothing.
 ;;
 ;;
 
 (define_address_constraint "ZT"
   "Pointer with index register and long displacement."
   (match_test "s390_mem_constraint (\"ZT\", op)"))
+
+(define_constraint "ZL"
+  "LARL operand when in 64-bit mode, otherwise nothing."
+  (match_test "TARGET_64BIT && larl_operand (op, VOIDmode)"))
index ae28a36881db6af0945fab78150587ce4ba77816..762c6bff07ba22dac44604560f561169f6e20b4b 100644 (file)
@@ -3859,6 +3859,10 @@ legitimate_pic_operand_p (rtx op)
   if (!SYMBOLIC_CONST (op))
     return 1;
 
+  /* Accept addresses that can be expressed relative to (pc).  */
+  if (larl_operand (op, VOIDmode))
+    return 1;
+
   /* Reject everything else; must be handled
      via emit_symbolic_move.  */
   return 0;
index 3bd18acb456d133c4aec929b499d78515d3e9011..e4049c254063d452087e6659d6798e3c0dbcc0a2 100644 (file)
     emit_symbolic_move (operands);
 })
 
-(define_insn "*movdi_larl"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-        (match_operand:DI 1 "larl_operand" "X"))]
-  "TARGET_64BIT
-   && !FP_REG_P (operands[0])"
-  "larl\t%0,%1"
-   [(set_attr "op_type" "RIL")
-    (set_attr "type"    "larl")
-    (set_attr "z10prop" "z10_super_A1")])
-
 (define_insn "*movdi_64"
   [(set (match_operand:DI 0 "nonimmediate_operand"
-         "=d,    d,    d,    d,    d, d,    d,    d,f,d,d,d,d,d,T,!*f,!*f,!*f,!R,!T,b,Q,d,t,Q,t,v,v,v,d,v,R")
+         "=d,    d,    d,    d,    d, d,    d,    d,f,d,d,d,d,d,T,!*f,!*f,!*f,!R,!T,b,Q,d,t,Q,t,v,v,v,d,v,R,d")
         (match_operand:DI 1 "general_operand"
-         " K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,L,b,d,T,d, *f,  R,  T,*f,*f,d,K,t,d,t,Q,K,v,d,v,R,v"))]
+         " K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,L,b,d,T,d, *f,  R,  T,*f,*f,d,K,t,d,t,Q,K,v,d,v,R,v,ZL"))]
   "TARGET_ZARCH"
   "@
    lghi\t%0,%h1
    vlvgg\t%v0,%1,0
    vlgvg\t%0,%v1,0
    vleg\t%v0,%1,0
-   vsteg\t%v1,%0,0"
+   vsteg\t%v1,%0,0
+   larl\t%0,%1"
   [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RIL,RRE,RXY,
-                        RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,VRI,VRR,VRS,VRS,VRX,VRX")
+                        RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,VRI,VRR,VRS,VRS,
+                        VRX,VRX,RIL")
    (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,larl,lr,load,store,
                      floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*,*,
-                     *,*,*,*,*,*,*")
+                     *,*,*,*,*,*,*,larl")
    (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,longdisp,
                              z10,*,*,*,*,*,longdisp,*,longdisp,
-                             z10,z10,*,*,*,*,vx,vx,vx,vx,vx,vx")
+                             z10,z10,*,*,*,*,vx,vx,vx,vx,vx,vx,*")
    (set_attr "z10prop" "z10_fwd_A1,
                         z10_fwd_E1,
                         z10_fwd_E1,
                         *,
                         *,
                         *,
-                        *,*,*,*,*,*,*")
+                        *,*,*,*,*,*,*,
+                        z10_super_A1")
 ])
 
 (define_split
index cdda13204d3ed649cbd3b38a1e560a1841c94866..ef5adb8f9261dc15fc5c1dcd446be2bd3aa590ed 100644 (file)
@@ -1,3 +1,13 @@
+2018-10-25  Ilya Leoshkevich  <iii@linux.ibm.com>
+
+       * gcc.target/s390/global-array-almost-huge-element.c: New test.
+       * gcc.target/s390/global-array-almost-negative-huge-element.c: New test.
+       * gcc.target/s390/global-array-element-pic.c: New test.
+       * gcc.target/s390/global-array-even-element.c: New test.
+       * gcc.target/s390/global-array-huge-element.c: New test.
+       * gcc.target/s390/global-array-negative-huge-element.c: New test.
+       * gcc.target/s390/global-array-odd-element.c: New test.
+
 2018-10-25  Jan Hubicka  <jh@suse.cz>
 
        * g++.dg/lto/odr-1_0.C: New test.
diff --git a/gcc/testsuite/gcc.target/s390/global-array-almost-huge-element.c b/gcc/testsuite/gcc.target/s390/global-array-almost-huge-element.c
new file mode 100644 (file)
index 0000000..28e4ccd
--- /dev/null
@@ -0,0 +1,12 @@
+/* Test the maximum possible LARL offset.  */
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+extern char a[] __attribute__ ((aligned (2)));
+extern char *b;
+
+void almost_huge()
+{
+  b = a + 0x7ffffffeULL;
+  /* { dg-final { scan-assembler {(?n)\n\tlarl\t%r\d+,a\+2147483646\n} } } */
+}
diff --git a/gcc/testsuite/gcc.target/s390/global-array-almost-negative-huge-element.c b/gcc/testsuite/gcc.target/s390/global-array-almost-negative-huge-element.c
new file mode 100644 (file)
index 0000000..0012ceb
--- /dev/null
@@ -0,0 +1,12 @@
+/* Test the minimum LARL offset.  */
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+extern char a[] __attribute__ ((aligned (2)));
+extern char *b;
+
+void almost_negative_huge()
+{
+  b = a - 0x80000000ULL;
+  /* { dg-final { scan-assembler {(?n)\n\tlarl\t%r\d+,a-2147483648\n} } } */
+}
diff --git a/gcc/testsuite/gcc.target/s390/global-array-element-pic.c b/gcc/testsuite/gcc.target/s390/global-array-element-pic.c
new file mode 100644 (file)
index 0000000..7872120
--- /dev/null
@@ -0,0 +1,13 @@
+/* Test accesses to global array elements in PIC code.  */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fPIC" } */
+
+extern char a[] __attribute__ ((aligned (2)));
+extern char *b;
+
+void c()
+{
+  b = a + 4;
+  /* { dg-final { scan-assembler {(?n)\n\tlarl\t%r\d+,a@GOTENT\n} } } */
+  /* { dg-final { scan-assembler-not {(?n)\n\tlarl\t%r\d+,a[^@]} } } */
+}
diff --git a/gcc/testsuite/gcc.target/s390/global-array-even-element.c b/gcc/testsuite/gcc.target/s390/global-array-even-element.c
new file mode 100644 (file)
index 0000000..5737f7e
--- /dev/null
@@ -0,0 +1,12 @@
+/* Test accesses to even global array elements.  */
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+extern char a[] __attribute__ ((aligned (2)));
+extern char *b;
+
+void even()
+{
+  b = a + 4;
+  /* { dg-final { scan-assembler {(?n)\n\tlarl\t%r\d+,a\+4\n} } } */
+}
diff --git a/gcc/testsuite/gcc.target/s390/global-array-huge-element.c b/gcc/testsuite/gcc.target/s390/global-array-huge-element.c
new file mode 100644 (file)
index 0000000..d4aad57
--- /dev/null
@@ -0,0 +1,12 @@
+/* Test minimum invalid LARL offset.  */
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+extern char a[] __attribute__ ((aligned (2)));
+extern char *b;
+
+void huge()
+{
+  b = a + 0x80000000ULL;
+  /* { dg-final { scan-assembler-not {(?n)\n\tlarl\t%r\d+,a} } } */
+}
diff --git a/gcc/testsuite/gcc.target/s390/global-array-negative-huge-element.c b/gcc/testsuite/gcc.target/s390/global-array-negative-huge-element.c
new file mode 100644 (file)
index 0000000..bd72d01
--- /dev/null
@@ -0,0 +1,12 @@
+/* Test maximum invalid LARL offset.  */
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+extern char a[] __attribute__ ((aligned (2)));
+extern char *b;
+
+void negative_huge()
+{
+  b = a - 0x80000004ULL;
+  /* { dg-final { scan-assembler-not {(?n)\n\tlarl\t%r\d+,a} } } */
+}
diff --git a/gcc/testsuite/gcc.target/s390/global-array-odd-element.c b/gcc/testsuite/gcc.target/s390/global-array-odd-element.c
new file mode 100644 (file)
index 0000000..84a65e5
--- /dev/null
@@ -0,0 +1,12 @@
+/* Test accesses to odd global array elements.  */
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+extern char a[] __attribute__ ((aligned (2)));
+extern char *b;
+
+void odd()
+{
+  b = a + 1;
+  /* { dg-final { scan-assembler-not {(?n)\n\tlarl\t%r\d+,a} } } */
+}