From: Vineet Gupta <[email protected]>

movsi currently only generates DImode rN regs, despite RTL being SImode.

| (insn 14 5 11 (set (reg:SI 1 %r1 [23])
|        (reg:SI 0 %r0))  {*movsi}
|     (expr_list:REG_DEAD (reg:SI 0 %r0)
|        (nil)))

generates

|  r1 = r0

as opposed to

| w1 = w0

This is not just issue of taste or getting more wN regs. As
illustrated by test, this can be a correctness issue where mov
needs to zero out the upper bits.

Again the issue is asm teplmate of pattern missing 'w' specifier,
leading bpf_print_register() to only generate 64-bit rN regs.
Using 'w' allows either wN/rN reg depending on the mode.

        PR target/124688

gcc/ChangeLog:

        * config/bpf/bpf.md (*movsi): Add 'w' to asm template.

gcc/testsuite/ChangeLog:

        * gcc.target/bpf/ret-reuse-arg-1.c: New test.

Signed-off-by: Vineet Gupta <[email protected]>
---
 gcc/config/bpf/bpf.md                          | 10 +++++-----
 gcc/testsuite/gcc.target/bpf/ret-reuse-arg-1.c | 14 ++++++++++++++
 2 files changed, 19 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/bpf/ret-reuse-arg-1.c

diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
index a2bceb8998d7..e6776a94e7e4 100644
--- a/gcc/config/bpf/bpf.md
+++ b/gcc/config/bpf/bpf.md
@@ -383,11 +383,11 @@
         (match_operand:MM 1 "mov_src_operand"      " q,rIc,BC,r,I"))]
   ""
   "@
-   *return bpf_output_move (operands, \"{ldx<mop>\t%0,%1|%0 = *(<smop> *) 
%1}\");
-   *return bpf_output_move (operands, \"{mov\t%0,%1|%0 = %1}\");
-   *return bpf_output_move (operands, \"{lddw\t%0,%1|%0 = %1 ll}\");
-   *return bpf_output_move (operands, \"{stx<mop>\t%0,%1|*(<smop> *) %0 = 
%1}\");
-   *return bpf_output_move (operands, \"{st<mop>\t%0,%1|*(<smop> *) %0 = 
%1}\");"
+   *return bpf_output_move (operands, \"{ldx<mop>\t%0,%1|%w0 = *(<smop> *) 
%w1}\");
+   *return bpf_output_move (operands, \"{mov\t%0,%1|%w0 = %w1}\");
+   *return bpf_output_move (operands, \"{lddw\t%0,%1|%w0 = %w1 ll}\");
+   *return bpf_output_move (operands, \"{stx<mop>\t%0,%1|*(<smop> *) %w0 = 
%w1}\");
+   *return bpf_output_move (operands, \"{st<mop>\t%0,%1|*(<smop> *) %w0 = 
%w1}\");"
 [(set_attr "type" "ldx,alu,alu,stx,st")])
 
 ;;;; Shifts
diff --git a/gcc/testsuite/gcc.target/bpf/ret-reuse-arg-1.c 
b/gcc/testsuite/gcc.target/bpf/ret-reuse-arg-1.c
new file mode 100644
index 000000000000..6d0a4f280cd7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/ret-reuse-arg-1.c
@@ -0,0 +1,14 @@
+/* Return value of first call is arg to second call.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=v4" } */
+
+int ret_int ();
+void arg_int (int);
+
+void foo () {
+   arg_int(ret_int ());
+}
+
+/* { dg-final { scan-assembler-not {r1 = r0} } } */
+/* { dg-final { scan-assembler-times {w1 = w0} 1 } } */
-- 
2.53.0

Reply via email to