]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[committed] [RISC-V] Fix bug in condition canonicalization for zicond
authorJeff Law <jlaw@ventanamicro.com>
Tue, 8 Aug 2023 21:32:38 +0000 (15:32 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Tue, 8 Aug 2023 21:37:34 +0000 (15:37 -0600)
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.

gcc/config/riscv/riscv.cc
gcc/testsuite/gcc.target/riscv/zicond-ice-1.c [new file with mode: 0644]

index f9b53d21d1b218b23534bbf30f31736853f12469..e277c138636d87b210d86c228a00389ba8dd79ee 100644 (file)
@@ -3600,7 +3600,7 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
 
          /* 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))))
diff --git a/gcc/testsuite/gcc.target/riscv/zicond-ice-1.c b/gcc/testsuite/gcc.target/riscv/zicond-ice-1.c
new file mode 100644 (file)
index 0000000..d1f98a4
--- /dev/null
@@ -0,0 +1,13 @@
+/* { 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;
+}