Since AArch64 sets all flags on logical operations, comparisons with zero can be combined into an AND even if the condition is LE or GT.
Passes regress, OK for commit? gcc: PR target/105773 * config/aarch64/aarch64.cc (aarch64_select_cc_mode): Allow GT/LE for merging compare with zero into AND. (aarch64_get_condition_code_1): Support GT and LE in CC_NZmode. gcc/testsuite: PR target/105773 * gcc.target/aarch64/ands_2.c: Test for ANDS. * gcc.target/aarch64/bics_2.c: Test for BICS. * gcc.target/aarch64/tst_2.c: Test for TST. * gcc.target/aarch64/tst_imm_split_1.c: Fix test. --- diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 1601d11710cb6132c80a77bb4fe2f8429519aa5a..00876b08d8fbb1329a37a0ea73d3abf09d28b829 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -11323,7 +11323,8 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y) if ((mode_x == SImode || mode_x == DImode) && y == const0_rtx - && (code == EQ || code == NE || code == LT || code == GE) + && (code == EQ || code == NE || code == LT || code == GE + || (code_x == AND && (code == GT || code == LE))) && (code_x == PLUS || code_x == MINUS || code_x == AND || code_x == NEG || (code_x == ZERO_EXTRACT && CONST_INT_P (XEXP (x, 1)) @@ -11471,6 +11472,8 @@ aarch64_get_condition_code_1 (machine_mode mode, enum rtx_code comp_code) case EQ: return AARCH64_EQ; case GE: return AARCH64_PL; case LT: return AARCH64_MI; + case GT: return AARCH64_GT; + case LE: return AARCH64_LE; default: return -1; } break; diff --git a/gcc/testsuite/gcc.target/aarch64/ands_2.c b/gcc/testsuite/gcc.target/aarch64/ands_2.c index b061b1dfc59c1847cb799a1e49f8e5fc53bf2f14..c8763f234c5f7d19ef9c222756ab5e8a6eaae6fe 100644 --- a/gcc/testsuite/gcc.target/aarch64/ands_2.c +++ b/gcc/testsuite/gcc.target/aarch64/ands_2.c @@ -8,8 +8,7 @@ ands_si_test1 (int a, int b, int c) { int d = a & b; - /* { dg-final { scan-assembler-not "ands\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ - /* { dg-final { scan-assembler-times "and\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" 2 } } */ + /* { dg-final { scan-assembler "ands\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ if (d <= 0) return a + c; else @@ -21,12 +20,11 @@ ands_si_test2 (int a, int b, int c) { int d = a & 0x99999999; - /* { dg-final { scan-assembler-not "ands\tw\[0-9\]+, w\[0-9\]+, -1717986919" } } */ - /* { dg-final { scan-assembler "and\tw\[0-9\]+, w\[0-9\]+, -1717986919" } } */ - if (d <= 0) - return a + c; - else + /* { dg-final { scan-assembler "ands\tw\[0-9\]+, w\[0-9\]+, -1717986919" } } */ + if (d > 0) return b + d + c; + else + return a + c; } int @@ -34,8 +32,7 @@ ands_si_test3 (int a, int b, int c) { int d = a & (b << 3); - /* { dg-final { scan-assembler-not "ands\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ - /* { dg-final { scan-assembler "and\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ + /* { dg-final { scan-assembler "ands\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ if (d <= 0) return a + c; else @@ -49,8 +46,7 @@ ands_di_test1 (s64 a, s64 b, s64 c) { s64 d = a & b; - /* { dg-final { scan-assembler-not "ands\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ - /* { dg-final { scan-assembler-times "and\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" 2 } } */ + /* { dg-final { scan-assembler "ands\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ if (d <= 0) return a + c; else @@ -62,12 +58,11 @@ ands_di_test2 (s64 a, s64 b, s64 c) { s64 d = a & 0xaaaaaaaaaaaaaaaall; - /* { dg-final { scan-assembler-not "ands\tx\[0-9\]+, x\[0-9\]+, -6148914691236517206" } } */ - /* { dg-final { scan-assembler "and\tx\[0-9\]+, x\[0-9\]+, -6148914691236517206" } } */ - if (d <= 0) - return a + c; - else + /* { dg-final { scan-assembler "ands\tx\[0-9\]+, x\[0-9\]+, -6148914691236517206" } } */ + if (d > 0) return b + d + c; + else + return a + c; } s64 @@ -75,8 +70,7 @@ ands_di_test3 (s64 a, s64 b, s64 c) { s64 d = a & (b << 3); - /* { dg-final { scan-assembler-not "ands\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ - /* { dg-final { scan-assembler "and\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ + /* { dg-final { scan-assembler "ands\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ if (d <= 0) return a + c; else diff --git a/gcc/testsuite/gcc.target/aarch64/bics_2.c b/gcc/testsuite/gcc.target/aarch64/bics_2.c index 9ccae368c1276618bad691c78fb621a9c82794b7..c1f7e87a6121f7b067b7b37b149da64aa63ebd1a 100644 --- a/gcc/testsuite/gcc.target/aarch64/bics_2.c +++ b/gcc/testsuite/gcc.target/aarch64/bics_2.c @@ -8,8 +8,7 @@ bics_si_test1 (int a, int b, int c) { int d = a & ~b; - /* { dg-final { scan-assembler-not "bics\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ - /* { dg-final { scan-assembler-times "bic\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" 2 } } */ + /* { dg-final { scan-assembler "bics\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ if (d <= 0) return a + c; else @@ -21,12 +20,11 @@ bics_si_test2 (int a, int b, int c) { int d = a & ~(b << 3); - /* { dg-final { scan-assembler-not "bics\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ - /* { dg-final { scan-assembler "bic\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ - if (d <= 0) - return a + c; - else + /* { dg-final { scan-assembler "bics\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ + if (d > 0) return b + d + c; + else + return a + c; } typedef long long s64; @@ -36,8 +34,7 @@ bics_di_test1 (s64 a, s64 b, s64 c) { s64 d = a & ~b; - /* { dg-final { scan-assembler-not "bics\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ - /* { dg-final { scan-assembler-times "bic\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" 2 } } */ + /* { dg-final { scan-assembler "bics\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ if (d <= 0) return a + c; else @@ -49,12 +46,11 @@ bics_di_test2 (s64 a, s64 b, s64 c) { s64 d = a & ~(b << 3); - /* { dg-final { scan-assembler-not "bics\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ - /* { dg-final { scan-assembler "bic\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ - if (d <= 0) - return a + c; - else + /* { dg-final { scan-assembler "bics\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ + if (d > 0) return b + d + c; + else + return a + c; } int diff --git a/gcc/testsuite/gcc.target/aarch64/tst_2.c b/gcc/testsuite/gcc.target/aarch64/tst_2.c index c8b28fc5620a9140fee29c4455294af708642d69..3c9bdfd05c4a19e83150f84f454c3e875c7757d1 100644 --- a/gcc/testsuite/gcc.target/aarch64/tst_2.c +++ b/gcc/testsuite/gcc.target/aarch64/tst_2.c @@ -8,8 +8,7 @@ tst_si_test1 (int a, int b, int c) { int d = a & b; - /* { dg-final { scan-assembler-not "tst\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" } } */ - /* { dg-final { scan-assembler-times "and\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+" 2 } } */ + /* { dg-final { scan-assembler "tst\tw\[0-9\]+, w\[0-9\]+" } } */ if (d <= 0) return 12; else @@ -21,12 +20,11 @@ tst_si_test2 (int a, int b, int c) { int d = a & 0x99999999; - /* { dg-final { scan-assembler-not "tst\tw\[0-9\]+, w\[0-9\]+, -1717986919" } } */ - /* { dg-final { scan-assembler "and\tw\[0-9\]+, w\[0-9\]+, -1717986919" } } */ - if (d <= 0) - return 12; - else + /* { dg-final { scan-assembler "tst\tw\[0-9\]+, -1717986919" } } */ + if (d > 0) return 18; + else + return 12; } int @@ -34,8 +32,7 @@ tst_si_test3 (int a, int b, int c) { int d = a & (b << 3); - /* { dg-final { scan-assembler-not "tst\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ - /* { dg-final { scan-assembler "and\tw\[0-9\]+, w\[0-9\]+, w\[0-9\]+, lsl 3" } } */ + /* { dg-final { scan-assembler "tst\tw\[0-9\]+, w\[0-9\]+, lsl 3" } } */ if (d <= 0) return 12; else @@ -49,8 +46,7 @@ tst_di_test1 (s64 a, s64 b, s64 c) { s64 d = a & b; - /* { dg-final { scan-assembler-not "tst\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" } } */ - /* { dg-final { scan-assembler-times "and\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+" 2 } } */ + /* { dg-final { scan-assembler "tst\tx\[0-9\]+, x\[0-9\]+" } } */ if (d <= 0) return 12; else @@ -62,8 +58,7 @@ tst_di_test2 (s64 a, s64 b, s64 c) { s64 d = a & 0xaaaaaaaaaaaaaaaall; - /* { dg-final { scan-assembler-not "tst\tx\[0-9\]+, x\[0-9\]+, -6148914691236517206" } } */ - /* { dg-final { scan-assembler "and\tx\[0-9\]+, x\[0-9\]+, -6148914691236517206" } } */ + /* { dg-final { scan-assembler "tst\tx\[0-9\]+, -6148914691236517206" } } */ if (d <= 0) return 12; else @@ -75,12 +70,11 @@ tst_di_test3 (s64 a, s64 b, s64 c) { s64 d = a & (b << 3); - /* { dg-final { scan-assembler-not "tst\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ - /* { dg-final { scan-assembler "and\tx\[0-9\]+, x\[0-9\]+, x\[0-9\]+, lsl 3" } } */ - if (d <= 0) - return 12; - else + /* { dg-final { scan-assembler "tst\tx\[0-9\]+, x\[0-9\]+, lsl 3" } } */ + if (d > 0) return 18; + else + return 12; } int diff --git a/gcc/testsuite/gcc.target/aarch64/tst_imm_split_1.c b/gcc/testsuite/gcc.target/aarch64/tst_imm_split_1.c index 33a2c0f45afadb8fc9488f847f296ec0e690c049..e456e823593fbe507a8a67b5115a45712e40f80e 100644 --- a/gcc/testsuite/gcc.target/aarch64/tst_imm_split_1.c +++ b/gcc/testsuite/gcc.target/aarch64/tst_imm_split_1.c @@ -14,5 +14,4 @@ g (unsigned char *p) } /* { dg-final { scan-assembler-not "and\\t\[xw\]\[0-9\]+, \[xw\]\[0-9\]+.*" } } */ -/* { dg-final { scan-assembler "tst\\t\[xw\]\[0-9\]+, \[xw\]\[0-9\]+" } } */ -/* { dg-final { scan-assembler "tst\\t\[xw\]\[0-9\]+, \[xw\]\[0-9\]+, lsr 4" } } */ +/* { dg-final { scan-assembler-times "tst\\t\[xw\]\[0-9\]+, \[xw\]\[0-9\]+" 2 } } */