On Fri, 19 Jun 2015, Marek Polacek wrote:

+/* x + y - (x | y) -> x & y */
+(simplify
+ (minus (plus @0 @1) (bit_ior @0 @1))
+ (if (!TYPE_OVERFLOW_SANITIZED (type) && !TYPE_SATURATING (type))
+  (bit_and @0 @1)))
+
+/* (x + y) - (x & y) -> x | y */
+(simplify
+ (minus (plus @0 @1) (bit_and @0 @1))
+ (if (!TYPE_OVERFLOW_SANITIZED (type) && !TYPE_SATURATING (type))
+  (bit_ior @0 @1)))

It could be macroized so they are handled by the same piece of code, but that's not important for a couple lines.

As far as I can tell, TYPE_SATURATING is for fixed point numbers only, are we allowed to use bit_ior/bit_and on those? I never know what kind of integers are supposed to be supported, so I would have checked TYPE_OVERFLOW_UNDEFINED (type) || TYPE_OVERFLOW_WRAPS (type) since those are the 2 cases where we know it is safe (for TYPE_OVERFLOW_TRAPS it is never clear if we are supposed to preserve traps or just avoid introducing new ones). Well, the reviewer will know, I'll shut up :-)

(I still believe that the necessity for TYPE_OVERFLOW_SANITIZED here points to a design issue in ubsan, but it is way too late to discuss that)

It is probably not worth the trouble adding the variant:
x+(y-(x&y)) -> x|y
since it decomposes as
y-(x&y) -> y&~x
x+(y&~x) -> x|y
x+(y-(x|y)) -> x-(x&~y) -> x&y is less likely to happen because the first transform y-(x|y) -> -(x&~y) increases the number of insns. Bah, we can't handle everything...

--
Marc Glisse

Reply via email to