The fix addresses a crash that may happen on Windows machines due to the way 
memory pages are allocated.
https://github.com/espressif/esp-idf/issues/12180

Minimal C code to reproduce the issue:
```
/*  Compile with -Og.  */

#define PIX1(d, s) ((d)[0] = (s)[0])
#define PIX2(d, s) (PIX1 (d, s), (d)[1] = (s)[1])
#define PIX3(d, s) (PIX2 (d, s), (d)[2] = (s)[2])

#define LOOP(N, I)                                          \
  for (int y = y0; y < y1; y++)                             \
    for (int x = x0; x < x1; x++)                           \
      {                                                     \
        unsigned j = y * stride + x * bpp - off;            \
        unsigned i = (I) * bpp;                             \
        PIX##N (to + i, from + j);                          \
      }                                                     \
  n = (x1 - x0) * w * bpp;                                  \
  p = to + x0 * w * bpp

#define ROTATE(N)                                           \
  switch (mode)                                             \
    {                                                       \
    case 0: LOOP (N, x * w + y); break;                     \
    case 1: LOOP (N, x * w + w - 1 - y); break;             \
    case 2: LOOP (N, (h - 1 - x) * w + y); break;           \
    case 3: LOOP (N, (h - 1 - x) * w + w - 1 - y); break;   \
    case 4: LOOP (N, y * w + w - 1 - x); break;             \
    case 5: LOOP (N, (h - 1 - y) * w + x); break;           \
    case 6: LOOP (N, (h - 1 - y) * w + w - 1 - x); break;   \
    case 7: LOOP (N, y * w + x); break;                     \
    }

void flush (void *, unsigned);

void
draw (unsigned char *to, const unsigned char *from, int mode, int w, int h,
      int bpp, int x0, int y0, int x1, int y1)
{
  unsigned stride = (x1 - x0) * bpp;
  unsigned off = y0 * stride + x0 * bpp;
  unsigned n = 0;
  unsigned char *p = to;
  if (bpp == 1)
    ROTATE (1)
  else if (bpp == 2)
    ROTATE (2)
  else if (bpp == 3)
    ROTATE (3)
  flush (p, n);
}
```

Running it under Valgrind on Linux confirms the issue:

```
$ valgrind --undef-value-errors=no --redzone-size=4096 \
    
~/.espressif/tools/xtensa-esp-elf/esp-16.2.0_20260914/xtensa-esp-elf/libexec/gcc/xtensa-esp-elf/16.2.0/cc1
 \
    -quiet repro.c -Og -o /dev/null
==PID== Invalid read of size 2
==PID==    at 0x11205C5: xt_true_regnum(rtx_def*) (in cc1)
==PID==    by 0x1120610: xtensa_valid_move(machine_mode, rtx_def**) (in cc1)
==PID==    by 0x1121B32: xtensa_emit_move_sequence(rtx_def**, machine_mode) (in 
cc1)
==PID==    by 0x16C315E: gen_movsi(rtx_def*, rtx_def*) (in cc1)
==PID==    by 0x964CF0: emit_move_insn_1(rtx_def*, rtx_def*) (in cc1)
==PID==    by 0x96512D: emit_move_insn(rtx_def*, rtx_def*) (in cc1)
==PID==    by 0xB7D82F: ??? (in cc1)
==PID==    by 0xB7F8FA: ira_emit(bool) (in cc1)
==PID==    by 0xB5DDFF: ??? (in cc1)
==PID==    by 0xC67237: execute_one_pass(opt_pass*) (in cc1)
==PID==    ...
==PID==  Address 0x174df6e4 is 146 bytes after a block of size 2,402 alloc'd
==PID==    at 0x4846828: malloc (in 
/usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==PID==    by 0x1A22F7B: xmalloc (in cc1)
==PID==    by 0xCEAC2E: resize_reg_info() (in cc1)
==PID==    by 0xB5D6E8: ??? (in cc1)
==PID==    by 0xC67237: execute_one_pass(opt_pass*) (in cc1)
==PID==    ...
==PID==
==PID== Invalid read of size 2
==PID==    at 0x11205C5: xt_true_regnum(rtx_def*) (in cc1)
==PID==    by 0x1120610: xtensa_valid_move(machine_mode, rtx_def**) (in cc1)
==PID==    by 0x192B58C: recog_8(rtx_def*, rtx_insn*, int*) (in cc1)
==PID==    by 0xB7D8ED: ??? (in cc1)
==PID==    by 0xB7F8FA: ira_emit(bool) (in cc1)
==PID==    by 0xB5DDFF: ??? (in cc1)
==PID==    by 0xC67237: execute_one_pass(opt_pass*) (in cc1)
==PID==    ...
==PID==  Address 0x174df6e4 is 146 bytes after a block of size 2,402 alloc'd
==PID==    (same allocation stack as above)
==PID==
==PID== ERROR SUMMARY: 210 errors from 2 contexts (suppressed: 0 from 0)
```

