[EXTERNAL] Re: [PATCH] tree-optimization/103514 Missing XOR-EQ-AND Optimization

Navid Rahimi navidrahimi@microsoft.com
Mon Dec 6 21:33:23 GMT 2021


Hi Marc, thanks for clear explanation.

Actually I have to withdraw this patch. As you noticed there are some problems with this. I was testing it yesterday, and I did realize I made mistake combining different types in this pattern.

The same approach would work only and only if the types of every operand is boolean. But if there are any integer here, then this is not going to work.

For looking at example and link to proof in each case [1].

One actual example, with the input values is like this:

(a & b) ^ (a == b) -> !(a | b)

a = 2 and b = 2,
src :
(a == b) => true
(a & b) => 2
(a & b) ^ (a == b) => (2) ^ (true) => 3 (the compiler will consider true as 1) [2].

tgt:
(a | b) => 2
!(a | b) => !(2) => false.

Which means the transformation is incorrect for other types. (Same transformation does work for bool types, so I think in my next patch I will keep the approach and will restrict it to bool types only).

1) https://compiler-explorer.com/z/h7hcohY74
2) https://eel.is/c++draft/conv.prom#6

Best wishes,
Navid.

________________________________________
From: Marc Glisse <marc.glisse@inria.fr>
Sent: Saturday, December 4, 2021 13:22
To: gcc-patches@gcc.gnu.org
Cc: Navid Rahimi
Subject: [EXTERNAL] Re: [PATCH] tree-optimization/103514 Missing XOR-EQ-AND Optimization

[You don't often get email from marc.glisse@inria.fr. Learn why this is important at http://aka.ms/LearnAboutSenderIdentification.]

+/* (a & b) ^ (a == b) -> !(a | b) */
+/* (a & b) == (a ^ b) -> !(a | b) */
+(for first_op (bit_xor eq)
+     second_op (eq bit_xor)
+ (simplify
+  (first_op:c (bit_and:c @0 @1) (second_op:c @0 @1))
+   (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
+        && types_match (TREE_TYPE (@0), TREE_TYPE (@1)))
+    (convert (bit_not (bit_ior @0 @1))))))

I don't think you need types_match, if both are operands of bit_and, their
types must already match.

It isn't clear what the INTEGRAL_TYPE_P test is for. Your 2
transformations don't seem that similar to me. The first one requires that
a and b have the same type as the result of ==, so they are boolean-like.
The second one makes sense for more general integers, but then it looks
like it should produce (a|b)==0.

It doesn't look like we have a canonical representation between a^b and
a!=b for booleans :-(

(sorry for the broken thread, I was automatically unsubscribed because
mailman doesn't like greylisting)

--
Marc Glisse


More information about the Gcc-patches mailing list