... by adjusting the asm template reg string to 'W', similar to commit
gbd275e81812c for zero_extendsidi2. However unike that change, this is
not a bug fix: zero_extendsidi2 relies on wN reg move to achieve the
32->64 semantics. A {8,16}->64 extension needs to be emulated anyways
by masking out extra bits so the reg used is not imp.

However wN reg based codegen is still preferable in general:
 - It is easier on verifier as it has to track fewer bits and avoids
   corner cases which could trip it up for false positives.
 - Better native codegen as upper bits are guarateed to be zero and can
   leverage target ISA mechanisms to achieve that mostly for free.
 - Better nativ codegen on 32-bit targets which need to use 2 regs for
   rN regs.

gcc/ChangeLog:

        * config/bpf/bpf.md (zero_extendhidi2): Add alternates for
        alu32 and use 'W' for reg operands.
        (zero_extendqidi2): Ditto.

gcc/testsuite/ChangeLog:

        * gcc.target/bpf/zero-ext.c: Add tests for {HI,QI}mode values.

Signed-off-by: Vineet Gupta <[email protected]>
---
 gcc/config/bpf/bpf.md                   |  8 ++++----
 gcc/testsuite/gcc.target/bpf/zero-ext.c | 16 ++++++++++++++++
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
index c2c3152b5d7c..a2bceb8998d7 100644
--- a/gcc/config/bpf/bpf.md
+++ b/gcc/config/bpf/bpf.md
@@ -279,8 +279,8 @@
        (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "0,r,q")))]
   ""
   "@
-   {and\t%0,0xffff|%0 &= 0xffff}
-   *return bpf_output_move (operands, \"{mov\t%0,%1\;and\t%0,0xffff|%0 = %1;%0 
&= 0xffff}\");
+   *return bpf_has_alu32 ? \"{and32\t%0,0xffff|%W0 &= 0xffff}\" : 
\"{and\t%0,0xffff|%0 &= 0xffff}\";
+   *return bpf_output_move (operands, bpf_has_alu32 ? 
\"{mov\t%0,%1\;and\t%0,0xffff|%W0 = %W1;%W0 &= 0xffff}\" : 
\"{mov\t%0,%1\;and\t%0,0xffff|%0 = %1;%0 &= 0xffff}\");
    *return bpf_output_move (operands, \"{ldxh\t%0,%1|%0 = *(u16 *) %1}\");"
   [(set_attr "type" "alu,alu,ldx")])
 
@@ -289,8 +289,8 @@
        (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "0,r,q")))]
   ""
   "@
-   {and\t%0,0xff|%0 &= 0xff}
-   *return bpf_output_move (operands, \"{mov\t%0,%1\;and\t%0,0xff|%0 = %1;%0 
&= 0xff}\");
+   *return bpf_has_alu32 ? \"{and32\t%0,0xff|%W0 &= 0xff}\" : 
\"{and\t%0,0xff|%0 &= 0xff}\";
+   *return bpf_output_move (operands, bpf_has_alu32 ? 
\"{mov\t%0,%1\;and\t%0,0xff|%W0 = %W1;%W0 &= 0xff}\" : 
\"{mov\t%0,%1\;and\t%0,0xff|%0 = %1;%0 &= 0xff}\");
    *return bpf_output_move (operands, \"{ldxb\t%0,%1|%0 = *(u8 *) %1}\");"
   [(set_attr "type" "alu,alu,ldx")])
 
diff --git a/gcc/testsuite/gcc.target/bpf/zero-ext.c 
b/gcc/testsuite/gcc.target/bpf/zero-ext.c
index a57c7dc521f0..b6ab7dab8bc0 100644
--- a/gcc/testsuite/gcc.target/bpf/zero-ext.c
+++ b/gcc/testsuite/gcc.target/bpf/zero-ext.c
@@ -2,6 +2,8 @@
 /* { dg-options "-O2 -mcpu=v4" } */
 
 int bar_int(void);
+short bar_short(void);
+_Bool bar_bool(void);
 
 int foo_int(void) {
       if (bar_int() != 1) return 0; else return 1;
@@ -9,3 +11,17 @@ int foo_int(void) {
 
 /* { dg-final { scan-assembler-not {r0 = r0} } } */
 /* { dg-final { scan-assembler-times {w0 = w0} 1 } } */
+
+int trigger_zext_hidi(void) {
+      if (bar_short() != 1) return 0; else return 1;
+}
+
+/* { dg-final { scan-assembler-not {r0 &= 0xffff} } } */
+/* { dg-final { scan-assembler-times {w0 &= 0xffff} 1 } } */
+
+int trigger_zext_qidi(void) {
+      if (bar_bool() != 0) return 0; else return 1;
+}
+
+/* { dg-final { scan-assembler-not {r0 &= 0xff\n} } } */
+/* { dg-final { scan-assembler-times {w0 &= 0xff\n} 1 } } */
-- 
2.53.0

Reply via email to