PR target/12654
authorfalk <falk@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 20 Oct 2003 07:59:45 +0000 (07:59 +0000)
committerfalk <falk@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 20 Oct 2003 07:59:45 +0000 (07:59 +0000)
* config/alpha/alpha.c (alpha_emit_conditional_branch): Don't do
comparison against constant by adjusting the argument except for
EQ and NE.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@72696 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/alpha/alpha.c
gcc/testsuite/gcc.c-torture/execute/20031020-1.c [new file with mode: 0644]

index 4ebb882..20a8abc 100644 (file)
@@ -1,3 +1,10 @@
+2003-10-20  Falk Hueffner  <falk@debian.org>
+
+       PR target/12654
+       * config/alpha/alpha.c (alpha_emit_conditional_branch): Don't do
+       comparison against constant by adjusting the argument except for
+       EQ and NE.
+
 2003-10-19  Mark Mitchell  <mark@codesourcery.com>
 
        * config.gcc: Add support for arm926ejs, arm1026ejs, arm1136js,
index c79a0b5..69d996a 100644 (file)
@@ -3160,10 +3160,10 @@ alpha_emit_conditional_branch (enum rtx_code code)
          if (op1 == const0_rtx)
            cmp_code = NIL, branch_code = code;
 
-         /* We want to use cmpcc/bcc when we can, since there is a zero delay
-            bypass between logicals and br/cmov on EV5.  But we don't want to
-            force valid immediate constants into registers needlessly.  */
-         else if (GET_CODE (op1) == CONST_INT)
+         /* If the constants doesn't fit into an immediate, but can
+            be generated by lda/ldah, we adjust the argument and
+            compare against zero, so we can use beq/bne directly.  */
+         else if (GET_CODE (op1) == CONST_INT && (code == EQ || code == NE))
            {
              HOST_WIDE_INT v = INTVAL (op1), n = -v;
 
diff --git a/gcc/testsuite/gcc.c-torture/execute/20031020-1.c b/gcc/testsuite/gcc.c-torture/execute/20031020-1.c
new file mode 100644 (file)
index 0000000..526ca04
--- /dev/null
@@ -0,0 +1,23 @@
+/* PR target/12654
+   The Alpha backend tried to do a >= 1024 as (a - 1024) >= 0, which fails
+   for very large negative values.  */
+/* Origin: tg@swox.com  */
+
+#include <limits.h>
+
+extern void abort (void);
+
+void __attribute__((noinline))
+foo (long x)
+{
+  if (x >= 1024)
+    abort ();
+}
+
+int
+main ()
+{
+  foo (LONG_MIN);
+  foo (LONG_MIN + 10000);
+  return 0;
+}