re PR regression/63150 (FAIL: gcc.target/powerpc/pr53199.c scan-assembler-times *)
authorAlan Modra <amodra@gmail.com>
Mon, 16 Mar 2015 03:29:36 +0000 (13:59 +1030)
committerAlan Modra <amodra@gcc.gnu.org>
Mon, 16 Mar 2015 03:29:36 +0000 (13:59 +1030)
PR target/63150
gcc/
* config/rs6000/rs6000.md (bswapdi2): Remove one scratch reg.
Modify Z->r bswapdi splitter to use dest in place of scratch.
In r->Z and Z->r bswapdi splitter rename word_high, word_low
to word1, word2 and rearrange logic to suit.
(bswapdi2_64bit): Remove early clobber on Z->r alternative.
(bswapdi2_ldbrx): Likewise.  Remove '??' on r->r.
(bswapdi2_32bit): Remove early clobber on Z->r alternative.
Add one '?' on r->r.  Modify Z->r splitter to avoid need for
early clobber.
gcc/testsuite/
* gcc.target/powerpc/pr53199.c: Add extra functions.  Revert
2014-12-05 change.

From-SVN: r221445

gcc/ChangeLog
gcc/config/rs6000/rs6000.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/pr53199.c

index e87e5fccb73f44ee85d7f7b2ad42560d27edfbec..7f7297fe7694e346730e797ac0c858ab009923ce 100644 (file)
@@ -1,3 +1,16 @@
+2015-03-16  Alan Modra  <amodra@gmail.com>
+
+       PR target/63150
+       * config/rs6000/rs6000.md (bswapdi2): Remove one scratch reg.
+       Modify Z->r bswapdi splitter to use dest in place of scratch.
+       In r->Z and Z->r bswapdi splitter rename word_high, word_low
+       to word1, word2 and rearrange logic to suit.
+       (bswapdi2_64bit): Remove early clobber on Z->r alternative.
+       (bswapdi2_ldbrx): Likewise.  Remove '??' on r->r.
+       (bswapdi2_32bit): Remove early clobber on Z->r alternative.
+       Add one '?' on r->r.  Modify Z->r splitter to avoid need for
+       early clobber.
+
 2015-03-14  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/65369
index 22787e2f70e3f2a4c927330b508b59a0c696fc40..001884cbe58e226d6bab5dfdd27fa91ab15fcc3b 100644 (file)
                   (bswap:DI
                    (match_operand:DI 1 "reg_or_mem_operand" "")))
              (clobber (match_scratch:DI 2 ""))
