Hi Roger,

On 2026-08-11 12:18, Roger Sayle wrote:

Hi Torbjorn,
I believe this size regression on ARM (thumb) is resolved by the attached patch.
This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
and make -k check, both with and without --target_board=unix{-m32}
with no new failures.  Ok for mainline?

I've tested your patch on top of r17-2833-g32657f29f91871 and I see no 
regression
for arm-none-eabi targets that I usually test.
So, from an arm-none-eabi point of view, this is ok, but you need to get
approval from a maintainer.

Kind regards,
Torbjörn


Hopefully, Jeff can spin this on his farm to see whether this transformation
is still useful anywhere (and not just creating problems on ARM)?

2026-08-11  Roger Sayle  <[email protected]>

gcc/ChangeLog
         * combine.cc (simplify_comparison) <case AND>: Delete
         transformation that changed (AND (SUBREG x) C) into the
         non-canonical (SUBREG (AND (x C)).

Thanks in advance,
Cheers,
Roger
--

-----Original Message-----
From: Torbjorn SVENSSON <[email protected]>
Sent: 10 August 2026 16:28
To: Richard Biener <[email protected]>; Roger Sayle
<[email protected]>; Richard Earnshaw (lists)
<[email protected]>
Cc: GCC Patches <[email protected]>; Jeffrey Law
<[email protected]>; Richard Sandiford
<[email protected]>
Subject: Re: [PATCH v2] PR middle-end/123236: Simplify (int)((long long)x >> 4)

Hi,

This change introduces a (size) regression for arm-none-eabi:


Testing arm/pr42879.c
doing compile
Executing on host: /build/r17-2833-g32657f29f91871/bin/arm-none-eabi-gcc
/build/gcc_src/gcc/testsuite/gcc.target/arm/pr42879.c  -mthumb -
march=armv7-m -mcpu=cortex-m3 -mfloat-abi=soft -mfpu=auto   -fdiagnostics-
plain-output  -mthumb -Os -ffat-lto-objects -fno-ident -S     -o pr42879.s
(timeout = 800)
spawn -ignore SIGHUP /build/r17-2833-g32657f29f91871/bin/arm-none-eabi-gcc
/build/gcc_src/gcc/testsuite/gcc.target/arm/pr42879.c -mthumb -march=armv7-
m -mcpu=cortex-m3 -mfloat-abi=soft -mfpu=auto -fdiagnostics-plain-output -
mthumb -Os -ffat-lto-objects -fno-ident -S -o pr42879.s pid is 180 -180 pid is 
-1
output is  status 0

PASS: gcc.target/arm/pr42879.c (test for excess errors)
FAIL: gcc.target/arm/pr42879.c scan-assembler lsls



$ /build/r17-2412-g2fcbe075ec3b32/bin/arm-none-eabi-gcc
/build/gcc_src/gcc/testsuite/gcc.target/arm/pr42879.c -mthumb -march=armv7-
m -mcpu=cortex-m3 -mfloat-abi=soft -mfpu=auto -Os -fno-ident -S -o -
          .cpu cortex-m3
          .arch armv7-m
          .fpu softvfp
          .eabi_attribute 20, 1
          .eabi_attribute 21, 1
          .eabi_attribute 23, 3
          .eabi_attribute 24, 1
          .eabi_attribute 25, 1
          .eabi_attribute 26, 1
          .eabi_attribute 30, 4
          .eabi_attribute 34, 1
          .eabi_attribute 18, 4
          .file   "pr42879.c"
          .text
          .align  1
          .global foo
          .syntax unified
          .thumb
          .thumb_func
          .type   foo, %function
foo:
          @ args = 0, pretend = 0, frame = 0
          @ frame_needed = 0, uses_anonymous_args = 0
          @ link register save eliminated.
          ldrb    r3, [r0]        @ zero_extendqisi2
          lsls    r3, r3, #31
          bmi     .L2
          b       bar
.L2:
          movs    r0, #1
          bx      lr
          .size   foo, .-foo


$ /build/r17-2413-ge46d96d20bbfa7/bin/arm-none-eabi-gcc
/build/gcc_src/gcc/testsuite/gcc.target/arm/pr42879.c -mthumb -march=armv7-
m -mcpu=cortex-m3 -mfloat-abi=soft -mfpu=auto -Os -fno-ident -S -o -
          .cpu cortex-m3
          .arch armv7-m
          .fpu softvfp
          .eabi_attribute 20, 1
          .eabi_attribute 21, 1
          .eabi_attribute 23, 3
          .eabi_attribute 24, 1
          .eabi_attribute 25, 1
          .eabi_attribute 26, 1
          .eabi_attribute 30, 4
          .eabi_attribute 34, 1
          .eabi_attribute 18, 4
          .file   "pr42879.c"
          .text
          .align  1
          .global foo
          .syntax unified
          .thumb
          .thumb_func
          .type   foo, %function
foo:
          @ args = 0, pretend = 0, frame = 0
          @ frame_needed = 0, uses_anonymous_args = 0
          @ link register save eliminated.
          ldrb    r3, [r0]        @ zero_extendqisi2
          and     r3, r3, #1
          cbnz    r3, .L2
          b       bar
.L2:
          movs    r0, #1
          bx      lr
          .size   foo, .-foo



Kind regards,
Torbjörn

On 2026-07-14 11:07, Richard Biener wrote:
On Fri, Jul 10, 2026 at 7:44 PM Roger Sayle <[email protected]>
wrote:


Long story... Back in January I proposed the following patch:
https://gcc.gnu.org/pipermail/gcc-patches/2026-January/705292.html
which contained two pieces, one in combine, the other in simplify-rtx.
Both of which were initially approved by Jeff Law here
https://gcc.gnu.org/pipermail/gcc-patches/2026-May/715595.html
but then Richard Sandiford pointed out the combine piece might cause
problems on RISC machines, and suggested improvements.
https://gcc.gnu.org/pipermail/gcc-patches/2026-May/715668.html

In addition to making Richard's recommended changes, I've also
decided to split the patch into two, to enable bisection and isolate
these transformations [in case Richard S's fears come to pass and the
combine transformation needs to be reverted].

This is the "safe" (or less controversial) half.  Hopefully, folks
are (still) happy for this bit to be committed?
p.s. the second and third hunks are just micro-optimizations; we
don't need to call simplify_gen_unary (TRUNCATE, ...) if the operand
already has the correct mode.  The significant change is that the
modes don't need to match, and the operand need not be a register
[combine can put anything in a SUBREG].

This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
and make -k check, both with and without --target_board=unix{-m32},
with no new failures.  Ok for mainline?

OK.

Thanks,
Richard.


2026-07-10  Roger Sayle  <[email protected]>

gcc/ChangeLog
          PR rtl-optimization/123236
          * simplify-rtx.cc (simplify_context::simplify_truncation): Handle
          cases where a ZERO_EXTRACT or SIGN_EXTRACT has a different mode
          to (but at least as wide as) its first operand.

gcc/testsuite/ChangeLog
          PR rtl-optimization/123236
          * gcc.target/i386/pr123236-1.c: New test case.


Thank again,
Roger
--



patchas.txt

diff --git a/gcc/combine.cc b/gcc/combine.cc
index 53ea168a44b..bb3d41bafd7 100644
--- a/gcc/combine.cc
+++ b/gcc/combine.cc
@@ -12869,50 +12869,6 @@ simplify_comparison (enum rtx_code code, rtx *pop0, 
rtx *pop1)
              continue;
            }
