Let's harmonize canonicalization for NOT-on-ROTATE and NOT-on-ROTATERT
with that of BSWAP and BITREVERSE, and document the canonical
form. Tested cross to cris-elf, native on x86_64-pc-linux-gnu.

Ok to commit?

brgds, H-P

-- >8 --
Before this patch, the combine pass would match (bitreverse:SI (not:SI
reg)) but not (rotate:SI (not:SI reg (const_int 16)))), instead
requiring (not:SI (rotate:SI reg (const_int 16))) for the compound
operation to be recognized.  That looked inconsistent considering that
both are bit-rearrangement operations commutative with bitwise negation.

I was about to write "operations with which bitwise negation is
commutative", but thought better list the operations explicitly.

        * doc/md.texi (Insn Canonicalizations): Document BITREVERSE,
        BSWAP, ROTATE, and ROTATERT as having the canonical form of
        NOT moved inside the first operand.
        * simplify-rtx.cc (simplify_context::simplify_unary_operation_1):
        Move a NOT to the inside of ROTATE and ROTATERT, like for BITREVERSE
        and BSWAP.
        * config/cris/cris.md (*rotsi2_16_not<setcc><setnz><setnzvc>): Adjust
        accordingly.
---
 gcc/config/cris/cris.md | 6 +++---
 gcc/doc/md.texi         | 7 +++++--
 gcc/simplify-rtx.cc     | 7 +++++++
 3 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md
index 1bb6ae96b1f7..d8ec890e3c53 100644
--- a/gcc/config/cris/cris.md
+++ b/gcc/config/cris/cris.md
@@ -2241,9 +2241,9 @@ (define_insn "*rotsi2_16<setcc><setnz><setnzvc>"
 
 (define_insn "*rotsi2_16_not<setcc><setnz><setnzvc>"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (not:SI
-        (rotate:SI (match_operand:SI 1 "register_operand" "0")
-                   (const_int 16))))
+       (rotate:SI
+        (not:SI (match_operand:SI 1 "register_operand" "0"))
+        (const_int 16)))
    (clobber (reg:CC CRIS_CC0_REGNUM))]
   "TARGET_HAS_SWAP"
   "swapnw %0"
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index f86fa8038e8a..abf64c9fddab 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -9090,8 +9090,11 @@ converted into the appropriate multiplication by a power 
of two.
 @cindex De Morgan's law
 @item
 De Morgan's Law is used to move bitwise negation inside a bitwise
-logical-and or logical-or operation.  If this results in only one
-operand being a @code{not} expression, it will be the first one.
+logical-and or logical-or operation.  The logical operations
+@code{bswap}, @code{bitreverse}, @code{rotate}, and @code{rotatert},
+also have the bitwise negation moved inside the first operand.  If
+this results in only one operand being a @code{not} expression, it
+will be the first one.
 
 A machine that has an instruction that performs a bitwise logical-and of one
 operand with the bitwise negation of the other should specify the pattern
diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index 66d7bb8d88a8..eba62e6b69e8 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -1069,6 +1069,13 @@ simplify_context::simplify_unary_operation_1 (rtx_code 
code, machine_mode mode,
          rtx x = simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
          return simplify_gen_unary (GET_CODE (op), mode, x, mode);
        }
+
+      /* (not (rotate x ...)) -> (rotate (not x) ...).  */
+      if (GET_CODE (op) == ROTATE || GET_CODE (op) == ROTATERT)
+       {
+         rtx x = simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
+         return simplify_gen_binary (GET_CODE (op), mode, x, XEXP (op, 1));
+       }
       break;
 
     case NEG:
-- 
2.43.0

Reply via email to