-             (clobber (match_scratch:DI 3 ""))
-             (clobber (match_scratch:DI 4 ""))])]
+             (clobber (match_scratch:DI 3 ""))])]
   ""
 {
   if (!REG_P (operands[0]) && !REG_P (operands[1]))
 
 ;; Power7/cell has ldbrx/stdbrx, so use it directly
 (define_insn "*bswapdi2_ldbrx"
-  [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r")
+  [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
        (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
    (clobber (match_scratch:DI 2 "=X,X,&r"))
-   (clobber (match_scratch:DI 3 "=X,X,&r"))
-   (clobber (match_scratch:DI 4 "=X,X,&r"))]
+   (clobber (match_scratch:DI 3 "=X,X,&r"))]
   "TARGET_POWERPC64 && TARGET_LDBRX
    && (REG_P (operands[0]) || REG_P (operands[1]))"
   "@
 
 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
 (define_insn "*bswapdi2_64bit"
-  [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,&r")
+  [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
        (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
    (clobber (match_scratch:DI 2 "=&b,&b,&r"))
-   (clobber (match_scratch:DI 3 "=&r,&r,&r"))
-   (clobber (match_scratch:DI 4 "=&r,X,&r"))]
+   (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
   "TARGET_POWERPC64 && !TARGET_LDBRX
    && (REG_P (operands[0]) || REG_P (operands[1]))
    && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
        (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
-   (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
-   (clobber (match_operand:DI 4 "gpc_reg_operand" ""))]
+   (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
   [(const_int 0)]
   "
   rtx src    = operands[1];
   rtx op2    = operands[2];
   rtx op3    = operands[3];
-  rtx op4    = operands[4];
   rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
                                    BYTES_BIG_ENDIAN ? 4 : 0);
-  rtx op4_32 = simplify_gen_subreg (SImode, op4, DImode,
-                                   BYTES_BIG_ENDIAN ? 4 : 0);
+  rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
+                                    BYTES_BIG_ENDIAN ? 4 : 0);
   rtx addr1;
   rtx addr2;
-  rtx word_high;
-  rtx word_low;
+  rtx word1;
+  rtx word2;
 
   addr1 = XEXP (src, 0);
   if (GET_CODE (addr1) == PLUS)
       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
     }
 
+  word1 = change_address (src, SImode, addr1);
+  word2 = change_address (src, SImode, addr2);
+
   if (BYTES_BIG_ENDIAN)
     {
-      word_high = change_address (src, SImode, addr1);
-      word_low  = change_address (src, SImode, addr2);
+      emit_insn (gen_bswapsi2 (op3_32, word2));
+      emit_insn (gen_bswapsi2 (dest_32, word1));
     }
   else
     {
-      word_high = change_address (src, SImode, addr2);
-      word_low  = change_address (src, SImode, addr1);
+      emit_insn (gen_bswapsi2 (op3_32, word1));
+      emit_insn (gen_bswapsi2 (dest_32, word2));
     }
 
-  emit_insn (gen_bswapsi2 (op3_32, word_low));
-  emit_insn (gen_bswapsi2 (op4_32, word_high));
-  emit_insn (gen_ashldi3 (dest, op3, GEN_INT (32)));
-  emit_insn (gen_iordi3 (dest, dest, op4));
+  emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
+  emit_insn (gen_iordi3 (dest, dest, op3));
   DONE;
 }")
 
   [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
        (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
-   (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
-   (clobber (match_operand:DI 4 "" ""))]
+   (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
   "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
   [(const_int 0)]
   "
                                    BYTES_BIG_ENDIAN ? 4 : 0);
   rtx addr1;
   rtx addr2;
-  rtx word_high;
-  rtx word_low;
+  rtx word1;
+  rtx word2;
 
   addr1 = XEXP (dest, 0);
   if (GET_CODE (addr1) == PLUS)
       addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
     }
 
+  word1 = change_address (dest, SImode, addr1);
+  word2 = change_address (dest, SImode, addr2);
+
   emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
+
   if (BYTES_BIG_ENDIAN)
     {
-      word_high = change_address (dest, SImode, addr1);
-      word_low  = change_address (dest, SImode, addr2);
+      emit_insn (gen_bswapsi2 (word1, src_si));
+      emit_insn (gen_bswapsi2 (word2, op3_si));
     }
   else
     {
-      word_high = change_address (dest, SImode, addr2);
-      word_low  = change_address (dest, SImode, addr1);
+      emit_insn (gen_bswapsi2 (word2, src_si));
+      emit_insn (gen_bswapsi2 (word1, op3_si));
     }
-  emit_insn (gen_bswapsi2 (word_high, src_si));
-  emit_insn (gen_bswapsi2 (word_low, op3_si));
   DONE;
 }")
 
   [(set (match_operand:DI 0 "gpc_reg_operand" "")
        (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
    (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
-   (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
-   (clobber (match_operand:DI 4 "" ""))]
+   (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
   "TARGET_POWERPC64 && reload_completed"
   [(const_int 0)]
   "
 }")
 
 (define_insn "bswapdi2_32bit"
-  [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,&r")
+  [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
        (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
    (clobber (match_scratch:SI 2 "=&b,&b,X"))]
   "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
   if (GET_CODE (addr1) == PLUS)
     {
       emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
-      if (TARGET_AVOID_XFORM)
+      if (TARGET_AVOID_XFORM
+         || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
        {
          emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
          addr2 = op2;
       else
        addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
     }
-  else if (TARGET_AVOID_XFORM)
+  else if (TARGET_AVOID_XFORM
+          || REGNO (addr1) == REGNO (dest2))
     {
       emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
       addr2 = op2;
   word2 = change_address (src, SImode, addr2);
 
   emit_insn (gen_bswapsi2 (dest2, word1));
+  /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
+     thus allowing us to omit an early clobber on the output.  */
   emit_insn (gen_bswapsi2 (dest1, word2));
   DONE;
 }")
index 4c5d99528d81f3abe3001bd61bddad93efe290fa..9c8532aa05a9171616db09bb8ba63cb4740f2dd6 100644 (file)
@@ -1,3 +1,8 @@
+2015-03-16  Alan Modra  <amodra@gmail.com>
+
+       * gcc.target/powerpc/pr53199.c: Add extra functions.  Revert
+       2014-12-05 change.
+
 2015-03-15  John David Anglin  <danglin@gcc.gnu.org>
 
        * gcc.dg/torture/pr65270-1.c: Add -fno-common to dg-options on
index e00683d7175d6c4606fb73445902ded50c0f792a..eede1dcb4f353e63292540ce9afc2026b04d0d07 100644 (file)
@@ -1,8 +1,8 @@
-/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-do compile { target { powerpc*-*-* } } } */
 /* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
 /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power6" } } */
 /* { dg-options "-O2 -mcpu=power6 -mavoid-indexed-addresses" } */
-/* { dg-final { scan-assembler-times "lwbrx" 6 } } */
+/* { dg-final { scan-assembler-times "lwbrx" 12 } } */
 /* { dg-final { scan-assembler-times "stwbrx" 6 } } */
 
 /* PR 51399: bswap gets an error if -mavoid-indexed-addresses was used in
@@ -26,6 +26,24 @@ load64_reverse_3 (long long *p, int i)
   return __builtin_bswap64 (p[i]);
 }
 
+long long
+load64_reverse_4 (long long dummy __attribute__ ((unused)), long long *p)
+{
+  return __builtin_bswap64 (*p);
+}
+
+long long
+load64_reverse_5 (long long dummy __attribute__ ((unused)), long long *p)
+{
+  return __builtin_bswap64 (p[1]);
+}
+
+long long
+load64_reverse_6 (long long dummy __attribute__ ((unused)), long long *p, int i)
+{
+  return __builtin_bswap64 (p[i]);
+}
+
 void
 store64_reverse_1 (long long *p, long long x)
 {
@@ -45,7 +63,13 @@ store64_reverse_3 (long long *p, long long x, int i)
 }
 
 long long
-reg_reverse (long long x)
+reg_reverse_1 (long long x)
+{
+  return __builtin_bswap64 (x);
+}
+
+long long
+reg_reverse_2 (long long dummy __attribute__ ((unused)), long long x)
 {
   return __builtin_bswap64 (x);
 }