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