[Bug middle-end/122871] [13/14/15/16/17 Regression] de-optimized synthesis of long long shift and add

2026-06-05 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122871

--- Comment #17 from GCC Commits  ---
The master branch has been updated by Roger Sayle :

https://gcc.gnu.org/g:373e2c30b1710e271664cf95fcfb66fea7dd15ed

commit r17-1373-g373e2c30b1710e271664cf95fcfb66fea7dd15ed
Author: Roger Sayle 
Date:   Fri Jun 5 14:53:27 2026 +0100

PR target/56102: Improve rtx_costs from -mthumb on ARM.

This patch provides improved (more accurate) RTX costs for -mthumb on ARM.
My recent patch for double word multiplication, PR 122871, revealed that
the current costs for THUMB code on ARM are... let's say a little dubious.

To demonstrate the code generation improvements provided by better
thumb1_rtx_costs consider the function below (from PR middle-end/122871).

long long foo (long long a)
{
  long long c = a << 33;
  c += a;
  return c;
}

With the ARM backend's current costs, this produces 11 instructions with
-O2 -mthumb.

Before: movsr3, r0
movsr2, #0
addsr2, r2, r0
adcsr3, r3, r1
addsr2, r2, r2
adcsr3, r3, r3
subsr2, r2, r0
sbcsr3, r3, r1
movsr0, r2
movsr1, r3
bx  lr

With sane RTX costs, GCC now generate the much more reasonable 5 insns:

After:  movsr2, #0
lslsr3, r0, #1
addsr0, r0, r2
adcsr1, r1, r3
bx  lr

2026-06-05  Roger Sayle  
Richard Earnshaw  

gcc/ChangeLog
PR target/56102
PR middle-end/122871
* config/arm/arm.cc (thumb1_rtx_costs): Provide reasonable costs
for PLUS, MINUS, COMPARE, AND, XOR, IOR, NEG, NOT, ASHIFT,
ASHIFTRT and ROTATERT for SImode, DImode, HImode and QImode.
(thumb1_size_rtx_costs): Likewise.

(comp_not_to_clear_mask_str_un): Silence host compiler warning.

[Bug middle-end/122871] [13/14/15/16/17 Regression] de-optimized synthesis of long long shift and add

2026-05-15 Thread roger at nextmovesoftware dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122871

--- Comment #16 from Roger Sayle  ---
The slightly unusual results from synth_mult on ARM with -mthumb are due to
incorrect values being returned by rtx_costs.  DImode addition and subtraction
should both be COSTS_N_INSNS(2), i.e. adds+adcs and subs+sbcs respectively, but
currently return COSTS_N_INSNS(1).

[Bug middle-end/122871] [13/14/15/16/17 Regression] de-optimized synthesis of long long shift and add

2026-05-13 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122871

--- Comment #15 from GCC Commits  ---
The master branch has been updated by Roger Sayle :

https://gcc.gnu.org/g:08d8760c3d97a329f543aec19b0d465b24fd42ea

commit r17-493-g08d8760c3d97a329f543aec19b0d465b24fd42ea
Author: Roger Sayle 
Date:   Wed May 13 12:23:41 2026 +0100

testsuite: Skip new test case gcc.target/arm/muldi-1.c with -mthumb

The recent test to confirm PR middle-end/122871 is resolved on ARM,
wasn't expecting -mthumb.  This adds a requires-effective-target.
Committed as obvious.

2026-05-13  Roger Sayle  
Richard Earnshaw  

gcc/testsuite/ChangeLog
PR middle-end/122871
* gcc.target/arm/muldi-1.c: Skip test if compiled with -mthumb.

[Bug middle-end/122871] [13/14/15/16/17 Regression] de-optimized synthesis of long long shift and add

2026-05-12 Thread rearnsha at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122871

--- Comment #14 from Richard Earnshaw  ---
We don't normally split double-word operations because the thumb1 port cannot
expose the Carry flag (most operations clobber the PSR, so it unsafe to do so
until after register allocation; we have very limited support for post-regalloc
as well).

I think this confirms that we will need a separate test for thumb1 and a
separate ticket to see if code can be further improved there.

[Bug middle-end/122871] [13/14/15/16/17 Regression] de-optimized synthesis of long long shift and add

2026-05-11 Thread roger at nextmovesoftware dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122871