The issue can also be reproduced on Windows using the gflags utility:

```
PS C:\Users\qweqe> $gflags = 'C:\Program Files (x86)\Windows 
Kits\10\Debuggers\x64\gflags.exe'
PS C:\Users\qweqe> & $gflags /p /enable cc1.exe /full
PS C:\Users\qweqe> & $gflags /p
PS C:\Users\qweqe>
PS C:\Users\qweqe> & $gcc -c "$HOME\rgb601_esp-16.2.0_20260914.i" @f -Og -o 
NUL; "driver -Og exit=$LASTEXITCODE"
during RTL pass: ira
/tmp/idf601/components/esp_lcd/rgb/esp_lcd_panel_rgb.c: In function 
'rgb_panel_draw_bitmap':
/tmp/idf601/components/esp_lcd/rgb/esp_lcd_panel_rgb.c:741:1: internal compiler 
error: Segmentation fault
C:/Users/qweqe/.espressif/tools/xtensa-esp-elf/esp-16.2.0_20260914/xtensa-esp-elf/bin/../libexec/gcc/xtensa-esp-elf/16.2.0/cc1.exe
 -fpreprocessed C:\Users\qweqe\rgb601_esp-16.2.0_20260914.i -quiet -dumpbase 
NUL.i -dumpbase-ext .i -mdynconfig=xtensa_esp32s3.so -mlongcalls 
-mdisable-hardware-atomics -gdwarf-4 -ggdb -Og -std=gnu23 -ffunction-sections 
-fdata-sections -fstrict-volatile-bitfields -fno-lto -fno-jump-tables 
-fno-tree-switch-conversion -fno-builtin-memcpy -fno-builtin-memset 
-fno-builtin-bzero -fzero-init-padding-bits=all -o 
C:\Users\qweqe\AppData\Local\Temp\ccVD5s7l.s
Please submit a full bug report, with preprocessed source (by using 
-freport-bug).
See <https://gcc.gnu.org/bugs/> for instructions.
driver -Og exit=1
PS C:\Users\qweqe>
```

________________________________
From: Alexey Lapshin
Sent: Tuesday, September 29, 2026 12:00 AM
To: [email protected] <[email protected]>
Cc: [email protected] <[email protected]>; Alexey Gerenkov 
<[email protected]>; [email protected] 
<[email protected]>; Alexey Lapshin <[email protected]>
Subject: [PATCH] xtensa: Don't index reg_renumber before LRA in xt_true_regnum

xt_true_regnum is used by move expanders and insn conditions, which
IRA invokes through emit_move_insn and recog_memoized when emitting
moves for regional allocation.  At that point reg_renumber has not
been resized to cover the new pseudos, so indexing it reads out of
bounds.  Before LRA starts reg_renumber holds no final assignments,
so only consult it once LRA is in progress or reload has completed.

gcc/ChangeLog:

        * config/xtensa/xtensa.cc (xt_true_regnum): Don't index
        reg_renumber before LRA starts.
---
 gcc/config/xtensa/xtensa.cc | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index 6b5d8d1099a..99a244bf9fd 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -546,9 +546,12 @@ xt_true_regnum (rtx x)
 {
   if (REG_P (x))
     {
+      /* Before LRA, reg_renumber need not cover pseudos created since it
+        was last resized (e.g. by ira_emit during regional allocation).  */
       if (! HARD_REGISTER_P (x)
           && reg_renumber
-         && (lra_in_progress || reg_renumber[REGNO (x)] >= 0))
+         && (lra_in_progress
+             || (reload_completed && reg_renumber[REGNO (x)] >= 0)))
         return reg_renumber[REGNO (x)];
       return REGNO (x);
     }
--
2.55.0

Reply via email to