diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2018-11-19 10:25:35 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2018-11-19 10:25:35 +0000 |
commit | 0ea52812a8a6c60c580529d1d3dbe144f8e6fc2f (patch) | |
tree | 6c9ca6f8eaa675d23da1de4346ac91ba6454a6bb /gcc | |
parent | fc315b476948df23d6d9594b0d0107daafeaf8a7 (diff) | |
download | gcc-0ea52812a8a6c60c580529d1d3dbe144f8e6fc2f.zip gcc-0ea52812a8a6c60c580529d1d3dbe144f8e6fc2f.tar.gz gcc-0ea52812a8a6c60c580529d1d3dbe144f8e6fc2f.tar.bz2 |
compare-elim.c (struct comparison): Add not_in_a field.
* compare-elim.c (struct comparison): Add not_in_a field.
(is_not): New static function.
(strip_not): Likewise.
(conforming_compare): Handle a NOT in the first operand.
(can_eliminate_compare): Likewise.
(find_comparison_dom_walker::before_dom_children): Likewise.
(try_eliminate_compare): Likewise.
* config/visium/visium.md (negsi2_insn_set_carry): Turn into...
(neg<mode>2_insn_set_carry): ...this and add missing NEG operation.
From-SVN: r266268
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/compare-elim.c | 36 | ||||
-rw-r--r-- | gcc/config/visium/visium.md | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/visium/overflow16.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/visium/overflow32.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/visium/overflow8.c | 3 |
7 files changed, 59 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0b8ab0c..9803871 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2018-11-19 Eric Botcazou <ebotcazou@adacore.com> + + * compare-elim.c (struct comparison): Add not_in_a field. + (is_not): New static function. + (strip_not): Likewise. + (conforming_compare): Handle a NOT in the first operand. + (can_eliminate_compare): Likewise. + (find_comparison_dom_walker::before_dom_children): Likewise. + (try_eliminate_compare): Likewise. + * config/visium/visium.md (negsi2_insn_set_carry): Turn into... + (neg<mode>2_insn_set_carry): ...this and add missing NEG operation. + 2018-11-19 Jonathan Wakely <jwakely@redhat.com> * doc/extend.texi (Common Type Attributes): Fix typos. diff --git a/gcc/compare-elim.c b/gcc/compare-elim.c index 8afbe76..f38e576 100644 --- a/gcc/compare-elim.c +++ b/gcc/compare-elim.c @@ -123,10 +123,32 @@ struct comparison /* True if its inputs are still valid at the end of the block. */ bool inputs_valid; + + /* Whether IN_A is wrapped in a NOT before being compared. */ + bool not_in_a; }; static vec<comparison *> all_compares; +/* Return whether X is a NOT unary expression. */ + +static bool +is_not (rtx x) +{ + return GET_CODE (x) == NOT; +} + +/* Strip a NOT unary expression around X, if any. */ + +static rtx +strip_not (rtx x) +{ + if (is_not (x)) + return XEXP (x, 0); + + return x; +} + /* Look for a "conforming" comparison, as defined above. If valid, return the rtx for the COMPARE itself. */ @@ -147,7 +169,7 @@ conforming_compare (rtx_insn *insn) if (!REG_P (dest) || REGNO (dest) != targetm.flags_regnum) return NULL; - if (!REG_P (XEXP (src, 0))) + if (!REG_P (strip_not (XEXP (src, 0)))) return NULL; if (CONSTANT_P (XEXP (src, 1)) || REG_P (XEXP (src, 1))) @@ -278,10 +300,13 @@ can_eliminate_compare (rtx compare, rtx eh_note, struct comparison *cmp) return false; /* Make sure the compare is redundant with the previous. */ - if (!rtx_equal_p (XEXP (compare, 0), cmp->in_a) + if (!rtx_equal_p (strip_not (XEXP (compare, 0)), cmp->in_a) || !rtx_equal_p (XEXP (compare, 1), cmp->in_b)) return false; + if (is_not (XEXP (compare, 0)) != cmp->not_in_a) + return false; + /* New mode must be compatible with the previous compare mode. */ machine_mode new_mode = targetm.cc_modes_compatible (GET_MODE (compare), cmp->orig_mode); @@ -365,8 +390,9 @@ find_comparison_dom_walker::before_dom_children (basic_block bb) last_cmp = XCNEW (struct comparison); last_cmp->insn = insn; last_cmp->prev_clobber = last_clobber; - last_cmp->in_a = XEXP (src, 0); + last_cmp->in_a = strip_not (XEXP (src, 0)); last_cmp->in_b = XEXP (src, 1); + last_cmp->not_in_a = is_not (XEXP (src, 0)); last_cmp->eh_note = eh_note; last_cmp->orig_mode = GET_MODE (src); if (last_cmp->in_b == const0_rtx @@ -837,7 +863,9 @@ try_eliminate_compare (struct comparison *cmp) flags = gen_rtx_REG (cmp->orig_mode, targetm.flags_regnum); /* Generate a new comparison for installation in the setter. */ - rtx y = copy_rtx (cmp_a); + rtx y = cmp->not_in_a + ? gen_rtx_NOT (GET_MODE (cmp_a), copy_rtx (cmp_a)) + : copy_rtx (cmp_a); y = gen_rtx_COMPARE (GET_MODE (flags), y, copy_rtx (cmp_b)); y = gen_rtx_SET (flags, y); diff --git a/gcc/config/visium/visium.md b/gcc/config/visium/visium.md index f94a4d4..c5100b7 100644 --- a/gcc/config/visium/visium.md +++ b/gcc/config/visium/visium.md @@ -1208,14 +1208,14 @@ "sub<s> %0,r0,%1" [(set_attr "type" "arith")]) -(define_insn "negsi2_insn_set_carry" +(define_insn "neg<mode>2_insn_set_carry" [(set (reg:CCC R_FLAGS) - (compare:CCC (not:SI (match_operand:SI 1 "register_operand" "r")) + (compare:CCC (not:I (neg:I (match_operand:I 1 "register_operand" "r"))) (const_int -1))) - (set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (match_dup 1)))] + (set (match_operand:I 0 "register_operand" "=r") + (neg:I (match_dup 1)))] "reload_completed" - "sub.l %0,r0,%1" + "sub<s> %0,r0,%1" [(set_attr "type" "arith")]) (define_insn "*neg<mode>2_insn_set_overflow" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e1f0ac6..271055d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2018-11-19 Eric Botcazou <ebotcazou@adacore.com> + + * gcc.target/visium/overflow8.c: Remove -fno-if-conversion and + unrelated final test. + * gcc.target/visium/overflow16: Likewise. + * gcc.target/visium/overflow32.c: Likewise. + 2018-11-18 Paolo Carlini <paolo.carlini@oracle.com> * g++.dg/template/crash91.C: Check location too. diff --git a/gcc/testsuite/gcc.target/visium/overflow16.c b/gcc/testsuite/gcc.target/visium/overflow16.c index 223184a..665b4c3 100644 --- a/gcc/testsuite/gcc.target/visium/overflow16.c +++ b/gcc/testsuite/gcc.target/visium/overflow16.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fno-if-conversion" } */ +/* { dg-options "-O2" } */ #include <stdbool.h> @@ -36,4 +36,3 @@ bool my_neg_overflow (short a, short *res) /* { dg-final { scan-assembler-times "add.w" 2 } } */ /* { dg-final { scan-assembler-times "sub.w" 4 } } */ /* { dg-final { scan-assembler-not "cmp.w" } } */ -/* { dg-final { scan-assembler-not "mov.w" } } */ diff --git a/gcc/testsuite/gcc.target/visium/overflow32.c b/gcc/testsuite/gcc.target/visium/overflow32.c index e73deb7..c9c5095 100644 --- a/gcc/testsuite/gcc.target/visium/overflow32.c +++ b/gcc/testsuite/gcc.target/visium/overflow32.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fno-if-conversion" } */ +/* { dg-options "-O2" } */ #include <stdbool.h> @@ -36,4 +36,3 @@ bool my_neg_overflow (int a, int *res) /* { dg-final { scan-assembler-times "add.l" 2 } } */ /* { dg-final { scan-assembler-times "sub.l" 4 } } */ /* { dg-final { scan-assembler-not "cmp.l" } } */ -/* { dg-final { scan-assembler-not "mov.l" } } */ diff --git a/gcc/testsuite/gcc.target/visium/overflow8.c b/gcc/testsuite/gcc.target/visium/overflow8.c index 3aa153e..1f96ecb 100644 --- a/gcc/testsuite/gcc.target/visium/overflow8.c +++ b/gcc/testsuite/gcc.target/visium/overflow8.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fno-if-conversion" } */ +/* { dg-options "-O2" } */ #include <stdbool.h> @@ -36,4 +36,3 @@ bool my_neg_overflow (signed char a, signed char *res) /* { dg-final { scan-assembler-times "add.b" 2 } } */ /* { dg-final { scan-assembler-times "sub.b" 4 } } */ /* { dg-final { scan-assembler-not "cmp.b" } } */ -/* { dg-final { scan-assembler-not "mov.b" } } */ |