The splitter matching (x >= 1 ? 2^n : 0) lowered it to
tmp = (x > 1); result = tmp << n, emitting any_gt instead of any_ge.
At x == 1 the original yields 2^n but the split yields 0, a
miscompile.  Emit any_ge to reproduce the matched comparison, as the
sibling GE/GEU splitters already do.

gcc/ChangeLog:

        * config/riscv/zicond.md: Emit any_ge instead of any_gt in the
        GE/GEU if-then-else splitter.

Signed-off-by: Jim Lin <[email protected]>
---
 gcc/config/riscv/zicond.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/riscv/zicond.md b/gcc/config/riscv/zicond.md
index a890322a518..b0152cb773f 100644
--- a/gcc/config/riscv/zicond.md
+++ b/gcc/config/riscv/zicond.md
@@ -458,7 +458,7 @@
         (const_int 0)))
    (clobber (match_operand:X 3 "register_operand"))]
   "exact_log2 (INTVAL (operands[2])) >= 0"
-  [(set (match_dup 3) (any_gt:X (match_dup 1) (const_int 1)))
+  [(set (match_dup 3) (any_ge:X (match_dup 1) (const_int 1)))
    (set (match_dup 0) (ashift:X (match_dup 3) (match_dup 4)))]
   { operands[4] = GEN_INT (exact_log2 (INTVAL (operands[2]))); })
 
-- 
2.52.0

Reply via email to