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) */

Reply via email to