This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] PR target/66144, PowerPC improve vector compare
- From: Segher Boessenkool <segher at kernel dot crashing dot org>
- To: Michael Meissner <meissner at linux dot vnet dot ibm dot com>, gcc-patches at gcc dot gnu dot org, David Edelsohn <dje dot gcc at gmail dot com>, Bill Schmidt <wschmidt at linux dot vnet dot ibm dot com>
- Date: Fri, 3 Feb 2017 18:07:56 -0600
- Subject: Re: [PATCH] PR target/66144, PowerPC improve vector compare
- Authentication-results: sourceware.org; auth=none
- References: <20170203212459.GA5647@ibm-tiger.the-meissners.org>
On Fri, Feb 03, 2017 at 04:25:00PM -0500, Michael Meissner wrote:
> +;; Return 1 if operand is either a vector constant of all 0 bits of a vector
> +;; constant of all 1 bits.
> +(define_predicate "vector_int_same_bit"
> + (match_code "const_vector")
> +{
> + if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
> + return 0;
> +
> + else
> + return op == CONST0_RTX (mode) || op == CONSTM1_RTX (mode);
> +})
This predicate is unused as far as I see?
> + /* Optimize vec1 == vec2, to know the mask generates -1/0. */
> + if (GET_MODE_CLASS (dest_mode) == MODE_VECTOR_INT)
> {
> - tmp = op_true;
> - op_true = op_false;
> - op_false = tmp;
> + if (op_true == constant_m1 && op_false == constant_0)
> + {
> + emit_move_insn (dest, mask);
> + return 1;
> + }
> +
> + else if (op_true == constant_0 && op_false == constant_m1)
> + {
> + emit_insn (gen_rtx_SET (dest, gen_rtx_NOT (dest_mode, mask)));
> + return 1;
> + }
> }
Do you need to test for dest_mode == mask_mode here, like below?
> + if (op_true == constant_m1 && dest_mode == mask_mode)
> + op_true = mask;
> + else if (!REG_P (op_true) && !SUBREG_P (op_true))
> + op_true = force_reg (dest_mode, op_true);
> +
> + if (op_false == constant_0 && dest_mode == mask_mode)
> + op_false = mask;
> + else if (!REG_P (op_false) && !SUBREG_P (op_false))
> + op_false = force_reg (dest_mode, op_false);
Another thing you could try is, if either op_true or op_false is 0
or -1, let the result be
(mask & op_true) | (~mask & op_false)
and let the rest of the optimisers sort it out (it's a single vor/vand
or vorc/vandc, or a vnot, or nothing). A later improvement perhaps.
Or does it already handle all cases now :-)
Okay for trunk with the unused predicate removed, and the dest_mode ==
mask_mode thing looked at. Thanks!
Segher