<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/63792>63792</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[llvm][ExpandMemCmp] volatile is not honored
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
yonghong-song
</td>
</tr>
</table>
<pre>
This may not be an expandMemCmp pass bug. But at least it is expandMemCmp caused "incorrect" transformation. So we can start the discussion here to find out whether we have a problem and how to fix the problem.
The original issue is reported by a bcc issue (https://github.com/iovisor/bcc/pull/4635#discussion_r1258655166).
The following is a simplified test case.
```
$ cat t.c
const volatile unsigned char addr[16] = {0};
const volatile int val = 1;
int foo1()
{
unsigned t = 0;
return __builtin_memcmp((void *)addr, (void *)&t, 4);
}
int foo2()
{
return addr[1] == 1;
}
int foo3()
{
return val;
}
$ cat run.sh
clang --target=bpf -O2 -g -mcpu=v3 -c t.c
$ ./run.sh
$ llvm-objdump -d t.o
t.o: file format elf64-bpf
Disassembly of section .text:
0000000000000000 <foo1>:
0: b4 00 00 00 00 00 00 00 w0 = 0x0
1: 95 00 00 00 00 00 00 00 exit
0000000000000010 <foo2>:
2: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0x0 ll
4: 71 11 01 00 00 00 00 00 r1 = *(u8 *)(r1 + 0x1)
5: b4 00 00 00 01 00 00 00 w0 = 0x1
6: 16 01 01 00 01 00 00 00 if w1 == 0x1 goto +0x1 <LBB1_2>
7: b4 00 00 00 00 00 00 00 w0 = 0x0
0000000000000040 <LBB1_2>:
8: 95 00 00 00 00 00 00 00 exit
0000000000000048 <foo3>:
9: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0x0 ll
11: 61 10 00 00 00 00 00 00 r0 = *(u32 *)(r1 + 0x0)
12: 95 00 00 00 00 00 00 00 exit
$
```
In the above example, global volatile const variable won't be treated pure constant since there is also volatile modifier, so loading these const volatile variables will actually have a 'load' operation. But if the variable (const volatile array) is passed as a parameter to __builtin_memcmp, the 'volatile' modifier does not have an effect and the ExpandMemCmp will replace the 'load' with a constant. See function 'foo1' disasm code.
The following the IR generated by frontend,
```
$ clang --target=bpf -O2 -g -mcpu=v3 -S -emit-llvm -Xclang -disable-llvm-passes t.c
$ cat t.ll
...
@addr = dso_local constant [16 x i8] zeroinitializer, align 1, !dbg !0
@val = dso_local constant i32 1, align 4, !dbg !7
; Function Attrs: nounwind
define dso_local i32 @foo1() #0 !dbg !23 {
entry:
%t = alloca i32, align 4
call void @llvm.lifetime.start.p0(i64 4, ptr %t) #3, !dbg !29
call void @llvm.dbg.declare(metadata ptr %t, metadata !27, metadata !DIExpression()), !dbg !30
store i32 0, ptr %t, align 4, !dbg !30, !tbaa !31
%call = call i32 @memcmp(ptr noundef @addr, ptr noundef %t, i64 noundef 4) #3, !dbg !35
call void @llvm.lifetime.end.p0(i64 4, ptr %t) #3, !dbg !36
ret i32 %call, !dbg !37
}
...
define dso_local i32 @foo2() #0 !dbg !48 {
entry:
%0 = load volatile i8, ptr getelementptr inbounds ([16 x i8], ptr @addr, i64 0, i64 1), align 1, !dbg !49, !tbaa !50
%conv = zext i8 %0 to i32, !dbg !49
%cmp = icmp eq i32 %conv, 1, !dbg !51
%conv1 = zext i1 %cmp to i32, !dbg !51
ret i32 %conv1, !dbg !52
}
...
define dso_local i32 @foo3() #0 !dbg !53 {
entry:
%0 = load volatile i32, ptr @val, align 4, !dbg !54, !tbaa !31
ret i32 %0, !dbg !55
}
```
Note that global variable `addr` does not have volatile modifier in the IR. Instead, 'volatile' is annotated in the load itself, see foo2() and foo3().
The missing 'volatile' semantics in global variable 'addr' caused incorrect transformation in ExpandMemCmp in foo1().
So this may not be a ExpandMemCmp issue, but I think this is a good starting place to discuss how to address this issue.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysWF1v47rR_jXMzcCGRMmWfZGLTbIBFnjfFuiei94FlDSSeUqRKknZzv76YqgPy4qye7aoYSQyzXnmkzOPKZyTtUZ8ZLsntnt5EJ0_Gfv4bnR9MrreOKPrh9yU749_nKSDRryDNh5yBKEBr63Q5f9j89y00ArnIO_qLTx1HoQHhcJ5kB6ku99ZiM5hCYxzqQtjLRaecQ7eCu0qYxvhpdFb-G7gglAIDc4L68GfEErpis45aTSc0CJ4A5XUJZjOw-WE_oSWhE7ijCCgtSZX2IDQJZzMpd99DUDDV1sWvbDoS__3jxOCsbKWWiiQznVIpltsjfVYQv4OAvKiGL5i_HDyvnUs-cL4K-OvtfSnLt8WpmH8VZqzdMYy_poXBeOvbacU46_pPtkxntzceLMx3x32u1283zN-3N4sqYxS5iJ1TUYIcLJplawkluDReSiEwzvr2T4a3v1HnkIhPPht0S8URjsPZ6OElwqh0yHxJRQnYUGUpWW7p3jPdi_Akhdg2VPEsheWPK1KS-3hLFTYGk-baLUyJmb8wPhxsCMbvoSbSh_kokkOwKLvrIa3t7yTykv91mBTNG0AOpyNpGr5wvgx2Mmf4X6V8b2n1ZSeR1Cyfm4V_8SqQfUYgSEA944tsZKfY52F-ig6JsR2eutOQ1SV0DVsNl7YGj1LXvK2gs3fOWxq2DRF27Hk5ZzAprilkWC2jL_OYWhNqXOzMfmfZde0sCnBb828Ouhj8gUAoKL89ccMUFX7dJO31Xzri3TCOWxy9Q6mAocFnUfYerx6KvbZ1mjxApY8hwJIvk47oX9Fg3oAyFOIopX3Jerr4hrdScYkedyty-BV-s8tikeL-IpFnHDjA0TxOvTq28ajjaDUHVxKcFkMcbyCOIiFcj10h6luD_QFf4LoGk_1NODtPglYvBKw-E5yf5OM90EgXkrKCi7xWOfRNYbaeEOW0DNLnv_v6Sl-C0GbA2e_n8O1rKTRvYpFXg43Lf9d1tPDkPVkBf04C87_KvdxfAPdxxCvCkfzCkj4SglEixKI-W9FgqewPgnC3286zD2RmzMCXkXTKqSeWSuTC3Xr7EOjF1aKXCFcjGY8CwPfWxQ0B9vODtuE9uCkLpCgbZiWQjlzA2tMSSMrtGxnQBlR0kDzJ3STpnHvqNLBRSoFovCdUOp9nOWMZyTOeAamRTtwBKIasgqeTSYzflhAC2vFO-NHMpBoCpYgaKa2wooGPVpiBh9nz3PAZTwbgUj56BKUBl3gQr2BGrCqsPCBbJDc1znlCS5ZbJXogzV35yL9CcQU0S18R4Sq033bZTzrR2pG5Ee4BgpT4gfecmMLhP7tH1Cjpij1vKWyRnvUJePPv6IMf3EifYcNNtJvaOzA5p-DGFmYKwyrmxBpR5MLPn0tuYpSw9J2O7qYRjSaw-EpnXlTphDqVn6BtMAV5IEG9w-0RmrppVDyR192QslaQ9yThrjMa_oXwQQ-spgVbJnwXrDHSO8xsgFjhEqe4HVM2hfvLRFD0KbTFyKo_aYSK6lxpotUsDS6kSZgPIlmWnhCVGwQR-3tO8GOXYLxXc-lhCI8gpvZO20rhKITTnwpjSg3WyUr9LLBbaDW2zZi_CD3ae9j621AHsxJ7v2mxU9xy7zellgoYZHxQ4NelMKLGeIzTIuElS1XXr59vbYWAzceSBa95wYk0WSA84baTsIhujf8k5wl0fDZ5yKoS-J5LIM_FM7wMORmYqKETvkssYKhKkel0_KgnEI5rqXrYUx2fyU9qMvfSk6yhxkX7V3o_VrsG6t3oqfTgftJjfL1GqV5-9Ma7Ucf9bvZL4jD6E2NHhU2qD19kjqnwDlq43eHe3L-FnoKSjQ-xEOhrB749LhI_C76vCndN6e-Mow-Byd-4NWDPPReeTOeuLmmO7mmDWKSHvDfU0KMPpPYwspdvNQZz5TGI-Ca2pnoPPEEsdjIb5m_9dpf96dkPfe7tf70q9T3xg_JpB9Ln53XXfrhvK54GS2EdstfXmt86G_G0yQWfmJAE3_Y9wW2jxYz_gOtAamHcbuFb9p5pIH-vGQMxIq0Nj4M40EiBER6h6oK3Igm_u18EYW4hfzDrG-kczTpF3ocNkJ7WThS8sEpnvWnJhuvX6a7l8XFC0nfcRepZz_qB2O-G_DL-6CFlHNdIJh55-Eb7db_6mXCdUZtTNnf65AnAy8y4_3OeFtDJqNzo5zrcPtQPiblMTmKB3yM94djlB75gT-cHkXJD8jTY8IznpUx5mlWFnl1LKu0Kqoie5CPPOJJlMVxlPKY8-0xy_fZsRJRUeZRIXKWRtgIqbahBxtbPwSVj_skO_IHJXJULtyTca7xMnrI2e7lwT4GypN3taMeLp13NxQvvQoXbLRCnWz3NA8VEZfb2RjqzWhjsXzorHr8yS1TAOz_bVpr_gw3aa_BMMf4azD8PwEAAP__NYySMg">