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. Fix this to
use the first operand.

Additionally, the operand constraint is loosened from "0" to "r" for better
performance. The split condition is set to only perform the split after reload.


gcc/ChangeLog:

        * config/arc/arc.md: Modify define_insn_and_split "*extvsi_n_0"

gcc/testsuite/ChangeLog:

        * gcc.target/arc/extvsi-3.c: New test.

Signed-off-by: Michiel Derhaeg <[email protected]>

---
 gcc/config/arc/arc.md                   |  6 +++---
 gcc/testsuite/gcc.target/arc/extvsi-3.c | 14 ++++++++++++++
 2 files changed, 17 insertions(+), 3 deletions(-)
 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 8f7e5373fdf..195821139e0 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -6286,15 +6286,15 @@ archs4x, archs4xd"
 
 (define_insn_and_split "*extvsi_n_0"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (sign_extract:SI (match_operand:SI 1 "register_operand" "0")
+       (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
                         (match_operand:QI 2 "const_int_operand")
                         (const_int 0)))]
   "!TARGET_BARREL_SHIFTER
    && IN_RANGE (INTVAL (operands[2]), 2,
                (optimize_insn_for_size_p () ? 28 : 30))"
   "#"
-  "&& 1"
-[(set (match_dup 0) (and:SI (match_dup 0) (match_dup 3)))
+  "&& ! arc_pre_reload_split ()"
+[(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" } } */
-- 
v2: apply Claudiu's notes, loosening the constraint and add split condition
perform split after reload.

Reply via email to