Commit 3f831b7d by Jakub Jelinek Committed by Jakub Jelinek

re PR rtl-optimization/49095 (Horrible code generation for trivial decrement with test)

	PR rtl-optimization/49095
	* config/i386/predicates.md (plusminuslogic_operator): New predicate.
	* config/i386/i386.md: Add peepholes for mem {+,-,&,|,^}= x; mem != 0.

	* gcc.target/i386/pr49095.c: New test.

From-SVN: r174413
parent fb03a37e
2011-05-29 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/49095
* config/i386/predicates.md (plusminuslogic_operator): New predicate.
* config/i386/i386.md: Add peepholes for mem {+,-,&,|,^}= x; mem != 0.
2011-05-29 Richard Sandiford <rdsandiford@googlemail.com>
PR target/43995
......
......@@ -16868,6 +16868,91 @@
(clobber (reg:CC FLAGS_REG))])
(set (match_dup 0) (match_dup 2))])
;; Attempt to use arith or logical operations with memory outputs with
;; setting of flags.
(define_peephole2
[(set (match_operand:SWI 0 "register_operand" "")
(match_operand:SWI 1 "memory_operand" ""))
(parallel [(set (match_dup 0)
(match_operator:SWI 3 "plusminuslogic_operator"
[(match_dup 0)
(match_operand:SWI 2 "<nonmemory_operand>" "")]))
(clobber (reg:CC FLAGS_REG))])
(set (match_dup 1) (match_dup 0))
(set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
"(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
&& peep2_reg_dead_p (4, operands[0])
&& !reg_overlap_mentioned_p (operands[0], operands[1])
&& ix86_match_ccmode (peep2_next_insn (3),
(GET_CODE (operands[3]) == PLUS
|| GET_CODE (operands[3]) == MINUS)
? CCGOCmode : CCNOmode)"
[(parallel [(set (match_dup 4) (match_dup 5))
(set (match_dup 1) (match_op_dup 3 [(match_dup 1)
(match_dup 2)]))])]
"operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
copy_rtx (operands[1]),
copy_rtx (operands[2]));
operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
operands[5], const0_rtx);")
(define_peephole2
[(parallel [(set (match_operand:SWI 0 "register_operand" "")
(match_operator:SWI 2 "plusminuslogic_operator"
[(match_dup 0)
(match_operand:SWI 1 "memory_operand" "")]))
(clobber (reg:CC FLAGS_REG))])
(set (match_dup 1) (match_dup 0))
(set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
"(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
&& GET_CODE (operands[2]) != MINUS
&& peep2_reg_dead_p (3, operands[0])
&& !reg_overlap_mentioned_p (operands[0], operands[1])
&& ix86_match_ccmode (peep2_next_insn (2),
GET_CODE (operands[2]) == PLUS
? CCGOCmode : CCNOmode)"
[(parallel [(set (match_dup 3) (match_dup 4))
(set (match_dup 1) (match_op_dup 2 [(match_dup 1)
(match_dup 0)]))])]
"operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
copy_rtx (operands[1]),
copy_rtx (operands[0]));
operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
operands[4], const0_rtx);")
(define_peephole2
[(set (match_operand:SWI12 0 "register_operand" "")
(match_operand:SWI12 1 "memory_operand" ""))
(parallel [(set (match_operand:SI 4 "register_operand" "")
(match_operator:SI 3 "plusminuslogic_operator"
[(match_dup 4)
(match_operand:SI 2 "nonmemory_operand" "")]))
(clobber (reg:CC FLAGS_REG))])
(set (match_dup 1) (match_dup 0))
(set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
"(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
&& REG_P (operands[0]) && REG_P (operands[4])
&& REGNO (operands[0]) == REGNO (operands[4])
&& peep2_reg_dead_p (4, operands[0])
&& !reg_overlap_mentioned_p (operands[0], operands[1])
&& ix86_match_ccmode (peep2_next_insn (3),
(GET_CODE (operands[3]) == PLUS
|| GET_CODE (operands[3]) == MINUS)
? CCGOCmode : CCNOmode)"
[(parallel [(set (match_dup 4) (match_dup 5))
(set (match_dup 1) (match_dup 6))])]
"operands[2] = gen_lowpart (<MODE>mode, operands[2]);
operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
copy_rtx (operands[1]), operands[2]);
operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
operands[5], const0_rtx);
operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
copy_rtx (operands[1]),
copy_rtx (operands[2]));")
;; Attempt to always use XOR for zeroing registers.
(define_peephole2
[(set (match_operand 0 "register_operand" "")
......
;; Predicate definitions for IA-32 and x86-64.
;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
;; Free Software Foundation, Inc.
;;
;; This file is part of GCC.
......@@ -1070,6 +1070,10 @@
(define_predicate "div_operator"
(match_code "div"))
;; Return true if this is a plus, minus, and, ior or xor operation.
(define_predicate "plusminuslogic_operator"
(match_code "plus,minus,and,ior,xor"))
;; Return true if this is a float extend operation.
(define_predicate "float_operator"
(match_code "float"))
......
2011-05-29 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/49095
* gcc.target/i386/pr49095.c: New test.
2011-05-29 Tobias Burnus <burnus@net-b.de>
PR fortran/18918
......
/* PR rtl-optimization/49095 */
/* { dg-do compile } */
/* { dg-options "-Os" } */
/* { dg-options "-Os -mregparm=2" { target ilp32 } } */
void foo (void *);
int *
f1 (int *x)
{
if (!--*x)
foo (x);
return x;
}
int
g1 (int x)
{
if (!--x)
foo ((void *) 0);
return x;
}
#define F(T, OP, OPN) \
T * \
f##T##OPN (T *x, T y) \
{ \
*x OP y; \
if (!*x) \
foo (x); \
return x; \
} \
\
T \
g##T##OPN (T x, T y) \
{ \
x OP y; \
if (!x) \
foo ((void *) 0); \
return x; \
} \
\
T * \
h##T##OPN (T *x) \
{ \
*x OP 24; \
if (!*x) \
foo (x); \
return x; \
} \
\
T \
i##T##OPN (T x, T y) \
{ \
x OP 24; \
if (!x) \
foo ((void *) 0); \
return x; \
}
#define G(T) \
F (T, +=, plus) \
F (T, -=, minus) \
F (T, &=, and) \
F (T, |=, or) \
F (T, ^=, xor)
G (char)
G (short)
G (int)
G (long)
/* { dg-final { scan-assembler-not "test\[lq\]" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment