On Thu, 13 Aug 2026 09:53:28 GMT, Quan Anh Mai <[email protected]> wrote:

>>> Since these transformations are similar between different kinds of 
>>> `XorNode` (scalar, vector, mask). I suggest refactoring it to a separate 
>>> function that gets called from those places.
>> 
>> Thanks for the suggestion. Just to make sure I understand correctly: are you 
>> proposing that we extract the `(A & B) ^ B → ~A & B` rewrite into a shared 
>> helper and call it from scalar `XorI/XorL` as well as from vector/mask 
>> `XorV/XorVMask`?
>> 
>> If so, that is feasible for the pattern-matching part (finding the And, 
>> handling commutativity, checking single-use / TOP). I prototyped that 
>> briefly. The limitation is that constructing the rewritten graph does not 
>> share cleanly across these cases:
>> 
>> - scalar uses `XorI/L` + `AndI/L`
>> 
>> - vector/mask uses `Replicate/MaskAll` + `XorV/XorVMask` + `AndV/AndVMask`
>> 
>> - vector also needs extra checks that scalar does not (e.g. rejecting 
>> predicated `XorV/AndV`)
>> 
>> So beyond the matcher, each Ideal path still needs its own node-building 
>> glue, and folding scalar into this change would expand the scope (and tests) 
>> quite a bit.
>> 
>> I’d prefer to keep this RFE focused on the `vector/mask` canonicalize (which 
>> already shares one Ideal path for `XorV` and `XorVMask`), and file a 
>> follow-up RFE for the scalar side (and any further shared-helper cleanup) if 
>> that sounds reasonable to you.
>
> @erifan Thanks for your response. The issue I see is that there are a lot of 
> different patterns, and each time we will just say well we only want to focus 
> on vector/mask canonicalization. And with more patterns getting integrated, 
> it will take us more work to consolidate the implementations between the 
> vector nodes and the scalar nodes.
> 
> My idea is that we will have a utility object `ArithmeticPattern` (for 
> example) which can be constructed from an arithmetic node. The object will 
> know what the element type is, how to create a constant, how to check whether 
> a node is a constant, or if it is a particular constant. With template, the 
> checks can be much easier. For example (you can probably think of a better 
> way, this is just my first thought):
> 
>     enum class NodeTypeCon {
>       INT,
>       LONG,
>       VECTOR
>     }
> 
>     template <class NodeClass>
>     class NodeType;
> 
>     template<>
>     class NodeType<XorINode> {
>       static constexpr NodeTypeCon value = INT;
>     };
> 
>     template <NodeTypeCon nodeType>
>     Node* create_xor(Node* op1, Node op2);
> 
>     template <>
>     Node* create_xor<NodeTypeCon::INT>(Node* op1, Node op2) {
>       return new XorINode(op1, op2);
>     }
> 
> This will allow us to extend these transformations easier across different 
> data types, and reduce the work to implement more pattern for vector/mask 
> nodes in the future.

Hi @merykitty, thanks for the suggestion — I agree it is reasonable.

Would you prefer that we expand this PR’s scope to also cover the scalar side 
(`XorI` / `XorL`), or keep the current focus on vector and vector mask only?

@dean-long @theRealAph, what do you think?

-------------

PR Comment: https://git.openjdk.org/jdk/pull/32095#issuecomment-5289391600

Reply via email to