https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82854
Bug ID: 82854 Summary: more missing simplifcations Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: andi-gcc at firstfloor dot org Target Milestone: --- These all come from a paper "Optgen: A Generator for Local Optimizations" (Buchwald et.al.). https://pp.info.uni-karlsruhe.de/uploads/publikationen/buchwald15cc.pdf These were found by a SAT solver. I wrote them in partial pseudo match.pd syntax (untested, likely buggy) I'm not sure how useful they are really for real programs, but with the auto generated matchers scaling well to more rules they wouldn't hurt I suppose. /* x + (x & 0x80000000) -> x & 0x7fffffff */ (simplify (plus:c @0 (bit_and @0 integer_msb_onlyp@1)) (bit_and @0 { @1 - 1; } )) /* (x | 0x80000000) + 0x80000000 -> x & 0x7FFFFFFF */ (simplify (plus:c (bit_ior @0 integer_msb_onlyp) msb_setp) (bit_and @0 { msb_minus_one_val(type); } )) /* x & (x + 0x80000000) -> x & 0x7FFFFFFF */ (simplify (bit_and:c (plus @0 msb_setp) @0) (bit_and @0 { msb_minus_one_val(type); } )) /* x & (0x7FFFFFFF - x) -> x & 0x80000000 */ (simplify (bit_and:c @0 (minus msb_minus_onep @0)) (bit_and @0 { msb_val(type); } )) /* is_power_of_2(c1) && c0 & (2 * c1 - 1) == c1 - 1 -> (c0 - x) & c1 -> x & c1 */ /* x | (x + 0x80000000) -> x | 0x80000000 */ (simplify (bit_ior:c @0 (plus @0 msb_onlyp)) (bit_ior @0 { msb_val(type); } )) /* x | (0x7FFFFFFF - x) -> x | 0x7FFFFFFF */ (simplify (bit_ior:c @0 (minus 0x7FFFFFFF @0)) (bit_ior @0 0x7FFFFFFF)) /* x | (x ^ y) -> x | y */ (simplify (bit_ior:c @0 (bit_xor:c @0 @1)) (bit_ior @0 @1)) /* ((c0 | -c0) & ∼c1) == 0 AND (x + c0) | c1 -> x | c1 */ /* is_power_of_2(∼c1) && c0 & (2 * ∼c1 - 1) == ∼c1 - 1 AND (c0 - x) | c1 -> x | c1 */ /* -x | 0xFFFFFFFE -> x | 0xFFFFFFFE */ (simplify (bit_or (negate @0) 0xFFFFFFFE) (bit_or @0 0xFFFFFFFE)) /* 0 - (x & 0x80000000) -> x & 0x80000000 */ (simplify (minus 0 (bit_and:c @0 0x80000000)) (bit_and @0 0x80000000)) /* 0x7FFFFFFF - (x & 0x80000000) -> x | 0x7FFFFFFF */ (simplify (minus 0x7FFFFFFF (bit_and @0 0x80000000)) (bit_ior @0 0x7FFFFFFF)) /* 0x7FFFFFFF - (x | 0x7FFFFFFF) -> x & 0x80000000 */ (simplify (minus 0x7FFFFFFF (bit_ior:c @0 0x7FFFFFFF)) (bit_and @0 0x80000000)) /* 0xFFFFFFFE - (x | 0x7FFFFFFF) -> x | 0x7FFFFFFF */ (simplify (minus 0xFFFFFFFE (bit_ior:c @0 0x7FFFFFFF)) (bit_ior @0 0x7FFFFFFF)) /* (x & 0x7FFFFFFF) - x -> x & 0x80000000 */ (simplify (minus (bit_and:c @0 0x7FFFFFFF) @0) (bit_and @0 0x80000000)) /* x ^ (x + 0x80000000) -> 0x80000000 */ (simplify (bit_xor:c (plus:c @0 0x80000000)) 0x80000000) /* x ^ (0x7FFFFFFF - x) -> 0x7FFFFFFF */ (simplify (bit_xor:c @0 (minus 0x7FFFFFFF @0)) 0x7FFFFFFF) /* (x + 0x7FFFFFFF) ^ 0x7FFFFFFF -> -x */ (simplify (bit_xor:c (plus:c @0 0x7FFFFFFF) 0x7FFFFFFF) (negate @0)) /* -x ^ 0x80000000 -> 0x80000000 - x */ (simplify (bit_xor:c (negate @0) 0x80000000) (minus 0x80000000 @0)) /* (0x7FFFFFFF - x) ^ 0x7FFFFFFF -> x */ (simplify (bit_xor:c (minus 0x7FFFFFFF @0) 0x7FFFFFFF) @0) /* ~(x + c) -> ~c - x */ (simplify (bit_not (plus:c @0 CONSTANT_CLASS_P@1)) (minus (bit_not c) @0)) /* -x ^ 0x7FFFFFFF -> x + 0x7FFFFFFF */ (simplify (bit_xor (negate @0) 0x7FFFFFFF) (plus @0 0x7FFFFFFF)) /* (x | c) - c -> x & ∼c */ (simplify (minus (bit_ior @0 CONSTANT_CLASS_P@1) @1) (bit_and @0 (bit_not @1))) /* ~(c - x) -> x + ∼c */ (simplify (bit_not (minus CONSTANT_CLASS_P@0 @1)) (plus @1 (bit_not @0))) /* -c0 == c1 AND (x | c0) + c1 -> x & ∼c1 */ (simplify (plus (bit_or @0 CONSTANT_CLASS_P@1) CONSTANT_CLASS_P@2) (if (...) (bit_and @0 (bit_not @2)) /* (c0 & ∼c1) == 0 AND (x ^ c0) | c1 -> x | c1 */ /* 0x7FFFFFFF - (x ^ c) -> x ^ (0x7FFFFFFF - c) */