From: Jakub Jelinek Date: Fri, 28 Sep 2012 12:20:54 +0000 (+0200) Subject: re PR target/54716 (Select best typed instruction for bitwise operations) X-Git-Tag: misc/gccgo-go1_1_2~589 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=42bace41fde0f50013e0522a3a00f8ae89313d65;p=thirdparty%2Fgcc.git re PR target/54716 (Select best typed instruction for bitwise operations) PR target/54716 * config/i386/predicates.md (nonimmediate_or_const_vector_operand): New predicate. * config/i386/i386.c (ix86_expand_vector_logical_operator): New function. * config/i386/i386-protos.h (ix86_expand_vector_logical_operator): New prototype. * config/i386/sse.md (3 VI logic): Use it. * gcc.target/i386/xorps-sse2.c: Remove xfails. From-SVN: r191827 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d45df05746f3..6f2fb9f40770 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 2012-09-28 Jakub Jelinek + PR target/54716 + * config/i386/predicates.md (nonimmediate_or_const_vector_operand): + New predicate. + * config/i386/i386.c (ix86_expand_vector_logical_operator): New + function. + * config/i386/i386-protos.h (ix86_expand_vector_logical_operator): New + prototype. + * config/i386/sse.md (3 VI logic): Use it. + PR tree-optimization/54713 * fold-const.c (vec_cst_ctor_to_array): Give up if vector CONSTRUCTOR has vector elements. diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 29bd69a47157..2002bfcef5bc 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -91,6 +91,8 @@ extern void ix86_fixup_binary_operands_no_copy (enum rtx_code, enum machine_mode, rtx[]); extern void ix86_expand_binary_operator (enum rtx_code, enum machine_mode, rtx[]); +extern void ix86_expand_vector_logical_operator (enum rtx_code, + enum machine_mode, rtx[]); extern bool ix86_binary_operator_ok (enum rtx_code, enum machine_mode, rtx[]); extern bool ix86_avoid_lea_for_add (rtx, rtx[]); extern bool ix86_use_lea_for_mov (rtx, rtx[]); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 68285717d8a6..de9c68718788 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -16490,6 +16490,82 @@ ix86_expand_binary_operator (enum rtx_code code, enum machine_mode mode, emit_move_insn (operands[0], dst); } +/* Expand vector logical operation CODE (AND, IOR, XOR) in MODE with + the given OPERANDS. */ + +void +ix86_expand_vector_logical_operator (enum rtx_code code, enum machine_mode mode, + rtx operands[]) +{ + rtx op1 = NULL_RTX, op2 = NULL_RTX; + if (GET_CODE (operands[1]) == SUBREG) + { + op1 = operands[1]; + op2 = operands[2]; + } + else if (GET_CODE (operands[2]) == SUBREG) + { + op1 = operands[2]; + op2 = operands[1]; + } + /* Optimize (__m128i) d | (__m128i) e and similar code + when d and e are float vectors into float vector logical + insn. In C/C++ without using intrinsics there is no other way + to express vector logical operation on float vectors than + to cast them temporarily to integer vectors. */ + if (op1 + && !TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL + && ((GET_CODE (op2) == SUBREG || GET_CODE (op2) == CONST_VECTOR)) + && GET_MODE_CLASS (GET_MODE (SUBREG_REG (op1))) == MODE_VECTOR_FLOAT + && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1))) == GET_MODE_SIZE (mode) + && SUBREG_BYTE (op1) == 0 + && (GET_CODE (op2) == CONST_VECTOR + || (GET_MODE (SUBREG_REG (op1)) == GET_MODE (SUBREG_REG (op2)) + && SUBREG_BYTE (op2) == 0)) + && can_create_pseudo_p ()) + { + rtx dst; + switch (GET_MODE (SUBREG_REG (op1))) + { + case V4SFmode: + case V8SFmode: + case V2DFmode: + case V4DFmode: + dst = gen_reg_rtx (GET_MODE (SUBREG_REG (op1))); + if (GET_CODE (op2) == CONST_VECTOR) + { + op2 = gen_lowpart (GET_MODE (dst), op2); + op2 = force_reg (GET_MODE (dst), op2); + } + else + { + op1 = operands[1]; + op2 = SUBREG_REG (operands[2]); + if (!nonimmediate_operand (op2, GET_MODE (dst))) + op2 = force_reg (GET_MODE (dst), op2); + } + op1 = SUBREG_REG (op1); + if (!nonimmediate_operand (op1, GET_MODE (dst))) + op1 = force_reg (GET_MODE (dst), op1); + emit_insn (gen_rtx_SET (VOIDmode, dst, + gen_rtx_fmt_ee (code, GET_MODE (dst), + op1, op2))); + emit_move_insn (operands[0], gen_lowpart (mode, dst)); + return; + default: + break; + } + } + if (!nonimmediate_operand (operands[1], mode)) + operands[1] = force_reg (mode, operands[1]); + if (!nonimmediate_operand (operands[2], mode)) + operands[2] = force_reg (mode, operands[2]); + ix86_fixup_binary_operands_no_copy (code, mode, operands); + emit_insn (gen_rtx_SET (VOIDmode, operands[0], + gen_rtx_fmt_ee (code, mode, operands[1], + operands[2]))); +} + /* Return TRUE or FALSE depending on whether the binary operator meets the appropriate constraints. */ diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 5234decc9784..6cf5651814a0 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -777,6 +777,12 @@ (ior (match_operand 0 "nonimmediate_operand") (match_operand 0 "const0_operand"))) +;; Return true when OP is either nonimmediate operand, or any +;; CONST_VECTOR. +(define_predicate "nonimmediate_or_const_vector_operand" + (ior (match_operand 0 "nonimmediate_operand") + (match_code "const_vector"))) + ;; Return true when OP is nonimmediate or standard SSE constant. (define_predicate "nonimmediate_or_sse_const_operand" (match_operand 0 "general_operand") diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 7934760624a3..d7fadd0df1f3 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -6264,10 +6264,13 @@ (define_expand "3" [(set (match_operand:VI 0 "register_operand") (any_logic:VI - (match_operand:VI 1 "nonimmediate_operand") - (match_operand:VI 2 "nonimmediate_operand")))] + (match_operand:VI 1 "nonimmediate_or_const_vector_operand") + (match_operand:VI 2 "nonimmediate_or_const_vector_operand")))] "TARGET_SSE" - "ix86_fixup_binary_operands_no_copy (, mode, operands);") +{ + ix86_expand_vector_logical_operator (, mode, operands); + DONE; +}) (define_insn "*3" [(set (match_operand:VI 0 "register_operand" "=x,x") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2ea0e80d7a72..9802c10e4840 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2012-09-28 Jakub Jelinek + PR target/54716 + * gcc.target/i386/xorps-sse2.c: Remove xfails. + PR tree-optimization/54713 * gcc.c-torture/compile/pr54713-1.c: New test. * gcc.c-torture/compile/pr54713-2.c: New test. diff --git a/gcc/testsuite/gcc.target/i386/xorps-sse2.c b/gcc/testsuite/gcc.target/i386/xorps-sse2.c index 3c268b4cbaa4..b9576d9700f0 100644 --- a/gcc/testsuite/gcc.target/i386/xorps-sse2.c +++ b/gcc/testsuite/gcc.target/i386/xorps-sse2.c @@ -1,8 +1,8 @@ /* Test that we generate xorps when the result is used in FP math. */ /* { dg-do compile } */ /* { dg-options "-O -msse2 -mno-sse3" } */ -/* { dg-final { scan-assembler "xorps\[ \t\]" { xfail *-*-* } } } */ -/* { dg-final { scan-assembler-not "pxor" { xfail *-*-* } } } */ +/* { dg-final { scan-assembler "xorps\[ \t\]" } } */ +/* { dg-final { scan-assembler-not "pxor" } } */ #define vector __attribute__ ((vector_size (16)))