]> gcc.gnu.org Git - gcc.git/commitdiff
re PR bootstrap/61078 (ESA mode bootstrap failure since r209897)
authorAndreas Krebbel <Andreas.Krebbel@de.ibm.com>
Wed, 3 Sep 2014 08:06:09 +0000 (08:06 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Wed, 3 Sep 2014 08:06:09 +0000 (08:06 +0000)
2014-09-03  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

PR target/61078
* config/s390/s390.md ("*negdi2_31"): Add s390_split_ok_p check
and add a second splitter to handle the remaining cases.

2014-09-03  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

PR target/61078
* gcc.target/s390/pr61078.c: New testcase.

From-SVN: r214850

gcc/ChangeLog
gcc/config/s390/s390.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/s390/pr61078.c [new file with mode: 0644]

index 00603fa4f9a8469765acabd8001bdb50d8fdc0a6..448eec8bdfb75e9c624612153528830f9bcb6f6b 100644 (file)
@@ -1,3 +1,9 @@
+2014-09-03  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
+
+       PR target/61078
+       * config/s390/s390.md ("*negdi2_31"): Add s390_split_ok_p check
+       and add a second splitter to handle the remaining cases.
+
 2014-09-03  Chung-Ju Wu  <jasonwucj@gmail.com>
 
        * config/nds32/nds32.h (PIC_OFFSET_TABLE_REGNUM): Define.
index dde529cc6841cf941a1b5a1d4c0feb98c99a61f8..bcfe8f94f7a14e474dd0b4e066583d2d078c1a35 100644 (file)
   [(set_attr "op_type"  "RR<E>")
    (set_attr "z10prop" "z10_super_c_E1")])
 
-(define_insn_and_split "*negdi2_31"
+(define_insn "*negdi2_31"
   [(set (match_operand:DI 0 "register_operand" "=d")
         (neg:DI (match_operand:DI 1 "register_operand" "d")))
    (clobber (reg:CC CC_REGNUM))]
   "!TARGET_ZARCH"
-  "#"
-  "&& reload_completed"
+  "#")
+
+; Split a DImode NEG on 31bit into 2 SImode NEGs
+
+; Doing the twos complement separately on the SImode parts does an
+; unwanted +1 on the high part which needs to be subtracted afterwards
+; ... unless the +1 on the low part created an overflow.
+
+(define_split
+  [(set (match_operand:DI 0 "register_operand" "")
+        (neg:DI (match_operand:DI 1 "register_operand" "")))
+   (clobber (reg:CC CC_REGNUM))]
+  "!TARGET_ZARCH
+   && (REGNO (operands[0]) == REGNO (operands[1])
+      || s390_split_ok_p (operands[0], operands[1], DImode, 0))
+   && reload_completed"
   [(parallel
     [(set (match_dup 2) (neg:SI (match_dup 3)))
      (clobber (reg:CC CC_REGNUM))])
    operands[5] = operand_subword (operands[1], 1, 0, DImode);
    operands[6] = gen_label_rtx ();")
 
+; Like above but first make a copy of the low part of the src operand
+; since it might overlap with the high part of the destination.
+
+(define_split
+  [(set (match_operand:DI 0 "register_operand" "")
+        (neg:DI (match_operand:DI 1 "register_operand" "")))
+   (clobber (reg:CC CC_REGNUM))]
+  "!TARGET_ZARCH
+   && s390_split_ok_p (operands[0], operands[1], DImode, 1)
+   && reload_completed"
+  [; Make a backup of op5 first
+   (set (match_dup 4) (match_dup 5))
+   ; Setting op2 here might clobber op5
+   (parallel
+    [(set (match_dup 2) (neg:SI (match_dup 3)))
+     (clobber (reg:CC CC_REGNUM))])
+   (parallel
+    [(set (reg:CCAP CC_REGNUM)
+          (compare:CCAP (neg:SI (match_dup 4)) (const_int 0)))
+     (set (match_dup 4) (neg:SI (match_dup 4)))])
+   (set (pc)
+        (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
+                      (pc)
+                      (label_ref (match_dup 6))))
+   (parallel
+    [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
+     (clobber (reg:CC CC_REGNUM))])
+   (match_dup 6)]
+  "operands[2] = operand_subword (operands[0], 0, 0, DImode);
+   operands[3] = operand_subword (operands[1], 0, 0, DImode);
+   operands[4] = operand_subword (operands[0], 1, 0, DImode);
+   operands[5] = operand_subword (operands[1], 1, 0, DImode);
+   operands[6] = gen_label_rtx ();")
+
 ;
 ; neg(df|sf)2 instruction pattern(s).
 ;
index 7c71898205d00145f755ff1be693335d4e4b2a2e..63105ca7b8ee3611e98ba7985b5ee577e963128d 100644 (file)
@@ -1,3 +1,8 @@
+2014-09-03  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
+
+       PR target/61078
+       * gcc.target/s390/pr61078.c: New testcase.
+
 2014-09-03  Uros Bizjak  <ubizjak@gmail.com>
 
        * gcc.dg/20111227-2.c: Compile only for x86 targets.
diff --git a/gcc/testsuite/gcc.target/s390/pr61078.c b/gcc/testsuite/gcc.target/s390/pr61078.c
new file mode 100644 (file)
index 0000000..2f95eba
--- /dev/null
@@ -0,0 +1,26 @@
+/* This testcase is extracted from s390_emit_prologue.  The negation
+   of a 64bit value got split incorrectly on 31 bit.  */
+
+/* { dg-do run } */
+/* { dg-options "-O2 -mesa -m31" } */
+
+extern void abort (void);
+
+long long frame_size = 42;
+
+int __attribute__((noinline))
+foo  (int a __attribute__((unused)), long long b)
+{
+  return (int)b;
+}
+
+int
+main ()
+{
+    if (frame_size > 0)
+    {
+      if (foo (0, -frame_size) != -42)
+       abort ();
+    }
+    return 0;
+}
This page took 0.134225 seconds and 5 git commands to generate.