This is a trivial oversight in the recently added improvement to conditional
move generation on the RISC-V port.
We have a step which canonicalizes the comparison operands. The process of
canonicalizing may change one or both operands, including giving a new pseudo
with a different mode.
The new code failed to account for that and as a result it was using a stale
mode (QI) which caused all kinds of problems later. Just swapping the code
which canonicalizes the operand with the code that extracts the mode and
everything is happy again. Fixed a formatting nit while I was in there.
Tested on riscv32-elf and riscv64-elf. But waiting for pre-commit CI to do its
thing.
PR target/125152
gcc/
* config/riscv/riscv.cc (riscv_expand_conditional_move): Extract the
mode after operand canonicalization.
gcc/testsuite/
* gcc.target/riscv/pr125152.c: New test.
&& GET_MODE_CLASS (cond_mode) == MODE_INT)
|| TARGET_COND_MOV)
{
+ canonicalize_comparands (code, &op0, &op1);
machine_mode mode0 = GET_MODE (op0);
- canonicalize_comparands (code,&op0,&op1);
-
/* In the fallback generic case use DST_MODE rather than WORD_MODE
for the output of the SCC instruction, to match the mode of the NEG
operation below. The output of SCC is 0 or 1 boolean, so it is
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-mmovcc -std=gnu99" } */
+
+typedef __attribute__((__vector_size__(16))) char V;
+V v;
+char c;
+
+void
+foo()
+{
+ v |= (V){4} > c;
+}