From 0340177d54d08b6375391ba164a878e6a596275e Mon Sep 17 00:00:00 2001
From: Andrew Pinski <quic_apinski@quicinc.com>
Date: Tue, 29 Jul 2025 21:49:16 -0700
Subject: [PATCH v2] simplify-rtx: Add `(subreg (not a))` simplification for
 word_mode [PR121308]

Right now in simplify_subreg, there is code to try to simplify for word_mode
with the binary bitwise operators. The unary bitwise operator is not handle,
this causes an odd mix match and the new self testing code that was added with
r16-2614-g965564eafb721f was not expecting.

The self testing code was for testing the newly added code but since there
was already code that handles word_mode, we hit the mismatch but only
for targets where word_mode is SImode (or smaller).

This adds the code to handle `not` in a similar fashion as the other
bitwise operators for word_mode.

Changes since v1:
* v2: add `&& SCALAR_INT_MODE_P (innermode)` to the conditional.

Bootstrapped and tested on x86_64-linux-gnu.

	PR rtl-optimization/121308
gcc/ChangeLog:

	* simplify-rtx.cc (simplify_context::simplify_subreg): Handle
	subreg of `not` with word_mode to make it symmetric with the
	other bitwise operators.

Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
---
 gcc/simplify-rtx.cc | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index 442da9f40fa..c723a07f06b 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -8344,6 +8344,15 @@ simplify_context::simplify_subreg (machine_mode outermode, rtx op,
 	return simplify_gen_binary (GET_CODE (op), outermode, op0, op1);
     }
 
+  /* Attempt to simplify WORD_MODE SUBREGs of unary bitwise expression.  */
+  if (outermode == word_mode && GET_CODE (op) == NOT
+      && SCALAR_INT_MODE_P (innermode))
+    {
+      rtx op0 = simplify_subreg (outermode, XEXP (op, 0), innermode, byte);
+      if (op0)
+	return simplify_gen_unary (GET_CODE (op), outermode, op0, outermode);
+    }
+
   scalar_int_mode int_outermode, int_innermode;
   if (is_a <scalar_int_mode> (outermode, &int_outermode)
       && is_a <scalar_int_mode> (innermode, &int_innermode)
-- 
2.43.0

