123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- From 36ee10a35991656d2733752a4ef4608fb59747f8 Mon Sep 17 00:00:00 2001
- From: Tsukasa OI <research_trasio@irq.a4lg.com>
- Date: Sun, 3 Sep 2023 12:39:47 +0000
- Subject: [PATCH 16/30] RISC-V: Fix Zicond ICE on large constants
- Large constant cons and/or alt will trigger ICEs building GCC target
- libraries (libgomp and libatomic) when the 'Zicond' extension is enabled.
- For instance, zicond-ice-2.c (new test case in this commit) will cause
- an ICE when SOME_NUMBER is 0x1000 or larger. While opposite numbers
- corresponding cons/alt (two temp2 variables) are checked, cons/alt
- themselves are not checked and causing 2 ICEs building
- GCC target libraries as of this writing:
- 1. gcc/libatomic/config/posix/lock.c
- 2. gcc/libgomp/fortran.c
- Coercing a large value into a register will fix the issue.
- It also coerce a large cons into a register on "imm, imm" case (the author
- could not reproduce but possible to cause an ICE).
- gcc/ChangeLog:
- * config/riscv/riscv.cc (riscv_expand_conditional_move): Force
- large constant cons/alt into a register.
- gcc/testsuite/ChangeLog:
- * gcc.target/riscv/zicond-ice-2.c: New test. This is based on
- an ICE at libat_lock_n func on gcc/libatomic/config/posix/lock.c
- but heavily minimized.
- ---
- gcc/config/riscv/riscv.cc | 21 +++++++++++++------
- gcc/testsuite/gcc.target/riscv/zicond-ice-2.c | 11 ++++++++++
- 2 files changed, 26 insertions(+), 6 deletions(-)
- create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-ice-2.c
- diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
- index 7488ffbe680..62d800bc459 100644
- --- a/gcc/config/riscv/riscv.cc
- +++ b/gcc/config/riscv/riscv.cc
- @@ -3517,6 +3517,11 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
- gen_rtx_IF_THEN_ELSE (mode, cond,
- CONST0_RTX (mode),
- alt)));
- + /* CONS might not fit into a signed 12 bit immediate suitable
- + for an addi instruction. If that's the case, force it
- + into a register. */
- + if (!SMALL_OPERAND (INTVAL (cons)))
- + cons = force_reg (mode, cons);
- riscv_emit_binary (PLUS, dest, dest, cons);
- return true;
- }
- @@ -3540,11 +3545,13 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
- rtx temp1 = gen_reg_rtx (mode);
- rtx temp2 = gen_int_mode (-1 * INTVAL (cons), mode);
-
- - /* TEMP2 might not fit into a signed 12 bit immediate suitable
- - for an addi instruction. If that's the case, force it into
- - a register. */
- + /* TEMP2 and/or CONS might not fit into a signed 12 bit immediate
- + suitable for an addi instruction. If that's the case, force it
- + into a register. */
- if (!SMALL_OPERAND (INTVAL (temp2)))
- temp2 = force_reg (mode, temp2);
- + if (!SMALL_OPERAND (INTVAL (cons)))
- + cons = force_reg (mode, cons);
-
- riscv_emit_binary (PLUS, temp1, alt, temp2);
- emit_insn (gen_rtx_SET (dest,
- @@ -3586,11 +3593,13 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
- rtx temp1 = gen_reg_rtx (mode);
- rtx temp2 = gen_int_mode (-1 * INTVAL (alt), mode);
-
- - /* TEMP2 might not fit into a signed 12 bit immediate suitable
- - for an addi instruction. If that's the case, force it into
- - a register. */
- + /* TEMP2 and/or ALT might not fit into a signed 12 bit immediate
- + suitable for an addi instruction. If that's the case, force it
- + into a register. */
- if (!SMALL_OPERAND (INTVAL (temp2)))
- temp2 = force_reg (mode, temp2);
- + if (!SMALL_OPERAND (INTVAL (alt)))
- + alt = force_reg (mode, alt);
-
- riscv_emit_binary (PLUS, temp1, cons, temp2);
- emit_insn (gen_rtx_SET (dest,
- diff --git a/gcc/testsuite/gcc.target/riscv/zicond-ice-2.c b/gcc/testsuite/gcc.target/riscv/zicond-ice-2.c
- new file mode 100644
- index 00000000000..ffd8dcb5814
- --- /dev/null
- +++ b/gcc/testsuite/gcc.target/riscv/zicond-ice-2.c
- @@ -0,0 +1,11 @@
- +/* { dg-do compile } */
- +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
- +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32d" { target { rv32 } } } */
- +
- +#define SOME_NUMBER 0x1000
- +
- +unsigned long
- +d (unsigned long n)
- +{
- + return n > SOME_NUMBER ? SOME_NUMBER : n;
- +}
- --
- 2.25.1
|