Vineet's glibc build triggered an ICE building glibc with the latest zicond
bits. It's a minor issue in the canonicalization of the condition.
When we need to canonicalize the condition we use an SCC insn to handle the
primary comparison with the output going into a temporary with the final value
of 0/1 which we can then use in a zicond instruction.
The mode of the newly generated temporary was taken from mode of the final
destination. That's simply wrong. The mode of the condition needs to be
word_mode.
This patch fixes that minor problem and adds a suitable testcase.
gcc/
* config/riscv/riscv.cc (riscv_expand_conditional_move): Use word_mode
for the temporary when canonicalizing the condition.
gcc/testsuite
* gcc.target/riscv/zicond-ice-1.c: New test.
/* Emit an scc like instruction into a temporary
so that we can use an EQ/NE comparison. */
- rtx tmp = gen_reg_rtx (mode);
+ rtx tmp = gen_reg_rtx (word_mode);
/* We can support both FP and integer conditional moves. */
if (INTEGRAL_MODE_P (GET_MODE (XEXP (op, 0))))
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc_zicond -mabi=ilp32f" { target { rv32 } } } */
+
+int a, c;
+long b;
+
+void
+d() {
+ for (;;)
+ if (a & (b < 8 ?: 1 << b))
+ c = 1;
+}