diff mbox series

RISC-V: Fix unrecognizable pattern in riscv_expand_conditional_move()

Message ID 20240621144612.122744-1-artemiy@synopsys.com
State New
Headers show
Series RISC-V: Fix unrecognizable pattern in riscv_expand_conditional_move() | expand

Commit Message

Artemiy Volkov June 21, 2024, 2:46 p.m. UTC
Presently, the code fragment:

int x[5];

void
d(int a, int b, int c) {
  for (int i = 0; i < 5; i++)
    x[i] = (a != b) ? c : a;
}

causes an ICE when compiled with -O2 -march=rv32i_zicond:

test.c: In function 'd':
test.c: error: unrecognizable insn:
   11 | }
      | ^
(insn 8 5 9 2 (set (reg:SI 139 [ iftmp.0_2 ])
        (if_then_else:SI (ne:SI (reg/v:SI 136 [ a ])
                (reg/v:SI 137 [ b ]))
            (reg/v:SI 136 [ a ])
            (reg/v:SI 138 [ c ]))) -1
     (nil))
during RTL pass: vregs

This happens because, as part of one of the optimizations in
riscv_expand_conditional_move(), an if_then_else is generated with both
comparands being register operands, resulting in an unmatchable insn since
Zicond patterns require constant 0 as the second comparand.  Fix this by adding
a extra check before performing this optimization.

The code snippet mentioned above is also included in this patch as a new Zicond
testcase.

gcc/ChangeLog:

        * config/riscv/riscv.cc (riscv_expand_conditional_move): Add a
        CONST0_RTX check.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/zicond-ice-3.c: New test.

Signed-off-by: Artemiy Volkov <artemiy@synopsys.com>
---
 gcc/config/riscv/riscv.cc                     |  3 ++-
 gcc/testsuite/gcc.target/riscv/zicond-ice-3.c | 11 +++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-ice-3.c

Comments

Jeff Law June 23, 2024, 8:55 p.m. UTC | #1
On 6/21/24 8:46 AM, Artemiy Volkov wrote:
> Presently, the code fragment:
> 
> int x[5];
> 
> void
> d(int a, int b, int c) {
>    for (int i = 0; i < 5; i++)
>      x[i] = (a != b) ? c : a;
> }
> 
> causes an ICE when compiled with -O2 -march=rv32i_zicond:
> 
> test.c: In function 'd':
> test.c: error: unrecognizable insn:
>     11 | }
>        | ^
> (insn 8 5 9 2 (set (reg:SI 139 [ iftmp.0_2 ])
>          (if_then_else:SI (ne:SI (reg/v:SI 136 [ a ])
>                  (reg/v:SI 137 [ b ]))
>              (reg/v:SI 136 [ a ])
>              (reg/v:SI 138 [ c ]))) -1
>       (nil))
> during RTL pass: vregs
> 
> This happens because, as part of one of the optimizations in
> riscv_expand_conditional_move(), an if_then_else is generated with both
> comparands being register operands, resulting in an unmatchable insn since
> Zicond patterns require constant 0 as the second comparand.  Fix this by adding
> a extra check before performing this optimization.
> 
> The code snippet mentioned above is also included in this patch as a new Zicond
> testcase.
> 
> gcc/ChangeLog:
> 
>          * config/riscv/riscv.cc (riscv_expand_conditional_move): Add a
>          CONST0_RTX check.
> 
> gcc/testsuite/ChangeLog:
> 
>          * gcc.target/riscv/zicond-ice-3.c: New test.
I've pushed this to the trunk.  Thanks Artemiy!

Jeff
diff mbox series

Patch

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 029c80b21cf..6c58687b5e5 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -4674,8 +4674,9 @@  riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
       /* reg, reg  */
       else if (REG_P (cons) && REG_P (alt))
 	{
-	  if ((code == EQ && rtx_equal_p (cons, op0))
+	  if (((code == EQ && rtx_equal_p (cons, op0))
 	       || (code == NE && rtx_equal_p (alt, op0)))
+	      && op1 == CONST0_RTX (mode))
 	    {
 	      rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
 	      if (!rtx_equal_p (cons, op0))
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-ice-3.c b/gcc/testsuite/gcc.target/riscv/zicond-ice-3.c
new file mode 100644
index 00000000000..ac6049c9ae5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-ice-3.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+
+int x[5];
+
+void
+d(int a, int b, int c) {
+  for (int i = 0; i < 5; i++)
+    x[i] = (a != b) ? c : a;
+}