0016-RISC-V-Fix-Zicond-ICE-on-large-constants.patch 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. From 36ee10a35991656d2733752a4ef4608fb59747f8 Mon Sep 17 00:00:00 2001
  2. From: Tsukasa OI <research_trasio@irq.a4lg.com>
  3. Date: Sun, 3 Sep 2023 12:39:47 +0000
  4. Subject: [PATCH 16/30] RISC-V: Fix Zicond ICE on large constants
  5. Large constant cons and/or alt will trigger ICEs building GCC target
  6. libraries (libgomp and libatomic) when the 'Zicond' extension is enabled.
  7. For instance, zicond-ice-2.c (new test case in this commit) will cause
  8. an ICE when SOME_NUMBER is 0x1000 or larger. While opposite numbers
  9. corresponding cons/alt (two temp2 variables) are checked, cons/alt
  10. themselves are not checked and causing 2 ICEs building
  11. GCC target libraries as of this writing:
  12. 1. gcc/libatomic/config/posix/lock.c
  13. 2. gcc/libgomp/fortran.c
  14. Coercing a large value into a register will fix the issue.
  15. It also coerce a large cons into a register on "imm, imm" case (the author
  16. could not reproduce but possible to cause an ICE).
  17. gcc/ChangeLog:
  18. * config/riscv/riscv.cc (riscv_expand_conditional_move): Force
  19. large constant cons/alt into a register.
  20. gcc/testsuite/ChangeLog:
  21. * gcc.target/riscv/zicond-ice-2.c: New test. This is based on
  22. an ICE at libat_lock_n func on gcc/libatomic/config/posix/lock.c
  23. but heavily minimized.
  24. ---
  25. gcc/config/riscv/riscv.cc | 21 +++++++++++++------
  26. gcc/testsuite/gcc.target/riscv/zicond-ice-2.c | 11 ++++++++++
  27. 2 files changed, 26 insertions(+), 6 deletions(-)
  28. create mode 100644 gcc/testsuite/gcc.target/riscv/zicond-ice-2.c
  29. diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
  30. index 7488ffbe680..62d800bc459 100644
  31. --- a/gcc/config/riscv/riscv.cc
  32. +++ b/gcc/config/riscv/riscv.cc
  33. @@ -3517,6 +3517,11 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
  34. gen_rtx_IF_THEN_ELSE (mode, cond,
  35. CONST0_RTX (mode),
  36. alt)));
  37. + /* CONS might not fit into a signed 12 bit immediate suitable
  38. + for an addi instruction. If that's the case, force it
  39. + into a register. */
  40. + if (!SMALL_OPERAND (INTVAL (cons)))
  41. + cons = force_reg (mode, cons);
  42. riscv_emit_binary (PLUS, dest, dest, cons);
  43. return true;
  44. }
  45. @@ -3540,11 +3545,13 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
  46. rtx temp1 = gen_reg_rtx (mode);
  47. rtx temp2 = gen_int_mode (-1 * INTVAL (cons), mode);
  48. - /* TEMP2 might not fit into a signed 12 bit immediate suitable
  49. - for an addi instruction. If that's the case, force it into
  50. - a register. */
  51. + /* TEMP2 and/or CONS might not fit into a signed 12 bit immediate
  52. + suitable for an addi instruction. If that's the case, force it
  53. + into a register. */
  54. if (!SMALL_OPERAND (INTVAL (temp2)))
  55. temp2 = force_reg (mode, temp2);
  56. + if (!SMALL_OPERAND (INTVAL (cons)))
  57. + cons = force_reg (mode, cons);
  58. riscv_emit_binary (PLUS, temp1, alt, temp2);
  59. emit_insn (gen_rtx_SET (dest,
  60. @@ -3586,11 +3593,13 @@ riscv_expand_conditional_move (rtx dest, rtx op, rtx cons, rtx alt)
  61. rtx temp1 = gen_reg_rtx (mode);
  62. rtx temp2 = gen_int_mode (-1 * INTVAL (alt), mode);
  63. - /* TEMP2 might not fit into a signed 12 bit immediate suitable
  64. - for an addi instruction. If that's the case, force it into
  65. - a register. */
  66. + /* TEMP2 and/or ALT might not fit into a signed 12 bit immediate
  67. + suitable for an addi instruction. If that's the case, force it
  68. + into a register. */
  69. if (!SMALL_OPERAND (INTVAL (temp2)))
  70. temp2 = force_reg (mode, temp2);
  71. + if (!SMALL_OPERAND (INTVAL (alt)))
  72. + alt = force_reg (mode, alt);
  73. riscv_emit_binary (PLUS, temp1, cons, temp2);
  74. emit_insn (gen_rtx_SET (dest,
  75. diff --git a/gcc/testsuite/gcc.target/riscv/zicond-ice-2.c b/gcc/testsuite/gcc.target/riscv/zicond-ice-2.c
  76. new file mode 100644
  77. index 00000000000..ffd8dcb5814
  78. --- /dev/null
  79. +++ b/gcc/testsuite/gcc.target/riscv/zicond-ice-2.c
  80. @@ -0,0 +1,11 @@
  81. +/* { dg-do compile } */
  82. +/* { dg-options "-march=rv64gc_zicond -mabi=lp64d" { target { rv64 } } } */
  83. +/* { dg-options "-march=rv32gc_zicond -mabi=ilp32d" { target { rv32 } } } */
  84. +
  85. +#define SOME_NUMBER 0x1000
  86. +
  87. +unsigned long
  88. +d (unsigned long n)
  89. +{
  90. + return n > SOME_NUMBER ? SOME_NUMBER : n;
  91. +}
  92. --
  93. 2.25.1