> From: Hans-Peter Nilsson <[email protected]>
> Date: Tue, 25 Aug 2026 17:50:01 +0200
> The only main issue is, that I'm curious why there are different orders
> for the "not" part of the combined operations in your rotsi_16_not as
> opposed to the other bit-negated variants, like bswapsi_not:
>
> > +(define_insn "<acc><anz><anzvc>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))))
>
> > +(define_insn "<acc><anz><anzvc>bitreversesi2_not<setcc><setnz><setnzvc>"
> > + [(set (match_operand:SI 0 "register_operand" "=r")
> > + (bitreverse:SI
> > + (not:SI (match_operand:SI 1 "register_operand" "0"))))
>
> Thoughts? Was either order a deliberate choice and if so, what was
> the reasoning?
>
> I'd say the second one is the canonical representation, except I can't
> find *specific* support for that in md.texi. It covers "not" moved
> into the operands of "and" and "or" (transforming the operation per
> DeMorgan's), not general bitwise operations. Maybe just a doc
> omission? Anyway, an unexpected inconsistency.
I'm guessing it was for pragmatic reasons, as changing the pattern to
(rotate (not ...)) doesn't match. I had a look using two gdb
sessions, tracing what combine did with the respective test-case. It
"thinks" rotate is a shift and "wants" to attempt to combine it with
outer operations, then leaving it at that, in simplify_shift_const_1.
There's also explicit code in simplify_unary_operation_1 handling
BITREVERSE and BSWAP, moving a NOT inside. I'm considering *trying*
to amend that, and have the canonical order documented as:
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index f86fa8038e8a..abc1523c70d3 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -9090,8 +9090,10 @@ 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. Other logical operations also
+have bitwise negation moved inside the first operand, possibly
+transforming the operation. 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
WDYT?
brgds, H-P