aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYvan Roux <yvan.roux@linaro.org>2014-08-11 22:08:03 +0000
committerYvan Roux <yvan.roux@linaro.org>2014-08-11 22:08:03 +0000
commit2748c83560e8b89f387e1f14e34cebaea3609f02 (patch)
treeb4119a08ecf2d105123c86a21050cf73c094fa50
parent33e55329ca8a9a4d34261903e8ba3adf755b0fb8 (diff)
gcc/
2014-08-11 Michael Collison <michael.collison@linaro.org> Backport from trunk r206529, r206530 2014-01-10 Richard Earnshaw <rearnsha@arm.com> PR target/59744 * aarch64-modes.def (CC_Zmode): New flags mode. * aarch64.c (aarch64_select_cc_mode): Only allow NEG when the condition represents an equality. (aarch64_get_condition_code): Handle CC_Zmode. * aarch64.md (compare_neg<mode>): Restrict to equality operations. gcc/testsuite/ 2014-08-11 Michael Collison <michael.collison@linaro.org> Backport from trunk r206529 2014-01-10 Richard Earnshaw <rearnsha@arm.com> PR target/59744 * gcc.target/aarch64/cmn-neg.c: Use equality comparisons. * gcc.target/aarch64/cmn-neg2.c: New test. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_8-branch@213842 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.linaro12
-rw-r--r--gcc/config/aarch64/aarch64-modes.def1
-rw-r--r--gcc/config/aarch64/aarch64.c22
-rw-r--r--gcc/config/aarch64/aarch64.md4
-rw-r--r--gcc/testsuite/ChangeLog.linaro9
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cmn-neg.c4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cmn-neg2.c34
7 files changed, 79 insertions, 7 deletions
diff --git a/gcc/ChangeLog.linaro b/gcc/ChangeLog.linaro
index 45587a4252b..49f418e1487 100644
--- a/gcc/ChangeLog.linaro
+++ b/gcc/ChangeLog.linaro
@@ -1,5 +1,17 @@
2014-08-11 Michael Collison <michael.collison@linaro.org>
+ Backport from trunk r206529, r206530
+ 2014-01-10 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/59744
+ * aarch64-modes.def (CC_Zmode): New flags mode.
+ * aarch64.c (aarch64_select_cc_mode): Only allow NEG when the condition
+ represents an equality.
+ (aarch64_get_condition_code): Handle CC_Zmode.
+ * aarch64.md (compare_neg<mode>): Restrict to equality operations.
+
+2014-08-11 Michael Collison <michael.collison@linaro.org>
+
Backport from trunk r204251
2013-10-31 Richard Sandiford <rsandifo@linux.vnet.ibm.com>
Yury Gribov <y.gribov@samsung.com>
diff --git a/gcc/config/aarch64/aarch64-modes.def b/gcc/config/aarch64/aarch64-modes.def
index fc547c890ea..c7fdddb2c81 100644
--- a/gcc/config/aarch64/aarch64-modes.def
+++ b/gcc/config/aarch64/aarch64-modes.def
@@ -24,6 +24,7 @@ CC_MODE (CC_SWP);
CC_MODE (CC_ZESWP); /* zero-extend LHS (but swap to make it RHS). */
CC_MODE (CC_SESWP); /* sign-extend LHS (but swap to make it RHS). */
CC_MODE (CC_NZ); /* Only N and Z bits of condition flags are valid. */
+CC_MODE (CC_Z); /* Only Z bit of condition flags is valid. */
/* Vector modes. */
VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI. */
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index bcad1b924e4..3589f057f78 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -3259,17 +3259,24 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y)
|| GET_CODE (x) == NEG))
return CC_NZmode;
- /* A compare with a shifted or negated operand. Because of canonicalization,
+ /* A compare with a shifted operand. Because of canonicalization,
the comparison will have to be swapped when we emit the assembly
code. */
if ((GET_MODE (x) == SImode || GET_MODE (x) == DImode)
&& (GET_CODE (y) == REG || GET_CODE (y) == SUBREG)
&& (GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT
|| GET_CODE (x) == LSHIFTRT
- || GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND
- || GET_CODE (x) == NEG))
+ || GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND))
return CC_SWPmode;
+ /* Similarly for a negated operand, but we can only do this for
+ equalities. */
+ if ((GET_MODE (x) == SImode || GET_MODE (x) == DImode)
+ && (GET_CODE (y) == REG || GET_CODE (y) == SUBREG)
+ && (code == EQ || code == NE)
+ && GET_CODE (x) == NEG)
+ return CC_Zmode;
+
/* A compare of a mode narrower than SI mode against zero can be done
by extending the value in the comparison. */
if ((GET_MODE (x) == QImode || GET_MODE (x) == HImode)
@@ -3360,6 +3367,15 @@ aarch64_get_condition_code (rtx x)
}
break;
+ case CC_Zmode:
+ switch (comp_code)
+ {
+ case NE: return AARCH64_NE;
+ case EQ: return AARCH64_EQ;
+ default: gcc_unreachable ();
+ }
+ break;
+
default:
gcc_unreachable ();
break;
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index dea03118bf7..0bf9009d5b4 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -1234,8 +1234,8 @@
)
(define_insn "*compare_neg<mode>"
- [(set (reg:CC_SWP CC_REGNUM)
- (compare:CC_SWP
+ [(set (reg:CC_Z CC_REGNUM)
+ (compare:CC_Z
(neg:GPI (match_operand:GPI 0 "register_operand" "r"))
(match_operand:GPI 1 "register_operand" "r")))]
""
diff --git a/gcc/testsuite/ChangeLog.linaro b/gcc/testsuite/ChangeLog.linaro
index 1b9307a0683..a68e21c08e9 100644
--- a/gcc/testsuite/ChangeLog.linaro
+++ b/gcc/testsuite/ChangeLog.linaro
@@ -1,3 +1,12 @@
+2014-08-11 Michael Collison <michael.collison@linaro.org>
+
+ Backport from trunk r206529
+ 2014-01-10 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/59744
+ * gcc.target/aarch64/cmn-neg.c: Use equality comparisons.
+ * gcc.target/aarch64/cmn-neg2.c: New test.
+
2014-04-07 Yvan Roux <yvan.roux@linaro.org>
GCC Linaro 4.8-2014.04 released.
diff --git a/gcc/testsuite/gcc.target/aarch64/cmn-neg.c b/gcc/testsuite/gcc.target/aarch64/cmn-neg.c
index 05c8bbff5be..ab264e798ef 100644
--- a/gcc/testsuite/gcc.target/aarch64/cmn-neg.c
+++ b/gcc/testsuite/gcc.target/aarch64/cmn-neg.c
@@ -6,7 +6,7 @@ extern void abort (void);
void __attribute__ ((noinline))
foo_s32 (int a, int b)
{
- if (a < -b)
+ if (a == -b)
abort ();
}
/* { dg-final { scan-assembler "cmn\tw\[0-9\]" } } */
@@ -14,7 +14,7 @@ foo_s32 (int a, int b)
void __attribute__ ((noinline))
foo_s64 (long long a, long long b)
{
- if (a < -b)
+ if (a == -b)
abort ();
}
/* { dg-final { scan-assembler "cmn\tx\[0-9\]" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/cmn-neg2.c b/gcc/testsuite/gcc.target/aarch64/cmn-neg2.c
new file mode 100644
index 00000000000..ca45a53435f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/cmn-neg2.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+extern void abort (void);
+
+/* It's unsafe to use CMN in these comparisons. */
+
+void __attribute__ ((noinline))
+foo_s32 (int a, int b)
+{
+ if (a < -b)
+ abort ();
+}
+
+void __attribute__ ((noinline))
+foo_s64 (unsigned long long a, unsigned long long b)
+{
+ if (a > -b)
+ abort ();
+}
+
+
+int
+main (void)
+{
+ int a = 30;
+ int b = 42;
+ foo_s32 (a, b);
+ foo_s64 (a, b);
+ return 0;
+}
+/* { dg-final { scan-assembler-not "cmn\t" } } */
+
+/* { dg-final { cleanup-saved-temps } } */