https://gcc.gnu.org/g:f3fecf54f0a91e8a9b65e1ce6b984324654b2e2d

commit f3fecf54f0a91e8a9b65e1ce6b984324654b2e2d
Author: Artemiy Volkov <artemiy.vol...@synopsys.com>
Date:   Sun Jun 23 14:54:00 2024 -0600

    [PATCH] RISC-V: Fix unrecognizable pattern in 
riscv_expand_conditional_move()
    
    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-5.c: New test.
    
    (cherry picked from commit eb647daa87b466d0a71246fad302cd81bfce9be5)

Diff:
---
 gcc/config/riscv/riscv.cc                     |  3 ++-
 gcc/testsuite/gcc.target/riscv/zicond-ice-5.c | 11 +++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 5c758b95327..cca7ffde33a 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -5111,8 +5111,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);
              alt = force_reg (mode, alt);
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-ice-5.c 
b/gcc/testsuite/gcc.target/riscv/zicond-ice-5.c
new file mode 100644
index 00000000000..ac6049c9ae5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zicond-ice-5.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;
+}

Reply via email to