On Mon, Jun 22, 2026 at 8:33 AM H.J. Lu <[email protected]> wrote:
>
> On Mon, Jun 22, 2026 at 1:59 PM Uros Bizjak <[email protected]> wrote:
> >
> > -ENOPATCH
>
> Oops.  Here it is.
>
> > On Sun, Jun 21, 2026 at 11:44 PM H.J. Lu <[email protected]> wrote:
> > >
> > > Since LCP stall peepholes are added after register allocation, each
> > > peephole may use a different scratch register.  For input:
> > >
> > > extern void bar (void);
> > >
> > > void
> > > foo (short *dst)
> > > {
> > >   dst[0] = 3;
> > >   asm volatile ("" : : : "memory");
> > >   dst[2] = 3;
> > >   bar ();
> > >   dst[1] = 3;
> > >   asm volatile ("" : : : "memory");
> > >   dst[4] = 3;
> > > }
> > >
> > > with LCP stall peepholes, GCC generates:
> > >
> > > movl $3, %eax
> > > pushq %rbx
> > > movq %rdi, %rbx
> > > movw %ax, (%rdi)
> > > movl $3, %edx
> > > movw %dx, 4(%rdi)
> > > call bar
> > > movl $3, %ecx
> > > movw %cx, 2(%rbx)
> > > movl $3, %esi
> > > movw %si, 8(%rbx)
> > > popq %rbx
> > >
> > > using 4 different scratch registers vs without LCP stall peepholes:
> > >
> > > pushq %rbx
> > > movq %rdi, %rbx
> > > movw $3, (%rdi)
> > > movw $3, 4(%rdi)
> > > call bar
> > > movw $3, 2(%rbx)
> > > movw $3, 8(%rbx)
> > > popq %rbx
> > >
> > > Add ix86_output_lcp_stall_peephole to generate LCP stall peepholes with
> > > the previous scratch register:
> > >
> > > 1. Scan backward for the previous scratch register definition with
> > > the same immediate operand in the same basic block.
> > > 2. The previous scratch register is unusable if it is set between the
> > > previous scratch register definition and the current instruction.
> > > 3. If a usable previous scratch register is found, ignore the allocated
> > > scratch register and use the previous scratch register.  Otherwise, use
> > > the allocated scratch register.
> > >
> > > so that the same scratch register can be reused if possible:
> > >
> > > movl $3, %eax
> > > pushq %rbx
> > > movq %rdi, %rbx
> > > movw %ax, (%rdi)
> > > movw %ax, 4(%rdi)
> > > call bar
> > > movl $3, %ecx
> > > movw %cx, 2(%rbx)
> > > movw %cx, 8(%rbx)
> > > popq %rbx
> > >
> > > I backported this patch to GCC 16:
> > >
> > > 1. When bootstrapping GCC 16 with only C and C++ enabled, this 
> > > optimization
> > > triggers 54 times.  No regressions.
> > > 2. When building glibc 2.44, this optimization triggers 33 times.  No
> > > regressions.
> > > 3. When building Linux kernel 7.1.1, this optimization triggers 2099 
> > > times.
> > > Kernel boots correctly.
> > >
> > > gcc/
> > >
> > > PR target/125893
> > > * config/i386/i386-protos.h (ix86_output_lcp_stall_peephole):
> > > New.
> > > * config/i386/i386.cc (ix86_output_lcp_stall_peephole): Likewise.
> > > * config/i386/i386.md (TARGET_LCP_STALL peepholes): Call
> > > ix86_output_lcp_stall_peephole.
> > >
> > > gcc/testsuite/
> > >
> > > PR target/125893
> > > * gcc.target/i386/pr125893-1.c: New test.
> > > * gcc.target/i386/pr125893-2.c: Likewise.
> > > * gcc.target/i386/pr125893-3.c: Likewise.
> > > * gcc.target/i386/pr125893-4.c: Likewise.
> > > * gcc.target/i386/pr125893-5.c: Likewise.
> > > * gcc.target/i386/pr125893-6.c: Likewise.
> > > * gcc.target/i386/pr125893-7.c: Likewise.
> > > * gcc.target/i386/pr125893-8.c: Likewise.
> > > * gcc.target/i386/pr125893-9.c: Likewise.
> > > * gcc.target/i386/pr125893-10.c: Likewise.


+/* Output LCP stall or long immediate peephole for INSN.  Use the
+   previous scratch register if possible.  */
+
+void
+ix86_output_lcp_stall_peephole (rtx_insn *insn, rtx *operands)
+{

Please name this function ix86_expand_lcp_stall_peephole. We are
expanding RTXes here, not outputting ASM.

-  [(parallel [(set (match_dup 2) (const_int 0))
-          (clobber (reg:CC FLAGS_REG))])
-   (set (match_dup 0) (match_dup 1))]
-  "operands[2] = gen_lowpart (SImode, operands[1]);")
+  [(const_int 0)]
+{
+  operands[2] = const0_rtx;
+  ix86_output_lcp_stall_peephole (curr_insn, operands);
+})

Missing DONE;

-  [(set (match_dup 2) (match_dup 1))
-   (set (match_dup 0) (match_dup 2))])
+  [(const_int 0)]
+  "ix86_output_lcp_stall_peephole (curr_insn, operands);")

Also here.

On a related note, the second peephole also allows const0_rtx, which
results in XOR form, which clobbers flags. Please better use some
boolean argument (e.g. use_xor) to the ix86_output_lcp_stall_peephole
and handle it accordingly in both peephole2 patterns.

Uros.

Reply via email to