--- Comment #13 from Roger Sayle  ---
This patch does indeed help thumb1, reducing the number of -mthumb instructions
for muldi-1.c from 23 before the patch, to only 10 after.  As Richard Earnshaw
points out this should ideally be around 3, if suitably optimized by the
backend.
As shown in Torbjorn's comment (#11) the current thumb code loads zero into a
register r2, and then uses it in an addition!?  I suspect the thumb backend
isn't using splitters to decompose double word operations before or after
reload.

[Bug middle-end/122871] [13/14/15/16/17 Regression] de-optimized synthesis of long long shift and add

2026-05-11 Thread rearnsha at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122871

--- Comment #12 from Richard Earnshaw  ---
(In reply to Torbjorn SVENSSON from comment #11)

> The new test case fail for Cortex-M0 and Cortex-M23. Is this a thumb2-only
> improvement?

In principle the optimization is valid for thumb1 cores, but since we lack
shift+add patterns there, we should end up with something like

lsls r2, r0, #1
adds r1, r1, r2
bx   lr

That's still much better than the sequence using adc(s), but obviously not
quite as simple as a single shift+add pattern.

And obviously this won't match the expected output in the current testcase.

The current test should probably add
/* { dg-require-effective-target arm32 } */

And then create a separate test for thumb1 targets.

If the thumb1 code generator isn't generating something like the above sequence
we should create a new PR for that as it's likely a costing issue in the
backend.

[Bug middle-end/122871] [13/14/15/16/17 Regression] de-optimized synthesis of long long shift and add

2026-05-10 Thread azoff at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122871

Torbjorn SVENSSON  changed:

   What|Removed |Added

 CC||azoff at gcc dot gnu.org

--- Comment #11 from Torbjorn SVENSSON  ---
(In reply to GCC Commits from comment #10)
> The master branch has been updated by Roger Sayle :
> 
> https://gcc.gnu.org/g:1a06a37611e3b27889c595a17df13f6d27202a95
> 
> commit r17-383-g1a06a37611e3b27889c595a17df13f6d27202a95
> Author: Roger Sayle 
> Date:   Thu May 7 18:46:37 2026 +0100
> 
> PR middle-end/122871: Doubleword multiplication improvements
> 
> This patch resolves PR middle-end/122871 by improving RTL expansion of
> doubleword multiplications.  The main change is to synth_mult adding
> support for the case where the constant being multiplied has
> BITS_PER_WORD
> or more trailing zeros.  The shift_cost tables in expmed are only
> parameterized for shifts less than BITS_PER_WORD, so doubleword shifts
> by more than this can't use the usual code path. This patch teaches
> synth_mult that for scalar doubleword multiplications, a doubleword shift
> by more than BITS_PER_WORD typically requires two instructions; one to
> set the result lowpart to zero, and the other a wordmode shift to
> calculate the result highpart.
> 
> For the testcase given in the PR:
> 
> long long ashll_fn (long long a)
> {
>   long long c;
> 
>   c = a << 33;
>   c += a;
>   return c;
> }
> 
> GCC for arm-linux-gnueabihf currently generates with -O2:
> 
> ashll_fn:
> lsl r2, r1, #11
> lsl ip, r0, #11
> subsip, ip, r0
> orr r2, r2, r0, lsr #21
> sbc r2, r2, r1
> lsl r3, ip, #11
> lsl r2, r2, #11
> addsr3, r3, r0
> orr r2, r2, ip, lsr #21
> adc r1, r1, r2
> lsl r2, r1, #11
> lsl r0, r3, #11
> addsr0, r3, r0
> orr r2, r2, r3, lsr #21
> adc r1, r1, r2
> bx  lr
> 
> with this patch, we instead generate:
> 
> ashll_fn:
> add r1, r1, r0, lsl #1
> bx  lr
> 
> Additionally, this patch includes a clean-up (identified by A. Pinski)
> to prevent RTL expansion of doubleword multiplications from
> initially emitting multiply instructions by immediate constants 0, 1
> or 2.  These dubious multiplications eventually get tidied up by later
> RTL optimization passes, but being sensible during RTL expansion
> both speeds up the compiler and reduces unnecessary memory usage.
> 
> 2026-05-07  Roger Sayle  
> 
> gcc/ChangeLog
> PR middle-end/122871
> * expmed.cc (synth_mult): Handle doubleword left shifts by
> BITS_PER_WORD bits or more, for scalar modes.
> * optabs.cc (expand_doubleword_mult): Avoid generating multiply
> instructions by immediate constants 0, 1 or 2.
> 
> gcc/testsuite/ChangeLog
> PR middle-end/122871
> * gcc.target/arm/muldi-1.c: New test case.

The new test case fail for Cortex-M0 and Cortex-M23. Is this a thumb2-only
improvement?

For Cortex-M0, I get:

$ /build/r17-409-g8376a674e3564f/bin/arm-none-eabi-gcc
/build/gcc_src/gcc/testsuite/gcc.target/arm/muldi-1.c -mthumb -march=armv6s-m
-mtune=cortex-m0 -mfloat-abi=soft -mfpu=auto -fdiagnostics-plain-output -O2
-ffat-lto-objects -fno-ident -S -o - -dP
.arch armv6s-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, 2
.eabi_attribute 34, 0
.eabi_attribute 18, 4
.file   "muldi-1.c"
.text
.align  1
.p2align 2,,3
.global ashll_fn
.syntax unified
.code   16
.thumb_func
.type   ashll_fn, %function
ashll_fn:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
@(insn 23 3 38 (set (reg:SI 3 r3 [ a+4 ])
@(reg:SI 0 r0 [orig:107 a ] [107]))
"/build/gcc_src/gcc/testsuite/gcc.target/arm/muldi-1.c":9:5 743
{*thumb1_movsi_insn}
@ (nil))
@ 0x
movsr3, r0  @ 23[c=4 l=2]  *thumb1_movsi_insn/0
@(insn 32 38 22 (unspec:SI [
@(reg/f:SI 13 sp)
@] UNSPEC_REGISTER_USE)
"/build/gcc_src/gcc/testsuite/gcc.target/arm/muldi-1.c":11:1 403
{force_register_use}
@ (nil))
@ 0x0002
@ sp needed @ 32[c=8 l=0]  force_register_use
@(insn 22 32 11 (set (reg:SI 2 r2 [orig:99 a ] [99])
@(const_int 0 [0]))

[Bug middle-end/122871] [13/14/15/16/17 Regression] de-optimized synthesis of long long shift and add

2026-05-07 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122871

--- Comment #10 from GCC Commits  ---
The master branch has been updated by Roger Sayle :

https://gcc.gnu.org/g:1a06a37611e3b27889c595a17df13f6d27202a95

commit r17-383-g1a06a37611e3b27889c595a17df13f6d27202a95
Author: Roger Sayle 
Date:   Thu May 7 18:46:37 2026 +0100

PR middle-end/122871: Doubleword multiplication improvements

This patch resolves PR middle-end/122871 by improving RTL expansion of
doubleword multiplications.  The main change is to synth_mult adding
support for the case where the constant being multiplied has BITS_PER_WORD
or more trailing zeros.  The shift_cost tables in expmed are only
parameterized for shifts less than BITS_PER_WORD, so doubleword shifts
by more than this can't use the usual code path. This patch teaches
synth_mult that for scalar doubleword multiplications, a doubleword shift
by more than BITS_PER_WORD typically requires two instructions; one to
set the result lowpart to zero, and the other a wordmode shift to
calculate the result highpart.

For the testcase given in the PR:

long long ashll_fn (long long a)
{
  long long c;

  c = a << 33;
  c += a;
  return c;
}

GCC for arm-linux-gnueabihf currently generates with -O2:

ashll_fn:
lsl r2, r1, #11
lsl ip, r0, #11
subsip, ip, r0
orr r2, r2, r0, lsr #21
sbc r2, r2, r1
lsl r3, ip, #11
lsl r2, r2, #11
addsr3, r3, r0
orr r2, r2, ip, lsr #21
adc r1, r1, r2
lsl r2, r1, #11
lsl r0, r3, #11
addsr0, r3, r0
orr r2, r2, r3, lsr #21
adc r1, r1, r2
bx  lr

with this patch, we instead generate:

ashll_fn:
add r1, r1, r0, lsl #1
bx  lr

Additionally, this patch includes a clean-up (identified by A. Pinski)
to prevent RTL expansion of doubleword multiplications from
initially emitting multiply instructions by immediate constants 0, 1
or 2.  These dubious multiplications eventually get tidied up by later
RTL optimization passes, but being sensible during RTL expansion
both speeds up the compiler and reduces unnecessary memory usage.

2026-05-07  Roger Sayle  

gcc/ChangeLog
PR middle-end/122871
* expmed.cc (synth_mult): Handle doubleword left shifts by
BITS_PER_WORD bits or more, for scalar modes.
* optabs.cc (expand_doubleword_mult): Avoid generating multiply
instructions by immediate constants 0, 1 or 2.

gcc/testsuite/ChangeLog
PR middle-end/122871
* gcc.target/arm/muldi-1.c: New test case.