re PR rtl-optimization/68910 (huge stack frame and poor code with instruction schedul...
authorEric Botcazou <ebotcazou@adacore.com>
Sat, 19 Dec 2015 21:58:02 +0000 (21:58 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sat, 19 Dec 2015 21:58:02 +0000 (21:58 +0000)
PR rtl-optimization/68910
* emit-rtl.c (set_unique_reg_note) <>REG_EQUAL>: Add bypass for USEs.
* config/sparc/sparc.md (anddi3): Enable only in 64-bit mode.
(iordi3): Likewise.
(xordi3): Likewise.
(one_cmpldi2): Likewise.
(*anddi3_sp32): Delete.
(*and_not_di_sp32): Likewise.
(*iordi3_sp32): Likewise.
(*or_not_di_sp32): Likewise.
(*xordi3_sp32): Likewise.
(*xor_not_di_sp32): Likewise.
(32-bit DImode logical operations splitter): Likewise.
(*one_cmpldi2_sp32): Likewise.

From-SVN: r231851

gcc/ChangeLog
gcc/config/sparc/sparc.md
gcc/emit-rtl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/sparc/20151219-1.c [new file with mode: 0644]

index b39dc4c1e73ad03d99b7199edf735fb458f8f381..b1e6ab993029eefb2f365e2d7fd6f2ed1d46b637 100644 (file)
@@ -1,3 +1,20 @@
+2015-12-19  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR rtl-optimization/68910
+       * emit-rtl.c (set_unique_reg_note) <>REG_EQUAL>: Add bypass for USEs.
+       * config/sparc/sparc.md (anddi3): Enable only in 64-bit mode.
+       (iordi3): Likewise.
+       (xordi3): Likewise.
+       (one_cmpldi2): Likewise.
+       (*anddi3_sp32): Delete.
+       (*and_not_di_sp32): Likewise.
+       (*iordi3_sp32): Likewise.
+       (*or_not_di_sp32): Likewise.
+       (*xordi3_sp32): Likewise.
+       (*xor_not_di_sp32): Likewise.
+       (32-bit DImode logical operations splitter): Likewise.
+       (*one_cmpldi2_sp32): Likewise.
+
 2015-12-19  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * config/arc/arc.md (*storeqi_update): Use 'any_mem_operand' and
index e1ffcc084340440629be412e052fc5ce631a29fa..3654d1e688b5ad08b234130b2789470917842b6d 100644 (file)
 
 ;; Boolean instructions.
 
-;; We define DImode `and' so with DImode `not' we can get
-;; DImode `andn'.  Other combinations are possible.
-
-(define_expand "anddi3"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (and:DI (match_operand:DI 1 "arith_double_operand" "")
-               (match_operand:DI 2 "arith_double_operand" "")))]
-  ""
-  "")
-
-(define_insn "*anddi3_sp32"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-       (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
-               (match_operand:DI 2 "arith_double_operand" "rHI")))]
-  "! TARGET_ARCH64"
-  "#")
-
-(define_insn "*anddi3_sp64"
+(define_insn "anddi3"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (and:DI (match_operand:DI 1 "arith_operand" "%r")
                (match_operand:DI 2 "arith_operand" "rI")))]
   operands[4] = GEN_INT (~INTVAL (operands[2]));
 })
 
-(define_insn_and_split "*and_not_di_sp32"
-  [(set (match_operand:DI 0 "register_operand" "=&r")
-       (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
-               (match_operand:DI 2 "register_operand" "r")))]
-  "! TARGET_ARCH64"
-  "#"
-  "&& reload_completed
-   && ((GET_CODE (operands[0]) == REG
-        && SPARC_INT_REG_P (REGNO (operands[0])))
-       || (GET_CODE (operands[0]) == SUBREG
-           && GET_CODE (SUBREG_REG (operands[0])) == REG
-           && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
-  [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
-   (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
-  "operands[3] = gen_highpart (SImode, operands[0]);
-   operands[4] = gen_highpart (SImode, operands[1]);
-   operands[5] = gen_highpart (SImode, operands[2]);
-   operands[6] = gen_lowpart (SImode, operands[0]);
-   operands[7] = gen_lowpart (SImode, operands[1]);
-   operands[8] = gen_lowpart (SImode, operands[2]);"
-  [(set_attr "length" "2")])
-
 (define_insn "*and_not_di_sp64"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
   ""
   "andn\t%2, %1, %0")
 
-(define_expand "iordi3"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (ior:DI (match_operand:DI 1 "arith_double_operand" "")
-               (match_operand:DI 2 "arith_double_operand" "")))]
-  ""
-  "")
-
-(define_insn "*iordi3_sp32"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-       (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
-               (match_operand:DI 2 "arith_double_operand" "rHI")))]
-  "! TARGET_ARCH64"
-  "#"
-  [(set_attr "length" "2")])
-
-(define_insn "*iordi3_sp64"
+(define_insn "iordi3"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (ior:DI (match_operand:DI 1 "arith_operand" "%r")
                (match_operand:DI 2 "arith_operand" "rI")))]
   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
 })
 
-(define_insn_and_split "*or_not_di_sp32"
-  [(set (match_operand:DI 0 "register_operand" "=&r")
-       (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
-               (match_operand:DI 2 "register_operand" "r")))]
-  "! TARGET_ARCH64"
-  "#"
-  "&& reload_completed
-   && ((GET_CODE (operands[0]) == REG
-        && SPARC_INT_REG_P (REGNO (operands[0])))
-       || (GET_CODE (operands[0]) == SUBREG
-           && GET_CODE (SUBREG_REG (operands[0])) == REG
-           && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
-  [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
-   (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
-  "operands[3] = gen_highpart (SImode, operands[0]);
-   operands[4] = gen_highpart (SImode, operands[1]);
-   operands[5] = gen_highpart (SImode, operands[2]);
-   operands[6] = gen_lowpart (SImode, operands[0]);
-   operands[7] = gen_lowpart (SImode, operands[1]);
-   operands[8] = gen_lowpart (SImode, operands[2]);"
-  [(set_attr "length" "2")])
-
 (define_insn "*or_not_di_sp64"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
   ""
   "orn\t%2, %1, %0")
 
-(define_expand "xordi3"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (xor:DI (match_operand:DI 1 "arith_double_operand" "")
-               (match_operand:DI 2 "arith_double_operand" "")))]
-  ""
-  "")
-
-(define_insn "*xordi3_sp32"
-  [(set (match_operand:DI 0 "register_operand" "=r")
-       (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
-               (match_operand:DI 2 "arith_double_operand" "rHI")))]
-  "! TARGET_ARCH64"
-  "#"
-  [(set_attr "length" "2")])
-
-(define_insn "*xordi3_sp64"
+(define_insn "xordi3"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (xor:DI (match_operand:DI 1 "arith_operand" "%rJ")
                (match_operand:DI 2 "arith_operand" "rI")))]
   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
 })
 
-;; Split DImode logical operations requiring two instructions.
-(define_split
-  [(set (match_operand:DI 0 "register_operand" "")
-       (match_operator:DI 1 "cc_arith_operator"        ; AND, IOR, XOR
-                          [(match_operand:DI 2 "register_operand" "")
-                           (match_operand:DI 3 "arith_double_operand" "")]))]
-  "! TARGET_ARCH64
-   && reload_completed
-   && ((GET_CODE (operands[0]) == REG
-        && SPARC_INT_REG_P (REGNO (operands[0])))
-       || (GET_CODE (operands[0]) == SUBREG
-           && GET_CODE (SUBREG_REG (operands[0])) == REG
-           && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
-  [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
-   (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
-{
-  operands[4] = gen_highpart (SImode, operands[0]);
-  operands[5] = gen_lowpart (SImode, operands[0]);
-  operands[6] = gen_highpart (SImode, operands[2]);
-  operands[7] = gen_lowpart (SImode, operands[2]);
-  operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
-  operands[9] = gen_lowpart (SImode, operands[3]);
-})
-
-;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
-;; Combine now canonicalizes to the rightmost expression.
-(define_insn_and_split "*xor_not_di_sp32"
-  [(set (match_operand:DI 0 "register_operand" "=&r")
-       (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
-                       (match_operand:DI 2 "register_operand" "r"))))]
-  "! TARGET_ARCH64"
-  "#"
-  "&& reload_completed
-   && ((GET_CODE (operands[0]) == REG
-        && SPARC_INT_REG_P (REGNO (operands[0])))
-       || (GET_CODE (operands[0]) == SUBREG
-           && GET_CODE (SUBREG_REG (operands[0])) == REG
-           && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
-  [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
-   (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
-  "operands[3] = gen_highpart (SImode, operands[0]);
-   operands[4] = gen_highpart (SImode, operands[1]);
-   operands[5] = gen_highpart (SImode, operands[2]);
-   operands[6] = gen_lowpart (SImode, operands[0]);
-   operands[7] = gen_lowpart (SImode, operands[1]);
-   operands[8] = gen_lowpart (SImode, operands[2]);"
-  [(set_attr "length" "2")])
-
 (define_insn "*xor_not_di_sp64"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
   "subcc\t%%g0, %1, %0"
   [(set_attr "type" "compare")])
 
-;; We cannot use the "not" pseudo insn because the Sun assembler
-;; does not know how to make it work for constants.
-(define_expand "one_cmpldi2"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (not:DI (match_operand:DI 1 "register_operand" "")))]
-  ""
-  "")
-
-(define_insn_and_split "*one_cmpldi2_sp32"
-  [(set (match_operand:DI 0 "register_operand" "=&r")
-       (not:DI (match_operand:DI 1 "register_operand" "r")))]
-  "! TARGET_ARCH64"
-  "#"
-  "&& reload_completed
-   && ((GET_CODE (operands[0]) == REG
-        && SPARC_INT_REG_P (REGNO (operands[0])))
-       || (GET_CODE (operands[0]) == SUBREG
-           && GET_CODE (SUBREG_REG (operands[0])) == REG
-           && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
-  [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
-   (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
-  "operands[2] = gen_highpart (SImode, operands[0]);
-   operands[3] = gen_highpart (SImode, operands[1]);
-   operands[4] = gen_lowpart (SImode, operands[0]);
-   operands[5] = gen_lowpart (SImode, operands[1]);"
-  [(set_attr "length" "2")])
-
-(define_insn "*one_cmpldi2_sp64"
+(define_insn "one_cmpldi2"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (not:DI (match_operand:DI 1 "arith_operand" "rI")))]
   "TARGET_ARCH64"
index c6a37e1c09c4d01debc16b90e04ad56e80859555..dbc0af09a0807c4945a7dc1f0c955157ea3c003d 100644 (file)
@@ -5239,7 +5239,8 @@ set_unique_reg_note (rtx insn, enum reg_note kind, rtx datum)
     {
     case REG_EQUAL:
     case REG_EQUIV:
-      if (!set_for_reg_notes (insn))
+      /* We need to support the REG_EQUAL on USE trick of find_reloads.  */
+      if (!set_for_reg_notes (insn) && GET_CODE (PATTERN (insn)) != USE)
        return NULL_RTX;
 
       /* Don't add ASM_OPERAND REG_EQUAL/REG_EQUIV notes.
index d1ebe8d9a883f9c5e8116600c683c9ee61d788f0..b1c48334d774d190e38c1e3a286bc4fa66dea297 100644 (file)
@@ -1,3 +1,7 @@
+2015-12-19  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc.target/sparc/20151219-1.c: New test.
+
 2015-12-19  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * gcc.target/arc/load-update.c: New file.
diff --git a/gcc/testsuite/gcc.target/sparc/20151219-1.c b/gcc/testsuite/gcc.target/sparc/20151219-1.c
new file mode 100644 (file)
index 0000000..efe720a
--- /dev/null
@@ -0,0 +1,39 @@
+/* PR rtl-optimization/68910 */
+/* Reported by Sebastian Huber <sebastian.huber@embedded-brains.de> */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=supersparc" } */
+
+typedef unsigned int size_t;
+typedef long long unsigned int uint64_t;
+
+extern void *memcpy (void *, const void *, size_t);
+
+void
+SHA512_Transform(uint64_t * state, const unsigned char block[128])
+{
+  uint64_t W[80];
+  uint64_t S[8];
+  uint64_t t0, t1;
+  int i;
+
+  memcpy ((void *)W, (const void *)block, (size_t)128);
+
+  for (i = 16; i < 80; i++)
+    W[i] = (((W[i - 2] >> 19) | (W[i - 2] << (64 - 19))) ^ ((W[i - 2] >> 61) | (W[i - 2] << (64 - 61))) ^ (W[i - 2] >> 6)) + W[i - 7] + (((W[i - 15] >> 1) | (W[i - 15] << (64 - 1))) ^ ((W[i - 15] >> 8) | (W[i - 15] << (64 - 8))) ^ (W[i - 15] >> 7)) + W[i - 16];
+
+  memcpy (S, state, 64);
+
+  t0 = S[(87 - 0) % 8] + (((S[(84 - 0) % 8] >> 14) | (S[(84 - 0) % 8] << (64 - 14))) ^ ((S[(84 - 0) % 8] >> 18) | (S[(84 - 0) % 8] << (64 - 18))) ^ ((S[(84 - 0) % 8] >> 41) | (S[(84 - 0) % 8] << (64 - 41)))) + ((S[(84 - 0) % 8] & (S[(85 - 0) % 8] ^ S[(86 - 0) % 8])) ^ S[(86 - 0) % 8]) + W[0] + 0x428a2f98d728ae22ULL; t1 = (((S[(80 - 0) % 8] >> 28) | (S[(80 - 0) % 8] << (64 - 28))) ^ ((S[(80 - 0) % 8] >> 34) | (S[(80 - 0) % 8] << (64 - 34))) ^ ((S[(80 - 0) % 8] >> 39) | (S[(80 - 0) % 8] << (64 - 39)))) + ((S[(80 - 0) % 8] & (S[(81 - 0) % 8] | S[(82 - 0) % 8])) | (S[(81 - 0) % 8] & S[(82 - 0) % 8])); S[(83 - 0) % 8] += t0; S[(87 - 0) % 8] = t0 + t1;
+
+  t0 = S[(87 - 1) % 8] + (((S[(84 - 1) % 8] >> 14) | (S[(84 - 1) % 8] << (64 - 14))) ^ ((S[(84 - 1) % 8] >> 18) | (S[(84 - 1) % 8] << (64 - 18))) ^ ((S[(84 - 1) % 8] >> 41) | (S[(84 - 1) % 8] << (64 - 41)))) + ((S[(84 - 1) % 8] & (S[(85 - 1) % 8] ^ S[(86 - 1) % 8])) ^ S[(86 - 1) % 8]) + W[1] + 0x7137449123ef65cdULL; t1 = (((S[(80 - 1) % 8] >> 28) | (S[(80 - 1) % 8] << (64 - 28))) ^ ((S[(80 - 1) % 8] >> 34) | (S[(80 - 1) % 8] << (64 - 34))) ^ ((S[(80 - 1) % 8] >> 39) | (S[(80 - 1) % 8] << (64 - 39)))) + ((S[(80 - 1) % 8] & (S[(81 - 1) % 8] | S[(82 - 1) % 8])) | (S[(81 - 1) % 8] & S[(82 - 1) % 8])); S[(83 - 1) % 8] += t0; S[(87 - 1) % 8] = t0 + t1;
+
+  t0 = S[(87 - 2) % 8] + (((S[(84 - 2) % 8] >> 14) | (S[(84 - 2) % 8] << (64 - 14))) ^ ((S[(84 - 2) % 8] >> 18) | (S[(84 - 2) % 8] << (64 - 18))) ^ ((S[(84 - 2) % 8] >> 41) | (S[(84 - 2) % 8] << (64 - 41)))) + ((S[(84 - 2) % 8] & (S[(85 - 2) % 8] ^ S[(86 - 2) % 8])) ^ S[(86 - 2) % 8]) + W[2] + 0xb5c0fbcfec4d3b2fULL; t1 = (((S[(80 - 2) % 8] >> 28) | (S[(80 - 2) % 8] << (64 - 28))) ^ ((S[(80 - 2) % 8] >> 34) | (S[(80 - 2) % 8] << (64 - 34))) ^ ((S[(80 - 2) % 8] >> 39) | (S[(80 - 2) % 8] << (64 - 39)))) + ((S[(80 - 2) % 8] & (S[(81 - 2) % 8] | S[(82 - 2) % 8])) | (S[(81 - 2) % 8] & S[(82 - 2) % 8])); S[(83 - 2) % 8] += t0; S[(87 - 2) % 8] = t0 + t1;
+
+  t0 = S[(87 - 3) % 8] + (((S[(84 - 3) % 8] >> 14) | (S[(84 - 3) % 8] << (64 - 14))) ^ ((S[(84 - 3) % 8] >> 18) | (S[(84 - 3) % 8] << (64 - 18))) ^ ((S[(84 - 3) % 8] >> 41) | (S[(84 - 3) % 8] << (64 - 41)))) + ((S[(84 - 3) % 8] & (S[(85 - 3) % 8] ^ S[(86 - 3) % 8])) ^ S[(86 - 3) % 8]) + W[3] + 0xe9b5dba58189dbbcULL; t1 = (((S[(80 - 3) % 8] >> 28) | (S[(80 - 3) % 8] << (64 - 28))) ^ ((S[(80 - 3) % 8] >> 34) | (S[(80 - 3) % 8] << (64 - 34))) ^ ((S[(80 - 3) % 8] >> 39) | (S[(80 - 3) % 8] << (64 - 39)))) + ((S[(80 - 3) % 8] & (S[(81 - 3) % 8] | S[(82 - 3) % 8])) | (S[(81 - 3) % 8] & S[(82 - 3) % 8])); S[(83 - 3) % 8] += t0; S[(87 - 3) % 8] = t0 + t1;
+
+  for (i = 0; i < 8; i++)
+    state[i] += S[i];
+}
+
+/* { dg-final { scan-assembler-not "stx\t%" } } */