This was tripping up gcc.c-torture/execute/pr60003.c at -O1 since the pattern semantics can't be expressed by zicond instructions.
This involves test code snippet: if (a == 0) return 0; else return x; } which is equivalent to: "x = (a != 0) ? x : a" and matches define_insn "*czero.nez.<GPR:mode><X:mode>.opt2" | (insn 41 20 38 3 (set (reg/v:DI 136 [ x ]) | (if_then_else:DI (ne (reg/v:DI 134 [ a ]) | (const_int 0 [0])) | (reg/v:DI 136 [ x ]) | (reg/v:DI 134 [ a ]))) {*czero.nez.didi.opt2} The corresponding asm pattern generates czero.nez x, x, a ; %0, %2, %1 implying "x = (a != 0) ? 0 : a" which is not what the pattern semantics are. Essentially "(a != 0) ? x : a" cannot be expressed with CZERO.nez As a side note, while correctness prevails, this test still gets a czero in the end, albeit a different one. if-convert generates two if_then_else | (insn 43 20 44 3 (set (reg:DI 143) | (reg/v:DI 136 [ x ])) "pr60003.c":36:9 179 {*movdi_64bit} | (insn 44 43 46 3 (set (reg:DI 142) | (reg/v:DI 134 [ a ])) "pr60003.c":36:9 179 {*movdi_64bit} | | (insn 46 44 47 3 (set (reg:DI 145) | (if_then_else:DI (ne:DI (reg/v:DI 134 [ a ]) | (const_int 0 [0])) | (const_int 0 [0]) | (reg:DI 142))) "pr60003.c":36:9 14532 {*czero.nez.didi} | | (insn 47 46 48 3 (set (reg:DI 144) | (if_then_else:DI (eq:DI (reg/v:DI 134 [ a ]) | (const_int 0 [0])) | (const_int 0 [0]) | (reg:DI 143))) "pr60003.c":36:9 14531 {*czero.eqz.didi} and combine is able to fuse them together | (insn 38 48 39 3 (set (reg/i:DI 10 a0) | (if_then_else:DI (eq:DI (reg/v:DI 134 [ a ]) | (const_int 0 [0])) | (const_int 0 [0]) | (reg:DI 143))) "pr60003.c":40:1 14531 {*czero.eqz.didi} before fix after fix ----------------- ----------------- li a5,1 li a0,1 ld a4,8(sp) ld a5,8(sp) czero.nez a0,a4,a5 czero.eqz a0,a5,a0 The issue only happens at -O1 as at higher optimization levels, the whole conditional move gets optimized away. gcc/ChangeLog: * config/riscv/zicond.md: Remove incorrect op2 pattern. Fixes: 1d5bc3285e8a ("[committed][RISC-V] Fix 20010221-1.c with zicond") Signed-off-by: Vineet Gupta <vine...@rivosinc.com> --- gcc/config/riscv/zicond.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/gcc/config/riscv/zicond.md b/gcc/config/riscv/zicond.md index 25f21d33487e..aa5607a9efd8 100644 --- a/gcc/config/riscv/zicond.md +++ b/gcc/config/riscv/zicond.md @@ -52,13 +52,3 @@ "TARGET_ZICOND && rtx_equal_p (operands[1], operands[2])" "czero.eqz\t%0,%3,%1" ) - -(define_insn "*czero.nez.<GPR:mode><X:mode>.opt2" - [(set (match_operand:GPR 0 "register_operand" "=r") - (if_then_else:GPR (ne (match_operand:X 1 "register_operand" "r") - (const_int 0)) - (match_operand:GPR 2 "register_operand" "r") - (match_operand:GPR 3 "register_operand" "1")))] - "TARGET_ZICOND && rtx_equal_p (operands[1], operands[3])" - "czero.nez\t%0,%2,%1" -) -- 2.34.1