<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/61169>61169</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
EarlyCSE drops debug info for pointer values derived from arguments
</td>
</tr>
<tr>
<th>Labels</th>
<td>
debuginfo,
llvm:optimizations
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
jryans
</td>
</tr>
</table>
<pre>
The `EarlyCSE` pass removes debug value info for portions of the `oid` pointer
array, even though these values must be available since they derive from
function arguments. The `SROA` pass just before this also seems to drop some
value info for the same variable.
## Versions
* Clang: version 17.0.0 (https://github.com/llvm/llvm-project.git 87cf39aa349b83ae3b7d16c30ac7a8ffa0ad098c)
* LLDB: version 17.0.0git (git@github.com:llvm/llvm-project.git revision c820e60844ee1e5f084dd7761576bd0bd4927264)
## Compiler Explorer
* [Optimisation pipeline view using x86-64 Clang trunk (may change over time)](https://godbolt.org/z/h7dbaWozP)
## Program source
```c
struct object_id {
int algo;
};
struct object {
struct object_id oid;
};
struct entry {
struct object *item;
};
int example(int n, struct entry *ent0, struct entry *ent1) {
const struct object_id *(oid[2]);
struct object_id mb_oid;
if (n) {
oid[0] = &mb_oid;
oid[1] = &ent0->item->oid;
} else {
int swap = 0;
oid[swap] = &ent0->item->oid;
oid[1 - swap] = &ent1->item->oid;
}
return oid[0]->algo;
}
```
## Debug info view
```
$ clang -fno-discard-value-names -fno-inline -g -O1 -c -o example-O1.o
$ llvm-dwarfdump -n example example-O1.o
0x00000032: DW_TAG_subprogram
DW_AT_low_pc (0x0000000000000000)
DW_AT_high_pc (0x0000000000000015)
DW_AT_frame_base (DW_OP_reg6 RBP)
DW_AT_call_all_calls (true)
DW_AT_name ("example")
DW_AT_decl_line (13)
DW_AT_prototyped (true)
DW_AT_type (0x000000a7 "int")
DW_AT_external (true)
$ llvm-dwarfdump -n oid example-O1.o
0x00000072: DW_TAG_variable
DW_AT_location (0x00000000:
[0x0000000000000011, 0x0000000000000013): DW_OP_reg0 RAX, DW_OP_piece 0x8)
DW_AT_name ("oid")
DW_AT_decl_line (14)
DW_AT_type (0x000000f7 "const object_id*[2]")
```
Location for `oid` is missing for most of the function, and the location that is
present only covers part of the array.
## IR before `EarlyCSE`
```llvm
if.then: ; preds = %entry
call void @llvm.dbg.value(metadata ptr undef, "oid", metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64))
%0 = load ptr, ptr %ent0, align 8
call void @llvm.dbg.value(metadata ptr %0, "oid", metadata !DIExpression(DW_OP_LLVM_fragment, 64, 64))
br label %if.end
if.else: ; preds = %entry
call void @llvm.dbg.value(metadata i32 0, "swap", metadata !DIExpression())
%1 = load ptr, ptr %ent0, align 8
call void @llvm.dbg.value(metadata ptr %1, "oid", metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64))
%2 = load ptr, ptr %ent1, align 8
call void @llvm.dbg.value(metadata ptr %2, "oid", metadata !DIExpression(DW_OP_LLVM_fragment, 64, 64))
%oid.sroa.0.0.sroa.speculate.load.if.else = load i32, ptr %1, align 4
br label %if.end
```
## IR after `EarlyCSE`
```llvm
if.then: ; preds = %entry
call void @llvm.dbg.value(metadata ptr undef, "oid", metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64))
call void @llvm.dbg.value(metadata ptr poison, "oid", metadata !DIExpression(DW_OP_LLVM_fragment, 64, 64))
br label %if.end
if.else: ; preds = %entry
call void @llvm.dbg.value(metadata i32 0, "swap", metadata !DIExpression())
%0 = load ptr, ptr %ent0, align 8
call void @llvm.dbg.value(metadata ptr %0, "oid", metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64))
call void @llvm.dbg.value(metadata ptr poison, "oid", metadata !DIExpression(DW_OP_LLVM_fragment, 64, 64))
%oid.sroa.0.0.sroa.speculate.load.if.else = load i32, ptr %0, align 4
br label %if.end
```
## IR diff before and after `EarlyCSE`
```diff
@@ -1,14 +1,12 @@
if.then: ; preds = %entry
call void @llvm.dbg.value(metadata ptr undef, "oid", metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64))
- %0 = load ptr, ptr %ent0, align 8
- call void @llvm.dbg.value(metadata ptr %0, "oid", metadata !DIExpression(DW_OP_LLVM_fragment, 64, 64))
+ call void @llvm.dbg.value(metadata ptr poison, "oid", metadata !DIExpression(DW_OP_LLVM_fragment, 64, 64))
br label %if.end
if.else: ; preds = %entry
call void @llvm.dbg.value(metadata i32 0, "swap", metadata !DIExpression())
- %1 = load ptr, ptr %ent0, align 8
- call void @llvm.dbg.value(metadata ptr %1, "oid", metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64))
- %2 = load ptr, ptr %ent1, align 8
- call void @llvm.dbg.value(metadata ptr %2, "oid", metadata !DIExpression(DW_OP_LLVM_fragment, 64, 64))
- %oid.sroa.0.0.sroa.speculate.load.if.else = load i32, ptr %1, align 4
+ %0 = load ptr, ptr %ent0, align 8
+ call void @llvm.dbg.value(metadata ptr %0, "oid", metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64))
+ call void @llvm.dbg.value(metadata ptr poison, "oid", metadata !DIExpression(DW_OP_LLVM_fragment, 64, 64))
+ %oid.sroa.0.0.sroa.speculate.load.if.else = load i32, ptr %0, align 4
br label %if.end
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWVtv2zzS_jX0zUCCRMmSfOELO04-FMiHFHmLt3tnUNJIZlciBZJyk_76BSnLh9jNoZssgsUKbSJLM8NnDnxmYjKteS0Q52S6JNPVhPVmI9X8h3pkQk9yWT7Ov20QSBJcM9U8Xv11TZIAOqY1KGzlFjWUmPc1bFnTI3BRSaikgk4qw6XQICswgwHJS6cruTCoSLAiwYIpxR4JvQLcogCzkX29sfIaB4Ma2l4byBHYlvGG5Q2C5qJAK_QIJSq-RaiUbAd7VS8Kuy4wVfctCqN92OH_6_5uscf-Y7BaSWUtcQ2s0RI0YqvBSCiV7EDLFgerT3yz_mjWWoiKW0j-ILb7SSNCI_gblbYBOH21gKuGiZpEC9gOAhCmfuAHQGi2MabTJFoQekPoTc3Nps_9QraE3jTNdvzldUr-wML4NTeQpUUVzRiL4lmeRQyjPC3DpIgCVqQsqyoWsDKYZQWhswOE29vV8hyBNUdoVnND4uBo8Wjxu8UVbrkzUGQ0wCTI4hgxxGkVZHFZpmkSTtMkL4O8jGc0pUl8QHEcqSvZdrxBBdcPXSPVWBoHvGS6vOsMb7lmLrcd77DhAmHL8Sf0mosaHrLES-IhumBUL_5pnWnZIxQbJmoEuUUFhrdoQUxX5-GWZS4b40tVE3rzi9CbTVrm7Lv89fUy7K9K1oq1oGWvCjwRSILhXzF81kb1hQGZ28iteQkkXQ5vALgwwJpakmj3iKSrw_25-rHumV27w160g8Kox9-aAUIX3GD7jB0LGR9Y2zVIaGY_CbuDT83TBQoT_OZ5SOjsGEEhhTbn7hC6IDSzTk2X1OVstodywfs2X58EYIxwZStBPFkSYLAbkOkKSLQCQpMnBg5C4ZGQdcsj0bUNkv19qkHSFWCj8XQpGyP9k3XORnBhAfvy1WvsUYEH54rhs-DGW4WmV-IoBlb6rA5Pq_nCHlg56nfEaPfixU0wKsRQuM3pVUJ6JdcFU6XnmNUTrEU9vODC7WyvBu8uBK8AT47F5t2FvjxYc3RU_mSqKvu2A0-Mchfkg4fAXRG1vLf6vv62-L-17vNu2MO7qKy-rxff1o38ue4KcBeh2ah6uPZ0sFPY8HozalxQCKcHhZNr0K4Ua3GdM1szNFt9X999XSusE7hffn1WsWBNs7b_7Y3e4zWqx6cIbXxHZUIzQul-_9Jn1yixaNYuIYRmYfSsbKekkeaxw_ICjgvyVvQ4XiwFQikX5iVQ-GBQCdZccvhyYUhePlMU6XFRjC39SUkUQ-d5mmHbPS7gtGLT5VkhhJYOz566qA4AhtQHcL_4hxUdnnQcC4TgIXs5q3Y7vzqjTimMn1p1aYGz8q9cdgai3lOuJeiRmg_LXiSM2zGEdoA6DINcQ8u16-D2RSut-WFiHEc5GwkmSvdsnwizYQb4brjqFGoUBqRoHqGwjV5Dx9TekhsyL81oX-7HGfB0vr3IY24KGhpg5ZsNCps0Ei2hU1jqHQNPXZvb9zXWNLC11Udip--Xee07zrPDCRpWMsOgMwp6UWJlXT1K4xXsRQgNV1-uH6yn2sVkxxS3t3__v6WQ2s66rrzsj2HSOpQBodPAAWwkK-1yVsiuOgB2OqzhtYDsD6Bb6--A3II-h54raFiOjV2FVz6K8mQUqXzbbW0mXn29S8p4RGF02vXgF70-y0j4oRkJP7CW6DPIw38bOf2oWiJ0KnnpayWZ_XtnuNEdFn3DDPrWH39XUAcHeUSPHDzyLn6xQp-Zm77cA6sMqv9y3nkDjk5yPXD9_2jkTTTy-Yn9c5fGO7BC8H6sUPKqGmcSO_S8miWs4u5RHJA4AM9yVRgDoUt3R2F4sQP4ai75JGTi_UGxe59ljCF0-Ykq_iU2hPenw_8MH3pvH6veXCIfNFd5fzBYvRn7R01W3seMVnbXvHnPv3WrfVyPs0g-y57fhfIDGt2LfW5SzqNyFs3YBOdhkqZZMgvT2WQzZ0mFJU5TzEqasJDlMWVJkOO0mCVBXAUTPqcBjYIoiMIsTsKZH-ZpmFRBWiXFLCvykMQBtow3vousVPWEa93jPAnDZDZxsLQ716LUnVFxUckhrIRSN1ZHC-kOFn65bxW0fTldTdTcfYWU97W2aePa6MMShpsG52M7didF4xHY0eGXO-Iaj7CGU6rSHVMdDqYmvWrmbzvyIfTGeagJvXFO_isAAP__bWsA9w">