On Feb 1, 2026, Jeffrey Law <[email protected]> wrote:
>> * simplify-rtx.cc (negated_ops_p): New.
>> (simpify_context::simplify_binary_operation_1): Use it.
> So the argument would be that we have a regression due to r15-9239?
Yup. The testcase used to pass, and then it started failing.
> I'm a bit surprised I didn't notice this on riscv64-elf in my testing.
Hmm, could it be that these patterns I observed are specific to some of
the boards we use for testing, and don't apply to you? My testing that
caught this problem was targeting spike.
> Formatting nits with the final close paren. Belongs on the previous line.
*nod*, sorry about that, I also caught that myself just at the moment I
hit send :-/ So now you may know how I write long conditions to reason
about them ;-)
>> + /* ??? Should we consider rotations of C and ~C by the same amount? */
> Probably. Though testcases would be helpful here. Defer since this
> issue may not be a regression?
I don't even know whether that comes up, it was just a possibility that
crossed my mind.
> OK with the formatting nit addressed assuming you're considering this
> a gcc-15/gcc-16 regression.
Here's what I've just put in for gcc-16.
simplify-rtx: fix riscv redundant-bitmap-2.C
The insn simplification expected by the test, to get a bset
instruction, has been prevented since r15-9239, because we get rotates
for bit clear and shifts for bit flip, and we don't know how to
simplify those.
Teach the rtl simplifier, at the spots where it had been extended to
handle these logical simplifications, to also handle these less
obvious negations.
for gcc/ChangeLog
* simplify-rtx.cc (negated_ops_p): New.
(simplify_context::simplify_binary_operation_1): Use it.
---
gcc/simplify-rtx.cc | 53 +++++++++++++++++++++++++++++++++++++++------------
1 file changed, 41 insertions(+), 12 deletions(-)
diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index 72c6bbb7d6713..88aa95c812327 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -3074,6 +3074,39 @@ simplify_with_subreg_not (rtx_code binop, machine_mode
mode, rtx op0, rtx op1)
return simplify_gen_binary (binop, mode, op0, new_not);
}
+/* Return TRUE iff NOP is a negated form of OP, or vice-versa. */
+static bool
+negated_ops_p (rtx nop, rtx op)
+{
+ /* Explicit negation. */
+ if (GET_CODE (nop) == NOT
+ && rtx_equal_p (XEXP (nop, 0), op))
+ return true;
+ if (GET_CODE (op) == NOT
+ && rtx_equal_p (XEXP (op, 0), nop))
+ return true;
+
+ /* (~C <r A) is a negated form of (C << A) if C == 1. */
+ if (GET_CODE (op) == ASHIFT
+ && GET_CODE (nop) == ROTATE
+ && XEXP (op, 0) == CONST1_RTX (GET_MODE (op))
+ && CONST_INT_P (XEXP (nop, 0))
+ && INTVAL (XEXP (nop, 0)) == -2
+ && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
+ return true;
+ if (GET_CODE (nop) == ASHIFT
+ && GET_CODE (op) == ROTATE
+ && XEXP (nop, 0) == CONST1_RTX (GET_MODE (op))
+ && CONST_INT_P (XEXP (nop, 0))
+ && INTVAL (XEXP (nop, 0)) == -2
+ && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
+ return true;
+
+ /* ??? Should we consider rotations of C and ~C by the same amount? */
+
+ return false;
+}
+
/* Subroutine of simplify_binary_operation. Simplify a binary operation
CODE with result mode MODE, operating on OP0 and OP1. If OP0 and/or
OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
@@ -3861,8 +3894,7 @@ simplify_context::simplify_binary_operation_1 (rtx_code
code,
/* Convert (ior (and (not A) B) A) into A | B. */
if (GET_CODE (op0) == AND
- && GET_CODE (XEXP (op0, 0)) == NOT
- && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1))
+ && negated_ops_p (XEXP (op0, 0), op1))
return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
tem = simplify_with_subreg_not (code, mode, op0, op1);
@@ -4133,8 +4165,7 @@ simplify_context::simplify_binary_operation_1 (rtx_code
code,
/* Convert (xor (and (not A) B) A) into A | B. */
if (GET_CODE (op0) == AND
- && GET_CODE (XEXP (op0, 0)) == NOT
- && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1))
+ && negated_ops_p (XEXP (op0, 0), op1))
return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
/* Convert (xor (and (rotate (~1) A) B) (ashift 1 A))
@@ -4413,21 +4444,19 @@ simplify_context::simplify_binary_operation_1 (rtx_code
code,
&& rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
- /* (and (ior/xor (X Y) (not Y)) -> X & ~Y */
+ /* (and (ior/xor X Y) (not Y)) -> X & ~Y */
if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
- && GET_CODE (op1) == NOT
- && rtx_equal_p (XEXP (op1, 0), XEXP (op0, 1)))
+ && negated_ops_p (op1, XEXP (op0, 1)))
return simplify_gen_binary (AND, mode, XEXP (op0, 0),
simplify_gen_unary (NOT, mode,
- XEXP (op1, 0),
+ XEXP (op0, 1),
mode));
- /* (and (ior/xor (Y X) (not Y)) -> X & ~Y */
+ /* (and (ior/xor Y X) (not Y)) -> X & ~Y */
if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
- && GET_CODE (op1) == NOT
- && rtx_equal_p (XEXP (op1, 0), XEXP (op0, 0)))
+ && negated_ops_p (op1, XEXP (op0, 0)))
return simplify_gen_binary (AND, mode, XEXP (op0, 1),
simplify_gen_unary (NOT, mode,
- XEXP (op1, 0),
+ XEXP (op0, 0),
mode));
/* Convert (and (ior A C) (ior B C)) into (ior (and A B) C). */
--
Alexandre Oliva, happy hacker https://blog.lx.oliva.nom.br/
Free Software Activist FSFLA co-founder GNU Toolchain Engineer
More tolerance and less prejudice are key for inclusion and diversity.
Excluding neuro-others for not behaving ""normal"" is *not* inclusive!