- /* If this is (and:M1 (subreg:M1 X:M2 0) (const_int C1)) where C1
-            fits in both M1 and M2 and the SUBREG is either paradoxical
-            or represents the low part, permute the SUBREG and the AND
-            and try again.  */
-         if (GET_CODE (XEXP (op0, 0)) == SUBREG
-             && CONST_INT_P (XEXP (op0, 1)))
-           {
-             unsigned HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
-             /* Require an integral mode, to avoid creating something like
-                (AND:SF ...).  */
-             if ((is_a <scalar_int_mode>
-                  (GET_MODE (SUBREG_REG (XEXP (op0, 0))), &tmode))
-                 /* It is unsafe to commute the AND into the SUBREG if the
-                    SUBREG is paradoxical and WORD_REGISTER_OPERATIONS is
-                    not defined.  As originally written the upper bits
-                    have a defined value due to the AND operation.
-                    However, if we commute the AND inside the SUBREG then
-                    they no longer have defined values and the meaning of
-                    the code has been changed.
-                    Also C1 should not change value in the smaller mode,
-                    see PR67028 (a positive C1 can become negative in the
-                    smaller mode, so that the AND does no longer mask the
-                    upper bits).  */
-                 && ((WORD_REGISTER_OPERATIONS
-                      && mode_width > GET_MODE_PRECISION (tmode)
-                      && mode_width <= BITS_PER_WORD
-                      && trunc_int_for_mode (c1, tmode) == (HOST_WIDE_INT) c1)
-                     || (mode_width <= GET_MODE_PRECISION (tmode)
-                         && subreg_lowpart_p (XEXP (op0, 0))))
-                 && mode_width <= HOST_BITS_PER_WIDE_INT
-                 && HWI_COMPUTABLE_MODE_P (tmode)
-                 && (c1 & ~mask) == 0
-                 && (c1 & ~GET_MODE_MASK (tmode)) == 0
-                 && c1 != mask
-                 && c1 != GET_MODE_MASK (tmode))
-               {
-                 op0 = simplify_gen_binary (AND, tmode,
-                                            SUBREG_REG (XEXP (op0, 0)),
-                                            gen_int_mode (c1, tmode));
-                 op0 = gen_lowpart (mode, op0);
-                 continue;
-               }
-           }
-
          /* Convert (ne (and (not X) 1) 0) to (eq (and X 1) 0).  */
          if (const_op == 0 && equality_comparison_p
              && XEXP (op0, 1) == const1_rtx

Reply via email to