From bd848fa1d8968ffbbc783c70bdecd8b365085e95 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Wed, 4 Feb 2026 23:48:55 -0300 Subject: [PATCH] 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 72c6bbb7d67..88aa95c8123 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 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). */ -- 2.47.3