aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-12-02 17:28:41 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2016-12-02 17:28:41 +0100
commit17c69eff82d20174099bad6bbd67dbf5e76c39a5 (patch)
treeed759c595afb358f1773a94aa24f381bcbbf4098 /gcc/config
parenteb61d07edaf05f36151bfe4382777eaa79bce4d9 (diff)
downloadgcc-17c69eff82d20174099bad6bbd67dbf5e76c39a5.zip
gcc-17c69eff82d20174099bad6bbd67dbf5e76c39a5.tar.gz
gcc-17c69eff82d20174099bad6bbd67dbf5e76c39a5.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 NOT. (dimode_scalar_chain::compute_convert_gain): Likewise. (dimode_scalar_chain::convert_insn): Likewise. * config/i386/i386.md (*one_cmpldi2_doubleword): New define_insn_and_split. (one_cmpl<mode>2): Use SWIM1248x iterator instead of SWIM. * gcc.target/i386/pr70322-1.c: New test. * gcc.target/i386/pr70322-2.c: New test. * gcc.target/i386/pr70322-3.c: New test. From-SVN: r243195
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/i386/i386.c16
-rw-r--r--gcc/config/i386/i386.md17
2 files changed, 30 insertions, 3 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 5678fa2..0bee09b 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2826,6 +2826,9 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn)
return false;
break;
+ case NOT:
+ break;
+
case REG:
return true;
@@ -2848,7 +2851,8 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn)
if ((GET_MODE (XEXP (src, 0)) != DImode
&& !CONST_INT_P (XEXP (src, 0)))
- || (GET_MODE (XEXP (src, 1)) != DImode
+ || (GET_CODE (src) != NOT
+ && GET_MODE (XEXP (src, 1)) != DImode
&& !CONST_INT_P (XEXP (src, 1))))
return false;
@@ -3415,6 +3419,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)
+ gain += ix86_cost->add - COSTS_N_INSNS (1);
else if (GET_CODE (src) == COMPARE)
{
/* Assume comparison cost is the same. */
@@ -3770,6 +3776,14 @@ dimode_scalar_chain::convert_insn (rtx_insn *insn)
PUT_MODE (src, V2DImode);
break;
+ case NOT:
+ src = XEXP (src, 0);
+ convert_op (&src, insn);
+ subreg = gen_reg_rtx (V2DImode);
+ emit_insn_before (gen_move_insn (subreg, CONSTM1_RTX (V2DImode)), insn);
+ src = gen_rtx_XOR (V2DImode, src, subreg);
+ break;
+
case MEM:
if (!REG_P (dst))
convert_op (&src, insn);
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 583d2bb..da7cb07 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -9312,9 +9312,22 @@
;; One complement instructions
+(define_insn_and_split "*one_cmpldi2_doubleword"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
+ (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
+ "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
+ && ix86_unary_operator_ok (NOT, DImode, operands)"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0)
+ (not:SI (match_dup 1)))
+ (set (match_dup 2)
+ (not:SI (match_dup 3)))]
+ "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
+
(define_expand "one_cmpl<mode>2"
- [(set (match_operand:SWIM 0 "nonimmediate_operand")
- (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
+ [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
+ (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
""
"ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")