SIGN_EXTEND, ZERO_EXTEND and SUBREG has been considered
to support SImode in 64-bit machine.

Co-authored-by: Xiao Zeng<zengx...@eswincomputing.com>

gcc/ChangeLog:

        * ifcvt.cc (noce_cond_zero_binary_op_supported): add support for 
extension
        (noce_bbs_ok_for_cond_zero_arith): likewise
        (noce_try_cond_zero_arith): support extension of LSHIFTRT case

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/zicond_ifcvt_opt.c: add TCs for extension
---
 gcc/ifcvt.cc                                  |  16 ++-
 .../gcc.target/riscv/zicond_ifcvt_opt.c       | 126 +++++++++++++++++-
 2 files changed, 139 insertions(+), 3 deletions(-)

diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc
index b84be53ec5c..306497a8e37 100644
--- a/gcc/ifcvt.cc
+++ b/gcc/ifcvt.cc
@@ -2934,6 +2934,10 @@ noce_cond_zero_binary_op_supported (rtx op)
 {
   enum rtx_code opcode = GET_CODE (op);
 
+  /* Strip SIGN_EXTEND or ZERO_EXTEND if any.  */
+  if (opcode == SIGN_EXTEND || opcode == ZERO_EXTEND)
+    opcode = GET_CODE (XEXP (op, 0));
+
   if (opcode == PLUS || opcode == MINUS || opcode == IOR || opcode == XOR
       || opcode == AND || noce_cond_zero_shift_op_supported (opcode))
     return true;
@@ -3000,7 +3004,11 @@ noce_bbs_ok_for_cond_zero_arith (struct noce_if_info 
*if_info, rtx *common_ptr,
   if (!(noce_cond_zero_binary_op_supported (a) && REG_P (b)))
     return false;
 
-  bin_exp = a;
+  /* Strip sign_extend if any.  */
+  if (GET_CODE (a) == SIGN_EXTEND || GET_CODE (a) == ZERO_EXTEND)
+    bin_exp = XEXP (a, 0);
+  else
+    bin_exp = a;
 
   /* Canonicalize x = (z op y) : y to x = (y op z) : y */
   op1 = get_base_reg (XEXP (bin_exp, 1));
@@ -3114,7 +3122,11 @@ noce_try_cond_zero_arith (struct noce_if_info *if_info)
       if (CONST_INT_P (*to_replace))
        {
          if (noce_cond_zero_shift_op_supported (bin_code))
-           *to_replace = gen_rtx_SUBREG (E_QImode, target, 0);
+           {
+             *to_replace = gen_rtx_SUBREG (E_QImode, target, 0);
+             if (GET_CODE (a) == ZERO_EXTEND && bin_code == LSHIFTRT)
+               PUT_CODE (a, SIGN_EXTEND);
+           }
          else if (SUBREG_P (bin_op0))
            *to_replace = gen_rtx_SUBREG (GET_MODE (bin_op0), target, 0);
          else
diff --git a/gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c 
b/gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c
index 85743e1734c..53206d76e9f 100644
--- a/gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c
+++ b/gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c
@@ -615,6 +615,69 @@ test_RotateR_eqz (unsigned long x, unsigned long y, 
unsigned long z,
   return x;
 }
 
+int
+test_ADD_ceqz_int (int x, int y, int z, int c)
+{
+  if (c)
+    x = y + z;
+  else
+    x = y;
+  return x;
+}
+
+int
+test_ShiftLeft_eqz_int (int x, int y, int z, int c)
+{
+  if (c)
+    x = y << z;
+  else
+    x = y;
+  return x;
+}
+
+int
+test_ShiftR_eqz_int (int x, int y, int z, int c)
+{
+  if (c)
+    x = y >> z;
+  else
+    x = y;
+  return x;
+}
+
+unsigned int
+test_ShiftR_logical_eqz_int (unsigned int x, unsigned int y, unsigned int z,
+                            unsigned int c)
+{
+  if (c)
+    x = y >> z;
+  else
+    x = y;
+  return x;
+}
+
+unsigned int
+test_RotateL_eqz_int (unsigned int x, unsigned int y, unsigned int z,
+                     unsigned int c)
+{
+  if (c)
+    x = (y << z) | (y >> (32 - z));
+  else
+    x = y;
+  return x;
+}
+
+unsigned int
+test_RotateR_eqz_int (unsigned int x, unsigned int y, unsigned int z,
+                     unsigned int c)
+{
+  if (c)
+    x = (y >> z) | (y << (32 - z));
+  else
+    x = y;
+  return x;
+}
+
 long
 test_ADD_ceqz_imm (long x, long y, long c)
 {
@@ -1225,6 +1288,67 @@ test_RotateR_eqz_imm (unsigned long x, unsigned long y, 
unsigned long c)
     x = y;
   return x;
 }
+
+int
+test_ADD_ceqz_imm_int (int x, int y, int c)
+{
+  if (c)
+    x = y + 11;
+  else
+    x = y;
+  return x;
+}
+
+int
+test_ShiftLeft_eqz_imm_int (int x, int y, int c)
+{
+  if (c)
+    x = y << 11;
+  else
+    x = y;
+  return x;
+}
+
+int
+test_ShiftR_eqz_imm_int (int x, int y, int c)
+{
+  if (c)
+    x = y >> 11;
+  else
+    x = y;
+  return x;
+}
+
+unsigned int
+test_ShiftR_logical_eqz_imm_int (unsigned int x, unsigned int y, unsigned int 
c)
+{
+  if (c)
+    x = y >> 11;
+  else
+    x = y;
+  return x;
+}
+
+unsigned int
+test_RotateL_eqz_imm_int (unsigned int x, unsigned int y, unsigned int c)
+{
+  if (c)
+    x = (y << 11) | (y >> (32 - 11));
+  else
+    x = y;
+  return x;
+}
+
+unsigned int
+test_RotateR_eqz_imm_int (unsigned int x, unsigned int y, unsigned int c)
+{
+  if (c)
+    x = (y >> 11) | (y << (32 - 11));
+  else
+    x = y;
+  return x;
+}
+
 long
 test_AND_ceqz (long x, long y, long z, long c)
 {
@@ -1544,5 +1668,5 @@ test_AND_eqz_x_2_imm_reverse_bin_oprands (long x, long c)
     x = 11 & x;
   return x;
 }
-/* { dg-final { scan-assembler-times {czero\.eqz} 82 } } */
+/* { dg-final { scan-assembler-times {czero\.eqz} 94 } } */
 /* { dg-final { scan-assembler-times {czero\.nez} 72 } } */
-- 
2.17.1

Reply via email to