aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorUros Bizjak <uros@gcc.gnu.org>2016-12-04 15:38:05 +0100
committerUros Bizjak <uros@gcc.gnu.org>2016-12-04 15:38:05 +0100
commit6b7d84532342ed038a07d850ddacf7a86106a998 (patch)
tree7e3242ff6da9239e948b52cac4248cba291a04c3 /gcc/config
parentc818397a989cda38cf335a411360307dea311c99 (diff)
downloadgcc-6b7d84532342ed038a07d850ddacf7a86106a998.zip
gcc-6b7d84532342ed038a07d850ddacf7a86106a998.tar.gz
gcc-6b7d84532342ed038a07d850ddacf7a86106a998.tar.bz2
re PR target/70322 (STV doesn't optimize andn)
PR target/70322 * config/i386/i386.c (dimode_scalar_to_vector_candidate_p): Handle NEG. (dimode_scalar_chain::compute_convert_gain): Ditto. (dimode_scalar_chain::convert_insn): Ditto. testsuite/ChangeLog: PR target/70322 * gcc.target/i386/pr70322-4.c: New test. From-SVN: r243228
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/i386/i386.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 0bee09b..41717da 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2826,6 +2826,7 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn)
return false;
break;
+ case NEG:
case NOT:
break;
@@ -2851,7 +2852,8 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn)
if ((GET_MODE (XEXP (src, 0)) != DImode
&& !CONST_INT_P (XEXP (src, 0)))
- || (GET_CODE (src) != NOT
+ || (GET_CODE (src) != NEG
+ && GET_CODE (src) != NOT
&& GET_MODE (XEXP (src, 1)) != DImode
&& !CONST_INT_P (XEXP (src, 1))))
return false;
@@ -3419,7 +3421,8 @@ dimode_scalar_chain::compute_convert_gain ()
if (CONST_INT_P (XEXP (src, 1)))
gain -= vector_const_cost (XEXP (src, 1));
}
- else if (GET_CODE (src) == NOT)
+ else if (GET_CODE (src) == NEG
+ || GET_CODE (src) == NOT)
gain += ix86_cost->add - COSTS_N_INSNS (1);
else if (GET_CODE (src) == COMPARE)
{
@@ -3776,6 +3779,14 @@ dimode_scalar_chain::convert_insn (rtx_insn *insn)
PUT_MODE (src, V2DImode);
break;
+ case NEG:
+ src = XEXP (src, 0);
+ convert_op (&src, insn);
+ subreg = gen_reg_rtx (V2DImode);
+ emit_insn_before (gen_move_insn (subreg, CONST0_RTX (V2DImode)), insn);
+ src = gen_rtx_MINUS (V2DImode, subreg, src);
+ break;
+
case NOT:
src = XEXP (src, 0);
convert_op (&src, insn);