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