From 2ab1754e1b62ca791c3953713e903750e687cb42 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 18 Jun 2005 15:40:49 -0700 Subject: [PATCH] expr.c (store_constructor): Use store of 0 to indicate value death instead of a clobber. * expr.c (store_constructor): Use store of 0 to indicate value death instead of a clobber. * config/i386/i386.c (ix86_expand_reduc_v4sf): New. * config/i386/i386-protos.h (ix86_expand_reduc_v4sf): Declare. * config/i386/sse.md (reduc_plus_v4sf): New. (reduc_smax_v4sf, reduc_smin_v4sf): New. From-SVN: r101169 --- gcc/ChangeLog | 10 ++++++++++ gcc/config/i386/i386-protos.h | 1 + gcc/config/i386/i386.c | 21 +++++++++++++++++++++ gcc/config/i386/sse.md | 34 ++++++++++++++++++++++++++++++++++ gcc/expr.c | 4 ++-- 5 files changed, 68 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6e03eef41e6..67db590e5c9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2005-06-18 Richard Henderson + + * expr.c (store_constructor): Use store of 0 to indicate value + death instead of a clobber. + + * config/i386/i386.c (ix86_expand_reduc_v4sf): New. + * config/i386/i386-protos.h (ix86_expand_reduc_v4sf): Declare. + * config/i386/sse.md (reduc_plus_v4sf): New. + (reduc_smax_v4sf, reduc_smin_v4sf): New. + 2005-06-18 James A. Morrison * fold_const (fold_binary): Fold X % (2**N) to X & (2**N - 1) for diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 142eb5ab1de..2dc0f4573d9 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -230,6 +230,7 @@ extern rtx ix86_tls_get_addr (void); extern void ix86_expand_vector_init (bool, rtx, rtx); extern void ix86_expand_vector_set (bool, rtx, rtx, int); extern void ix86_expand_vector_extract (bool, rtx, rtx, int); +extern void ix86_expand_reduc_v4sf (rtx (*)(rtx, rtx, rtx), rtx, rtx); /* In winnt.c */ extern int i386_pe_dllexport_name_p (const char *); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 781daee98d0..6a5dbdfe5b6 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -17366,6 +17366,27 @@ ix86_expand_vector_extract (bool mmx_ok, rtx target, rtx vec, int elt) emit_move_insn (target, tmp); } } + +/* Expand a vector reduction on V4SFmode for SSE1. FN is the binar + pattern to reduce; DEST is the destination; IN is the input vector. */ + +void +ix86_expand_reduc_v4sf (rtx (*fn) (rtx, rtx, rtx), rtx dest, rtx in) +{ + rtx tmp1, tmp2, tmp3; + + tmp1 = gen_reg_rtx (V4SFmode); + tmp2 = gen_reg_rtx (V4SFmode); + tmp3 = gen_reg_rtx (V4SFmode); + + emit_insn (gen_sse_movhlps (tmp1, in, in)); + emit_insn (fn (tmp2, tmp1, in)); + + emit_insn (gen_sse_shufps_1 (tmp3, tmp2, tmp2, + GEN_INT (1), GEN_INT (1), + GEN_INT (1+4), GEN_INT (1+4))); + emit_insn (fn (dest, tmp2, tmp3)); +} /* Implements target hook vector_mode_supported_p. */ static bool diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 48b6cde1692..e323937f592 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -653,6 +653,40 @@ [(set_attr "type" "sseadd") (set_attr "mode" "V4SF")]) +(define_expand "reduc_plus_v4sf" + [(match_operand:V4SF 0 "register_operand" "") + (match_operand:V4SF 1 "register_operand" "")] + "TARGET_SSE" +{ + if (TARGET_SSE3) + { + rtx tmp = gen_reg_rtx (V4SFmode); + emit_insn (gen_sse3_haddv4sf3 (tmp, operands[1], operands[1])); + emit_insn (gen_sse3_haddv4sf3 (operands[0], tmp, tmp)); + } + else + ix86_expand_reduc_v4sf (gen_addv4sf3, operands[0], operands[1]); + DONE; +}) + +(define_expand "reduc_smax_v4sf" + [(match_operand:V4SF 0 "register_operand" "") + (match_operand:V4SF 1 "register_operand" "")] + "TARGET_SSE" +{ + ix86_expand_reduc_v4sf (gen_smaxv4sf3, operands[0], operands[1]); + DONE; +}) + +(define_expand "reduc_smin_v4sf" + [(match_operand:V4SF 0 "register_operand" "") + (match_operand:V4SF 1 "register_operand" "")] + "TARGET_SSE" +{ + ix86_expand_reduc_v4sf (gen_sminv4sf3, operands[0], operands[1]); + DONE; +}) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Parallel single-precision floating point comparisons diff --git a/gcc/expr.c b/gcc/expr.c index ac500b5d52c..0f9b1d2965c 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -5151,9 +5151,9 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size) cleared = 1; } + /* Inform later passes that the old value is dead. */ if (!cleared && REG_P (target)) - /* Inform later passes that the old value is dead. */ - emit_insn (gen_rtx_CLOBBER (VOIDmode, target)); + emit_move_insn (target, CONST0_RTX (GET_MODE (target))); /* Store each element of the constructor into the corresponding element of TARGET, determined by counting the elements. */ -- 2.30.2