diff options
author | Yvan Roux <yvan.roux@linaro.org> | 2014-08-11 22:08:03 +0000 |
---|---|---|
committer | Yvan Roux <yvan.roux@linaro.org> | 2014-08-11 22:08:03 +0000 |
commit | 2748c83560e8b89f387e1f14e34cebaea3609f02 (patch) | |
tree | b4119a08ecf2d105123c86a21050cf73c094fa50 | |
parent | 33e55329ca8a9a4d34261903e8ba3adf755b0fb8 (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.linaro | 12 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-modes.def | 1 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 22 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.md | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog.linaro | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/cmn-neg.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/cmn-neg2.c | 34 |
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 } } */ |