]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PATCH 2/5] [ifcvt] optimize x=c ? (y shift_op z):y by RISC-V Zicond like insns
authorFei Gao <gaofei@eswincomputing.com>
Sun, 10 Dec 2023 20:39:30 +0000 (13:39 -0700)
committerJeff Law <jlaw@ventanamicro.com>
Sun, 10 Dec 2023 20:41:01 +0000 (13:41 -0700)
op=[ASHIFT, ASHIFTRT, LSHIFTRT, ROTATE, ROTATERT]

Conditional op, if zero
rd = (rc == 0) ? (rs1 op rs2) : rs1
-->
czero.nez rd, rs2, rc
op rd, rs1, rd

Conditional op, if non-zero
rd = (rc != 0) ? (rs1 op rs2) : rs1
-->
czero.eqz rd, rs2, rc
op rd, rs1, rd

gcc/ChangeLog:

* ifcvt.cc (noce_cond_zero_binary_op_supported): Add support for shift
like op.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/zicond_ifcvt_opt.c: Add tests for shift like op.

Co-authored-by: Xiao Zeng<zengxiao@eswincomputing.com>
gcc/ifcvt.cc
gcc/testsuite/gcc.target/riscv/zicond_ifcvt_opt.c

index e4eda1a68375957908b72035e7c6976c69fa9e9a..6ac91b8cbb3355add4f0e716488448188ad926b7 100644 (file)
@@ -2920,7 +2920,9 @@ noce_cond_zero_binary_op_supported (rtx op)
 {
   enum rtx_code opcode = GET_CODE (op);
 
-  if (opcode == PLUS || opcode == MINUS || opcode == IOR || opcode == XOR)
+  if (opcode == PLUS || opcode == MINUS || opcode == IOR || opcode == XOR
+      || opcode == ASHIFT || opcode == ASHIFTRT || opcode == LSHIFTRT
+      || opcode == ROTATE || opcode == ROTATERT)
     return true;
 
   return false;
index dcb21c15d1a7905ae0568da5d534a1aaf50bafea..efed199627e5482b1368f42bf807ac8cf403cd83 100644 (file)
@@ -562,5 +562,58 @@ test_XOR_eqz_x_2_reverse_bin_oprands (long x, long z, long c)
   return x;
 }
 
+long
+test_ShiftLeft_eqz (long x, long y, long z, long c)
+{
+  if (c)
+    x = y << z;
+  else
+    x = y;
+  return x;
+}
+
+long
+test_ShiftR_eqz (long x, long y, long z, long c)
+{
+  if (c)
+    x = y >> z;
+  else
+    x = y;
+  return x;
+}
+
+unsigned long
+test_ShiftR_logical_eqz (unsigned long x, unsigned long y, unsigned long z,
+                        unsigned long c)
+{
+  if (c)
+    x = y >> z;
+  else
+    x = y;
+  return x;
+}
+
+unsigned long
+test_RotateL_eqz (unsigned long x, unsigned long y, unsigned long z,
+                 unsigned long c)
+{
+  if (c)
+    x = (y << z) | (y >> (64 - z));
+  else
+    x = y;
+  return x;
+}
+
+unsigned long
+test_RotateR_eqz (unsigned long x, unsigned long y, unsigned long z,
+                 unsigned long c)
+{
+  if (c)
+    x = (y >> z) | (y << (64 - z));
+  else
+    x = y;
+  return x;
+}
+
 /* { dg-final { scan-assembler-times {czero\.eqz} 28 } } */
 /* { dg-final { scan-assembler-times {czero\.nez} 28 } } */