I think Roger designed this pattern to happen after reload. Your patch is a good starting point, but you need to perform the split after reload. Also you can relax the constraint letter of operand 1 for better performance.
//Claudiu On Thu, Nov 13, 2025 at 11:38 AM Luis Silva <[email protected]> wrote: > > From: Michiel Derhaeg <[email protected]> > > Trivial fix, looks like a typo. The first instruction erroneously used > the output register as operand instead of the first operand. > > gcc/ChangeLog: > > * config/arc/arc.md: Use correct input operand for *extvsi_n_0 > define_insn_and_split > > gcc/testsuite/ChangeLog: > > * gcc.target/arc/extvsi-3.c: New test. > > Signed-off-by: Michiel Derhaeg <[email protected]> > > --- > gcc/config/arc/arc.md | 2 +- > gcc/testsuite/gcc.target/arc/extvsi-3.c | 14 ++++++++++++++ > 2 files changed, 15 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/gcc.target/arc/extvsi-3.c > > diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md > index 6b3dca27b99..dd3d47e2e84 100644 > --- a/gcc/config/arc/arc.md > +++ b/gcc/config/arc/arc.md > @@ -6293,7 +6293,7 @@ archs4x, archs4xd" > (optimize_insn_for_size_p () ? 28 : 30))" > "#" > "&& 1" > -[(set (match_dup 0) (and:SI (match_dup 0) (match_dup 3))) > +[(set (match_dup 0) (and:SI (match_dup 1) (match_dup 3))) > (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 4))) > (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 4)))] > { > diff --git a/gcc/testsuite/gcc.target/arc/extvsi-3.c > b/gcc/testsuite/gcc.target/arc/extvsi-3.c > new file mode 100644 > index 00000000000..2a466f90ed0 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arc/extvsi-3.c > @@ -0,0 +1,14 @@ > +/* { dg-do compile } */ > +/* { dg-skip-if "avoid conflicts with -mcpu options" { *-*-* } { "-mcpu=*" } > { "-mcpu=em" } } */ > +/* { dg-options "-O2 -mcpu=em" } */ > +struct S { int a : 5; }; > + > +/* An extra parameter is added to ensure a different register is used for > input and output. */ > +int foo (int unused, struct S p) > +{ > + return p.a; > +} > + > +/* { dg-final { scan-assembler "and\\s+r0,r1,31" } } */ > +/* { dg-final { scan-assembler "xor\\s+r0,r0,16" } } */ > +/* { dg-final { scan-assembler "sub\\s+r0,r0,16" } } */ > -- > 2.43.0 >
