1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
graphic: 0.986
TCG: 0.952
semantic: 0.941
performance: 0.909
ppc: 0.866
user-level: 0.798
device: 0.796
PID: 0.779
files: 0.779
socket: 0.777
debug: 0.756
architecture: 0.726
network: 0.695
kernel: 0.668
register: 0.659
permissions: 0.653
vnc: 0.607
peripherals: 0.606
hypervisor: 0.560
VMM: 0.548
risc-v: 0.544
assembly: 0.500
boot: 0.491
arm: 0.471
x86: 0.462
mistranslation: 0.411
virtual: 0.406
i386: 0.311
KVM: 0.258
Infinite recursion in tcg_gen_mulu2_i32 for certain 32-bit hosts.
Description of problem:
`tcg_gen_mulu2_i32` infinitely recurses on a 32-bit host (TCG target) that has neither `TCG_TARGET_HAS_mulu2_i32` nor `TCG_TARGET_HAS_muluh_i32`.
I don't actually think there is any host that is 32-bits and has neither mulu2 nor muluh. The only reference I found is [this](https://gitlab.com/qemu-project/qemu/-/commit/df9ebea53ebc1c98217743f56c30ae3a46031bb9) commit, which adds an `#error` if that situation is hit. But the check, which [still exists](https://gitlab.com/qemu-project/qemu/-/blob/v7.2.0/include/tcg/tcg.h#L174), checks if those flags are *defined*, not for their value. I guess, over the years as the code was refactored, the check wasn't updated because, frankly, there aren't any hosts that match that situation (except mine).
One easy fix is to change the check mentioned above to check the actual macro value so that compilation fails. I can create a PR for that.
Steps to reproduce:
(Note: I'm linking to the v7.2.0 tag so that these links stay relevant).
1. `tcg_gen_mulu2_i32` [calls](https://gitlab.com/qemu-project/qemu/-/blob/v7.2.0/tcg/tcg-op.c#L890) `tcg_gen_mul_i64`.
2. `tcg_gen_mul_i64` on 32-bit hosts, due to [this](https://gitlab.com/qemu-project/qemu/-/blob/v7.2.0/tcg/tcg-op.c#L1097) check for `TCG_TARGET_REG_BITS == 32`, is defined [here](https://gitlab.com/qemu-project/qemu/-/blob/v7.2.0/tcg/tcg-op.c#L1218), and [calls](https://gitlab.com/qemu-project/qemu/-/blob/v7.2.0/tcg/tcg-op.c#L1226) `tcg_gen_mulu2_i32`.
3. Rinse and repeat.
4. Eventually, as gen_mulu2/mul functions spill while trying to allocate temps, they will overflow the TB buffer. This will restart code generation with smaller and smaller block sizes, until the block size reaches 1 instruction. TCG will then give up and [assert](https://gitlab.com/qemu-project/qemu/-/blob/v7.2.0/accel/tcg/translate-all.c#L869).
Additional information:
|