<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/86880>86880</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Frame pointer corrupted by __cpuid after #85193
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
thurstond
</td>
</tr>
</table>
<pre>
"[InstCombine] Support and/or in getFreelyInvertedImpl using DeMorgan's Law" (https://github.com/llvm/llvm-project/pull/85193) in isolation is a correct and innocuous InstCombine patch, but it appears to be triggering a latent miscompilation bug that is particularly noticeable when using the cpuid instruction in the presence of register pressure.
## Context
The `cpuid` instruction writes to registers RAX, RBX, RCX, and RDX. Since RBX is used as the frame pointer (if enabled), it typically needs to be preserved, such as by exchanging it back and forth with another register. For example, clang's `__cpuid` macro has:
```
/* x86-64 uses %rbx as the base register, so preserve it. */
#define __cpuid(__leaf, __eax, __ebx, __ecx, __edx) \
__asm(" xchgq %%rbx,%q1\n" \
" cpuid\n" \
" xchgq %%rbx,%q1" \
: "=a"(__eax), "=r" (__ebx), "=c"(__ecx), "=d"(__edx) \
: "0"(__leaf))
```
(https://github.com/llvm/llvm-project/blob/main/clang/lib/Headers/cpuid.h#L268)
## Reproducer
```
git clone https://github.com/pytorch/cpuinfo.git # commit 6543fec09b2f04ac4a666882998b534afc9c1349
cd cpuinfo/src
clang -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -O2 -I../include -I. x86/isa.c -msse4.2 -gmlt -c -o isa.o
llvm-objdump -D -S isa.o | grep cpuid -A 1 -B 1
```
### clang at revision cf5cd98e74275ed6198b4bbe76cec250ade2c186:
```
75: 48 87 f3 xchgq %rbx, %rsi
78: 0f a2 cpuid
7a: 48 87 f3 xchgq %rbx, %rsi
# Editor's note: this works; it is using %rsi as temporary storage, which happens to be available.
--
99: 48 87 f3 xchgq %rbx, %rsi
9c: 0f a2 cpuid
9e: 48 87 f3 xchgq %rbx, %rsi
--
ce: 48 87 cb xchgq %rbx, %rcx
d1: 0f a2 cpuid
d3: 48 87 cb xchgq %rbx, %rcx
# This doesn't work, because %rcx is also modified by cpuid. As a result, %rbx is corrupted, and subsequent use of the frame pointer leads to a segfault or memory corruption.
--
127: 48 87 f3 xchgq %rbx, %rsi
12a: 0f a2 cpuid
12c: 48 87 f3 xchgq %rbx, %rsi
--
a54: 48 87 f3 xchgq %rbx, %rsi
a57: 0f a2 cpuid
a59: 48 87 f3 xchgq %rbx, %rsi
--
a72: 48 87 f3 xchgq %rbx, %rsi
a75: 0f a2 cpuid
a77: 48 87 f3 xchgq %rbx, %rsi
```
### clang at the immediately preceding revision (6d30223f7c66ca07ea7ff40ffba426f2dc789e74) with the same compile command does not use %rcx:
```
75: 48 87 f3 xchgq %rbx, %rsi
78: 0f a2 cpuid
7a: 48 87 f3 xchgq %rbx, %rsi
--
99: 48 87 f3 xchgq %rbx, %rsi
9c: 0f a2 cpuid
9e: 48 87 f3 xchgq %rbx, %rsi
--
ce: 4c 87 fb xchgq %rbx, %r15
d1: 0f a2 cpuid
d3: 4c 87 fb xchgq %rbx, %r15
--
122: 48 87 f3 xchgq %rbx, %rsi
125: 0f a2 cpuid
127: 48 87 f3 xchgq %rbx, %rsi
--
a55: 48 87 f3 xchgq %rbx, %rsi
a58: 0f a2 cpuid
a5a: 48 87 f3 xchgq %rbx, %rsi
--
a73: 48 87 f3 xchgq %rbx, %rsi
a76: 0f a2 cpuid
a78: 48 87 f3 xchgq %rbx, %rsi
```
N.B. Memory sanitizer with track-origins was used as a convenient way to increase register pressure, but I believe this could happen without sanitizers.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzUWE1v4zjS_jX0pSBDor4PPiTxa7wBZnaB9Bz6FlBUSeK0RKpJKrH31y9ISY4zk87Gm1xWMCKFFKueKlY9VSIzRrQScUfSW5LuN2yyndI7203aWCXrTaXq045QStLbe2nsnRoqIZGke_g2jaPSFpisCT0oDUJCi_agEfvTvXxCbbG-H8YeJiNkC3v8XemWSUJzA7-xZ0IpEFp01o6GxDeEHgg9tMJ2U7XlaiD00PdP6y0YtfoTuSX0ME59T-ihSKMyJrR0aoVRPbNCuSdgwJXWyD0yEFIqPqnJwAV8GJnlHaF3UE0WhAU2jsi0AaugQrBatC1qB5pBzyxKC4MwXA2jWPRUUwu2Y9YpHJm2gk890_0JpLKCI6t6hOcO5WK77RD4OAmHx1g98Rms9BOjRoOSI6gGNLbCWNR-0EwatyTck_Bm-UtjQmO4U9Li0V7O_NEhkCz0OkgWvlLzrIVFb9sq3cDDzXdn_sPtfLvzN-evh_33LXwTDs7D7Xdn3mSwBmY81EazAWFUQjqMhBaiAZTO2prQ0skQFuxpFJz1zhmI9epUb6V-ci_egZl452RWJ8Aj75hsnZeEhYrxHx5Ho7Tt4FnYDphUtkN9Rr8FF214ZMPYo5PGeyZbH1YkCx8fz04YGNcKOubD69KNWbj8Fq8eCL2BY5EFWeLMNUBoqqvjanXFDJ61e_jqbA4IuwVCvZB1j2psXJCtSGjx-Ngja9zKx0dkx-WhWh_4-lAfXUCT9G4WBQDw-MjMQGjhsgWOvGt_gkM3AyT0jtD0Z0TSO-nT6bzSvz6r_9vc-Xpf5ltrSOxFk3jP3M1Z5u3xWz9P6CWvFwMvZvh5CX89UZ8n3nDAhdpwfW_2Zul-b2_o9axS9aoi9DAwIQk9LBF16IUb_H9kNWrjxp1Htx2h8W80K170X2bnA45a1RNH_U7MtcIC75VEeAfpeLJKO57yemWjtm6Z08HVMAgLWZrEDfKwrGgTJownLMuyoqBlWVRpnLCGlzyKkwUlr2GRQ-jBaL6MOlMhaAyTwop_IYn3Aw5Kny7GgnkksJrxH4HSohXSkHhPIWikCtQgbOCpIVipIfgnheB-uyX0ICTvpxrdvy7H3IhhWw7BYAwmWwpBO_QWAg6BAjelYEbmd0hVf9bTMEKwh-DbOp3fQatxXCg1uIEIgluI3g6Gi73xrvP2Mgsan4Rx_MiblNdlgXlC8xTrLCqLKqkqzDOOnKYhq5HyqMjeZ5E5UvPUxWpSQJFDE6_JBefU8k9GvFpSuCVhA4wuGXs5yV7Je_P6D0qc0f9XC6u0p0ipLDqZthMGnpX-YUh866jXU72j4Xm1Jz8cRqWZPoGxSrPWs-1zJ3gHnSuZciV39sRE78rAUq6C4NKIsrzaKSV_ccqvrktnlfhZP72GzC_k8eoaefx4KaeO3tncOv4aJW6H_3DbWSs0rr-yfmN9f4OcTQaXRb496o2CQdWiEVi7AjxzGty4zkmjmXq7aqn8AtdNTaOdC7crzWaqDP6cXFfkRKvmjdagRzZXfgYG24ZNvQWlYWGWRaRQ8q14iWh-bbxElF0XLxHlXxowLE0-naiznPzXAcPS8mtB5_TToNnMeB_3_Kz4mh3-KKG7KBTDgLVgFvuTa9E41o7RzlRPaJHVcUhp3OQ8yzgLc2R50yRh01QsoVlDa54XJeaJa0R8--nEGhfbc__v74PLA5dtjk7hJcFeSsT_RnE4h0P56cia37nk7b_h_ThJX0HR3Eu7ij2j9FcU_dEAXql7Vf6-nr-wG72e3dJfe_WvbPmZKGBp-kUs9k7YsvTDYfshDou_BnKe_Tc8VnyWx_6xvd3C73NZXNttvRDPZbcNz-zlU5wBV_IJpXA1-JmdXKEVkmu8_FA9HyGs5xz3UGEv8Ann3o-rqa-XPs4rVJN9gWCWyrypd3FdxiXb4C7KoyjN8yguN90uamhTFBEvyrBKGxqyKi7LgmOdRlkdNXQjdjSkSRjTnNIwjYttE-c0rpo0KYom5kVGkhAHJvqta_S3SrcbYcyEuyIrinDTswp748-lKJX4DH7Sn0TtN3rnPw6qqTUkCXthrHmRYoXtcXd41Y-cmxjX8Swf5sCa-RQj9mdJm0n3u6u_Gz0q92noUf87AAD__1hCUic">