[PATCH] Canonicalize (vec_duplicate (not A)) to (not (vec_duplicate A)).

Liu, Hongtao hongtao.liu@intel.com
Fri Jun 4 02:48:19 GMT 2021



>-----Original Message-----
>From: Segher Boessenkool <segher@kernel.crashing.org>
>Sent: Friday, June 4, 2021 4:00 AM
>To: Liu, Hongtao <hongtao.liu@intel.com>
>Cc: Richard Biener <richard.guenther@gmail.com>; GCC Patches <gcc-
>patches@gcc.gnu.org>
>Subject: Re: [PATCH] Canonicalize (vec_duplicate (not A)) to (not
>(vec_duplicate A)).
>
>On Thu, Jun 03, 2021 at 11:03:43AM +0000, Liu, Hongtao wrote:
>> >A very typical example is how UMIN is optimised:
>> >
>> >   case UMIN:
>> >      if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
>> >	return op1;
>> >      if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
>> >	return op0;
>> >      tem = simplify_associative_operation (code, mode, op0, op1);
>> >      if (tem)
>> >	return tem;
>> >      break;
>> >
>> >(the stuff using "tem").
>> >
>> >Hongtao, can we do something similar here?  Does that work well?
>> >Please try it out :-)
>>
>> In simplify_rtx, no simplication occurs, there is just the difference
>> between  (vec_duplicate (not REG)) and (not (vec_duplicate (REG)). So here
>tem will only be 0.
>
>simplify-rtx is used by combine.  When you do and+not+splat for example my
>suggestion should kick in.  Try it out, don't just dismiss it?
>
Forgive my obtuseness, do you mean try the following changes, if so then there will be no "kick in", 
temp will be 0, there's no simplification here since it's just the difference between  (vec_duplicate (not REG))
 and (not (vec_duplicate (REG)). Or maybe you mean something else?

@@ -1708,6 +1708,17 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
 #endif
       break;

+      /* Canonicalize (vec_duplicate (not A)) to (not (vec_duplicate A)).  */
+    case VEC_DUPLICATE:
+      if (GET_CODE (op) == NOT)
+       {
+         rtx vec_dup = gen_rtx_VEC_DUPLICATE (mode, XEXP (op, 0));
+         temp = simplify_unary_operation (NOT, mode, vec_dup, GET_MODE (op));
+         if (temp)
+           return temp;
+       }
+      break;
+
>> Basically we don't know it's a simplication until combine successfully
>> split the
>> 3->2 instructions (not + broadcast + and to andnot + broadcast), but
>> 3->it's pretty awkward
>> to do this in combine.
>
>But you need to do this *before* it is split.  That is the whole point.
>
>> Consider andnot is existed for many backends, I think a canonicalization is
>needed here.
>
>Please do note that that is not as easy as yoou may think: you need to make
>sure nothing ever creates non-canonical code.
>
>> Maybe we can add insn canonicalization for transforming (and
>> (vect_duplicate (not A)) B) to (and (not (duplicate (not A)) B) instead of
>(vec_duplicate (not A)) to (not (vec_duplicate A))?
>
>I don't understand what this means?
I mean let's give a last shot for andnot in case AND like below

@ -3702,6 +3702,16 @@ simplify_context::simplify_binary_operation_1 (rtx_code code,
       tem = simplify_associative_operation (code, mode, op0, op1);
       if (tem)
        return tem;
+
+      if (GET_CODE (op0) == VEC_DUPLICATE
+         && GET_CODE (XEXP (op0, 0)) == NOT)
+       {
+         rtx vec_dup = gen_rtx_VEC_DUPLICATE (GET_MODE (op0),
+                                              XEXP (XEXP (op0, 0), 0));
+         return simplify_gen_binary (AND, mode,
+                                     gen_rtx_NOT (mode, vec_dup),
+                                     op1);
+       }
       break;
>
>
>Segher


More information about the Gcc-patches mailing list