diff options
author | Jakub Jelinek <jakub@redhat.com> | 2019-04-08 14:36:58 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2019-04-08 14:36:58 +0200 |
commit | 0d0f212a51c1601659483e102183a75f76a2bc72 (patch) | |
tree | e86a239c5f2a6037d81f67b21f602e8a4041b071 | |
parent | 8ad68a6d87ff1978a7ef9228e79795711aed4d61 (diff) | |
download | gcc-0d0f212a51c1601659483e102183a75f76a2bc72.zip gcc-0d0f212a51c1601659483e102183a75f76a2bc72.tar.gz gcc-0d0f212a51c1601659483e102183a75f76a2bc72.tar.bz2 |
re PR rtl-optimization/89865 (FAIL: gcc.target/i386/pr49095.c scan-assembler-times \\\\), % 45)
PR rtl-optimization/89865
* config/i386/i386.md: Add peepholes for z = x; x ^= y; x != z.
* gcc.target/i386/pr49095.c: Don't expect any RMW sequences.
From-SVN: r270206
-rw-r--r-- | gcc/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 94 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr49095.c | 6 |
4 files changed, 102 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5ee20a9..5339017 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,9 @@ 2019-04-08 Jakub Jelinek <jakub@redhat.com> PR rtl-optimization/89865 + * config/i386/i386.md: Add peepholes for z = x; x ^= y; x != z. + + PR rtl-optimization/89865 * config/i386/i386.md (SWI12 peephole for mem {+,-,&,|,^}= x; mem != 0): Fix up operand numbers not to clash with the additional operands[4]. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index b797e40..4188c1a 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -18931,6 +18931,100 @@ const0_rtx); }) +;; Special cases for xor, where (x ^= y) != 0 is (misoptimized) +;; into x = z; x ^= y; x != z +(define_peephole2 + [(set (match_operand:SWI 0 "register_operand") + (match_operand:SWI 1 "memory_operand")) + (set (match_operand:SWI 3 "register_operand") (match_dup 0)) + (parallel [(set (match_operand:SWI 4 "register_operand") + (xor:SWI (match_dup 4) + (match_operand:SWI 2 "<nonmemory_operand>"))) + (clobber (reg:CC FLAGS_REG))]) + (set (match_dup 1) (match_dup 4)) + (set (reg:CCZ FLAGS_REG) + (compare:CCZ (match_operand:SWI 5 "register_operand") + (match_operand:SWI 6 "<nonmemory_operand>")))] + "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) + && (REGNO (operands[4]) == REGNO (operands[0]) + || REGNO (operands[4]) == REGNO (operands[3])) + && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0]) + ? 3 : 0], operands[5]) + ? rtx_equal_p (operands[2], operands[6]) + : rtx_equal_p (operands[2], operands[5]) + && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0]) + ? 3 : 0], operands[6])) + && peep2_reg_dead_p (4, operands[4]) + && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0]) + ? 3 : 0]) + && !reg_overlap_mentioned_p (operands[0], operands[1]) + && !reg_overlap_mentioned_p (operands[0], operands[2]) + && !reg_overlap_mentioned_p (operands[3], operands[0]) + && !reg_overlap_mentioned_p (operands[3], operands[1]) + && !reg_overlap_mentioned_p (operands[3], operands[2]) + && (<MODE>mode != QImode + || immediate_operand (operands[2], QImode) + || any_QIreg_operand (operands[2], QImode))" + [(parallel [(set (match_dup 7) (match_dup 9)) + (set (match_dup 1) (match_dup 8))])] +{ + operands[7] = SET_DEST (PATTERN (peep2_next_insn (4))); + operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]), + operands[2]); + operands[9] + = gen_rtx_COMPARE (GET_MODE (operands[7]), + copy_rtx (operands[8]), + const0_rtx); +}) + +(define_peephole2 + [(set (match_operand:SWI12 0 "register_operand") + (match_operand:SWI12 1 "memory_operand")) + (set (match_operand:SWI12 3 "register_operand") (match_dup 0)) + (parallel [(set (match_operand:SI 4 "register_operand") + (xor:SI (match_dup 4) + (match_operand:SI 2 "<nonmemory_operand>"))) + (clobber (reg:CC FLAGS_REG))]) + (set (match_dup 1) (match_operand:SWI12 5 "register_operand")) + (set (reg:CCZ FLAGS_REG) + (compare:CCZ (match_operand:SWI12 6 "register_operand") + (match_operand:SWI12 7 "<nonmemory_operand>")))] + "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) + && (REGNO (operands[5]) == REGNO (operands[0]) + || REGNO (operands[5]) == REGNO (operands[3])) + && REGNO (operands[5]) == REGNO (operands[4]) + && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0]) + ? 3 : 0], operands[6]) + ? (REG_P (operands[2]) + ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7]) + : rtx_equal_p (operands[2], operands[7])) + : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0]) + ? 3 : 0], operands[7]) + && REG_P (operands[2]) + && REGNO (operands[2]) == REGNO (operands[6]))) + && peep2_reg_dead_p (4, operands[5]) + && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0]) + ? 3 : 0]) + && !reg_overlap_mentioned_p (operands[0], operands[1]) + && !reg_overlap_mentioned_p (operands[0], operands[2]) + && !reg_overlap_mentioned_p (operands[3], operands[0]) + && !reg_overlap_mentioned_p (operands[3], operands[1]) + && !reg_overlap_mentioned_p (operands[3], operands[2]) + && (<MODE>mode != QImode + || immediate_operand (operands[2], SImode) + || any_QIreg_operand (operands[2], SImode))" + [(parallel [(set (match_dup 8) (match_dup 10)) + (set (match_dup 1) (match_dup 9))])] +{ + operands[8] = SET_DEST (PATTERN (peep2_next_insn (4))); + operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]), + gen_lowpart (<MODE>mode, operands[2])); + operands[10] + = gen_rtx_COMPARE (GET_MODE (operands[8]), + copy_rtx (operands[9]), + const0_rtx); +}) + ;; Attempt to optimize away memory stores of values the memory already ;; has. See PR79593. (define_peephole2 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 087c58b..9b7b08d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,9 @@ 2019-04-08 Jakub Jelinek <jakub@redhat.com> PR rtl-optimization/89865 + * gcc.target/i386/pr49095.c: Don't expect any RMW sequences. + + PR rtl-optimization/89865 * gcc.target/i386/pr49095.c: Adjust number of expected RMW spots on ia32. diff --git a/gcc/testsuite/gcc.target/i386/pr49095.c b/gcc/testsuite/gcc.target/i386/pr49095.c index 3ae14e3..f1295b3 100644 --- a/gcc/testsuite/gcc.target/i386/pr49095.c +++ b/gcc/testsuite/gcc.target/i386/pr49095.c @@ -71,7 +71,5 @@ G (int) G (long) /* { dg-final { scan-assembler-not "test\[lq\]" } } */ -/* The {f,h}{char,short,int,long}xor functions aren't optimized into - a RMW instruction, so need load, modify and store. FIXME eventually. */ -/* { dg-final { scan-assembler-times "\\(%eax\\), %" 8 { target { ia32 } } } } */ -/* { dg-final { scan-assembler-times "\\(%\[re\]di\\), %" 8 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not "\\(%eax\\), %" { target { ia32 } } } } */ +/* { dg-final { scan-assembler-not "\\(%\[re\]di\\), %" { target { ! ia32 } } } } */ |