diff mbox series

[1/2] xtensa: Recover constant synthesis for HImode after LRA transition

Message ID 426f1bc2-0840-41f4-bb7e-d6037baf9068@yahoo.co.jp
State New
Headers show
Series [1/2] xtensa: Recover constant synthesis for HImode after LRA transition | expand

Commit Message

Takayuki 'January June' Suwa Feb. 3, 2024, 2:17 p.m. UTC
After LRA transition, HImode constants that don't fit into signed 12 bits
are no longer subject to constant synthesis:

    /* example */
    void test(void) {
      short foo = 32767;
      __asm__ ("" :: "r"(foo));
    }

    ;; before
   	.literal_position
    	.literal .LC0, 32767
    test:
    	l32r	a9, .LC0
    	ret.n

This patch fixes that:

    ;; after
    test:
    	movi.n	a9, -1
    	extui	a9, a9, 17, 15
    	ret.n

gcc/ChangeLog:

	* config/xtensa/xtensa.md (2 split patterns related to constsynth):
	Change to also accept HImode operands.
---
 gcc/config/xtensa/xtensa.md | 30 +++++++++++++++++++-----------
 1 file changed, 19 insertions(+), 11 deletions(-)

Comments

Max Filippov Feb. 3, 2024, 3:52 p.m. UTC | #1
Hi Suwa-san,

On Sat, Feb 3, 2024 at 6:20 AM Takayuki 'January June' Suwa
<jjsuwa_sys3175@yahoo.co.jp> wrote:
> After LRA transition, HImode constants that don't fit into signed 12 bits
> are no longer subject to constant synthesis:

with this change I get multiple ICEs during libgomp, libgfortran and
libstdc++ builds, e.g.:

/home/jcmvbkbc/ws/tensilica/gcc/gcc/libstdc++-v3/src/c++20/tzdb.cc:1228:3:
error: unrecognizable insn:
1228 |   }
     |   ^
(insn 3131 27 3132 2 (set (subreg:SI (reg:DI 176) 0)
       (const_int 78796800 [0x4b25800]))
"/home/jcmvbkbc/ws/tensilica/gcc/builds/gcc-14-8779-ge15d00be88c1-xtensa-call0-le/xtensa-buildroot-linux-uclibc/libstdc++-v3/include/bits/chrono.h":574:6
-1
    (nil))
during RTL pass: subreg3
/home/jcmvbkbc/ws/tensilica/gcc/gcc/libstdc++-v3/src/c++20/tzdb.cc:1228:3:
internal compiler error: in extract_insn, at recog.cc:2812
0x7cb898 _fatal_insn(char const*, rtx_def const*, char const*, int, char const*)
       /home/jcmvbkbc/ws/tensilica/gcc/gcc/gcc/rtl-error.cc:108
0x7cb8b4 _fatal_insn_not_found(rtx_def const*, char const*, int, char const*)
       /home/jcmvbkbc/ws/tensilica/gcc/gcc/gcc/rtl-error.cc:116
0x7ca31e extract_insn(rtx_insn*)
       /home/jcmvbkbc/ws/tensilica/gcc/gcc/gcc/recog.cc:2812
0x1c08b57 decompose_multiword_subregs
       /home/jcmvbkbc/ws/tensilica/gcc/gcc/gcc/lower-subreg.cc:1569
0x1c09d7d execute
       /home/jcmvbkbc/ws/tensilica/gcc/gcc/gcc/lower-subreg.cc:1834



/home/jcmvbkbc/ws/tensilica/gcc/gcc/libstdc++-v3/src/filesystem/ops.cc:936:1:
error: unrecognizable insn:
 936 | }
     | ^
(insn 260 21 261 2 (set (reg:SI 4 a4)
       (const_int 1000000000 [0x3b9aca00]))
"/home/jcmvbkbc/ws/tensilica/gcc/builds/gcc-14-8779-ge15d00be88c1-xtensa-call0-le/xtensa-buildroot-linux-uclibc/libstdc++-v3/include/bits/chrono.h":214:38
discrim 1 -1
    (nil))
during RTL pass: subreg3
/home/jcmvbkbc/ws/tensilica/gcc/gcc/libstdc++-v3/src/filesystem/ops.cc:936:1:
internal compiler error: in extract_insn, at recog.cc:2812
0x7cb898 _fatal_insn(char const*, rtx_def const*, char const*, int, char const*)
       /home/jcmvbkbc/ws/tensilica/gcc/gcc/gcc/rtl-error.cc:108
0x7cb8b4 _fatal_insn_not_found(rtx_def const*, char const*, int, char const*)
       /home/jcmvbkbc/ws/tensilica/gcc/gcc/gcc/rtl-error.cc:116
0x7ca31e extract_insn(rtx_insn*)
       /home/jcmvbkbc/ws/tensilica/gcc/gcc/gcc/recog.cc:2812
0x1c08b57 decompose_multiword_subregs
       /home/jcmvbkbc/ws/tensilica/gcc/gcc/gcc/lower-subreg.cc:1569
0x1c09d7d execute
       /home/jcmvbkbc/ws/tensilica/gcc/gcc/gcc/lower-subreg.cc:1834
diff mbox series

Patch

diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index f3953aa26b0..5242eb3c006 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -1291,28 +1291,36 @@ 
    (set_attr "length"	"2,2,2,2,2,2,3,3,3,3,6,3,3,3,3,3")])
 
 (define_split
-  [(set (match_operand:SI 0 "register_operand")
-	(match_operand:SI 1 "const_int_operand"))]
+  [(set (match_operand 0 "register_operand")
+	(match_operand 1 "const_int_operand"))]
   "!TARGET_CONST16 && !TARGET_AUTO_LITPOOLS
    && ! xtensa_split1_finished_p ()
-   && ! xtensa_simm12b (INTVAL (operands[1]))"
+   && ! xtensa_simm12b (INTVAL (operands[1]))
+   && GET_MODE (operands[0]) == GET_MODE (operands[1])
+   && (GET_MODE (operands[0]) == SImode
+       || GET_MODE (operands[0]) == HImode)"
   [(set (match_dup 0)
 	(match_dup 1))]
 {
-  operands[1] = force_const_mem (SImode, operands[1]);
+  operands[1] = force_const_mem (GET_MODE (operands[0]), operands[1]);
 })
 
 (define_split
-  [(set (match_operand:SI 0 "register_operand")
-	(match_operand:SI 1 "constantpool_operand"))]
-  "! optimize_debug && reload_completed"
+  [(set (match_operand 0 "register_operand")
+	(match_operand 1 "constantpool_operand"))]
+  "! optimize_debug && reload_completed
+   && GET_MODE (operands[0]) == GET_MODE (operands[1])
+   && (GET_MODE (operands[0]) == SImode
+       || GET_MODE (operands[0]) == HImode)"
   [(const_int 0)]
 {
-  rtx x = avoid_constant_pool_reference (operands[1]);
-  if (! CONST_INT_P (x))
+  rtx x, dst;
+  if (! CONST_INT_P (x = avoid_constant_pool_reference (operands[1])))
     FAIL;
-  if (! xtensa_constantsynth (operands[0], INTVAL (x)))
-    emit_move_insn (operands[0], x);
+  if (GET_MODE (dst = operands[0]) == HImode)
+    dst = gen_rtx_REG (SImode, REGNO (dst));
+  if (! xtensa_constantsynth (dst, INTVAL (x)))
+    emit_move_insn (dst, x);
   DONE;
 })