fix SH long long compare
authorChristian Bruel <christian.bruel@st.com>
Thu, 17 Apr 2008 06:49:16 +0000 (08:49 +0200)
committerChristian Bruel <chrbr@gcc.gnu.org>
Thu, 17 Apr 2008 06:49:16 +0000 (08:49 +0200)
From-SVN: r134380

gcc/ChangeLog
gcc/config/sh/sh.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/long-long-compare-1.c [new file with mode: 0644]

index 57d334c17e0c2fb08c5c67734978847e87e48cca..4efd1c0ecc2b0bfb9b653964da6c75fba166857b 100644 (file)
@@ -1,3 +1,8 @@
+2008-04-17  Christian Bruel  <christian.bruel@st.com>
+
+       * config/sh/sh.c (expand_cbranchdi4): Use original operands for
+       msw_skip comparison.
+       
 2008-04-16  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/35739
index d020ccda5828fb1c53176704f80f31536f190a86..6b20ee3071d66207a79b58bd851f68b88b9c4790 100644 (file)
@@ -1685,6 +1685,14 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
     {
       rtx taken_label = operands[3];
 
+      /* Operands were possibly modified, but msw_skip doesn't expect this.
+        Always use the original ones.  */
+      if (msw_taken != CODE_FOR_nothing)
+       {
+         operands[1] = op1h;
+         operands[2] = op2h;
+       }
+
       operands[3] = skip_label = gen_label_rtx ();
       expand_cbranchsi4 (operands, msw_skip, msw_skip_prob);
       operands[3] = taken_label;
index b7349e22069d52f4caf460010bc2a2a052e21e1d..4ac7a4440ef8fe17463b7218cfcbb10db95ebba3 100644 (file)
@@ -1,3 +1,7 @@
+2008-04-17  Christian Bruel  <christian.bruel@st.com>
+
+       * gcc.dg/dicomp.c: New testcase. 
+       
 2008-04-16  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR fortran/35724
diff --git a/gcc/testsuite/gcc.dg/long-long-compare-1.c b/gcc/testsuite/gcc.dg/long-long-compare-1.c
new file mode 100644 (file)
index 0000000..c650cb1
--- /dev/null
@@ -0,0 +1,126 @@
+/* Problem only noticed on SH for -mcbranchdi DImode comparison with constants.
+ * Target dependant failure but test valid for alls.  */
+/* { dg-do run } */
+/* { dg-options "-O0" } */
+/* { dg-options "-O0 -mcbranchdi" { target sh4-*-* } } */
+
+extern void abort(void);
+extern void exit(int);
+
+int test2(long long n)
+{
+  if (n < 2)
+    return 1;
+  return 0;
+}
+
+int test1(long long n)
+{
+  if (n < 1)
+    return 1;
+  return 0;
+}
+
+int test0(long long n)
+{
+  if (n < 0)
+    return 1;
+  return 0;
+}
+
+int test1n(long long n)
+{
+  if (n < -1LL)
+    return 1;
+  return 0;
+}
+
+int test2n(long long n)
+{
+  if (n < -2LL)
+    return 1;
+  return 0;
+}
+
+int main()
+{
+  if (test2n (-1LL))
+    abort ();
+
+  if (test2n (-2LL))
+    abort ();
+
+  if (test2n (0LL))
+    abort ();
+
+  if (test2n (1LL))
+    abort ();
+
+  if (test2n (2LL))
+    abort ();
+  if (test1n (-1LL))
+    abort ();
+
+  if (!test1n (-2LL))
+    abort ();
+
+  if (test1n (0LL))
+    abort ();
+
+  if (test1n (1LL))
+    abort ();
+
+  if (test1n (2LL))
+    abort ();
+
+  if (!test0 (-1LL))
+    abort ();
+
+  if (!test0 (-2LL))
+    abort ();
+
+  if (test0 (0LL))
+    abort ();
+
+  if (test0 (1LL))
+    abort ();
+
+  if (test0 (2LL))
+    abort ();
+
+  if (!test2 (-1LL))
+    abort ();
+
+  if (!test2 (-2LL))
+    abort ();
+
+  if (!test2 (0LL))
+    abort ();
+
+  if (!test2 (1LL))
+    abort ();
+
+  if (test2 (2LL))
+    abort ();
+
+  if (!test1 (-1LL))
+    abort ();
+
+  if (!test1 (-2LL))
+    abort ();
+
+  if (!test1 (0LL))
+    abort ();
+
+  if (test1 (1LL))
+    abort ();
+
+  if (test1 (2LL))
+    abort ();
+
+  exit (0);
+}
+
+
+