<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/61266>61266</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            InstCombine drops debug value after simplifying to boolean
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            debuginfo,
            llvm:instcombine
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          jryans
      </td>
    </tr>
</table>

<pre>
    The `InstCombine` pass simplifies `health_started` to a boolean value, but in
doing so, it loses the debug value info for `health_started` at the point of the
`cleanup` label.

## Versions

* Clang: version 17.0.0 (https://github.com/llvm/llvm-project.git 7de0804ea3290e5e43ce38567b4056a34ccad551)
* 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/3q1417xj6)

## Program source

```c
extern int result;
extern int bob(void);

int d() {
  int health_started = 0;
  if (bob())
    goto cleanup;
 health_started = 1;
cleanup:
  if (health_started)
    return ++result;
  return 0;
}
```

## Debug info view

```
$ clang -fno-discard-value-names -fno-inline -g -O1 -c -o example-O1.o
$ llvm-dwarfdump -n health_started example-O1.o
0x0000004b: DW_TAG_variable
              DW_AT_location (0x00000000:
                 [0x0000000000000004, 0x000000000000000f): DW_OP_consts +0, DW_OP_stack_value)
              DW_AT_name ("health_started")
              DW_AT_decl_line   (5)
 DW_AT_type        (0x00000082 "int")
$ llvm-dwarfdump --debug-line example-O1.o
Address            Line   Column File   ISA Discriminator Flags
------------------ ------ ------ ------ --- ------------- -------------
0x0000000000000000      4      0      1   0             0 is_stmt
0x0000000000000004      6      7      1   0             0  is_stmt prologue_end
0x000000000000000f     10      7      1   0             0 is_stmt
0x0000000000000011     13      1      1   0             0 is_stmt
0x0000000000000013     11     12      1   0             0 is_stmt
0x0000000000000021     13      1      1   0             0 is_stmt
0x0000000000000023     13      1      1   0             0  is_stmt end_sequence
```

The variable `health_started` has the location range `[0x04, 0x0f)`. The
conditional `if (health_started)` is on source line 10 / address `0x0f`. The
value should remain visible at least for the conditional (where it is used), but
currently it stops just before that.

## IR before `InstCombine`

```llvm
define dso_local i32 @d() local_unnamed_addr {
entry:
  call void @llvm.dbg.value(metadata i32 0, "health_started", metadata !DIExpression())
  %call = call i32 @bob()
  %tobool = icmp ne i32 %call, 0
  br i1 %tobool, label %cleanup, label %if.end

if.end: ; preds = %entry
  call void @llvm.dbg.value(metadata i32 1, "health_started", metadata !DIExpression())
  br label %cleanup

cleanup: ; preds = %entry, %if.end
  %health_started.0 = phi i32 [ 0, %entry ], [ 1, %if.end ]
  call void @llvm.dbg.value(metadata i32 %health_started.0, "health_started", metadata !DIExpression())
  call void @llvm.dbg.label(metadata !16)
  %tobool1 = icmp ne i32 %health_started.0, 0
  br i1 %tobool1, label %if.then2, label %if.end3

if.then2:                                         ; preds = %cleanup
  %0 = load i32, ptr @result, align 4
  %inc = add nsw i32 %0, 1
  store i32 %inc, ptr @result, align 4
  br label %cleanup4

if.end3:                                          ; preds = %cleanup
  br label %cleanup4

cleanup4: ; preds = %if.end3, %if.then2
  %retval.0 = phi i32 [ %inc, %if.then2 ], [ 0, %if.end3 ]
  ret i32 %retval.0
}
```

## IR after `InstCombine`

```llvm
define dso_local i32 @d() local_unnamed_addr {
entry:
  call void @llvm.dbg.value(metadata i32 0, "health_started", metadata !DIExpression())
  %call = call i32 @bob()
  %tobool.not.not = icmp eq i32 %call, 0
  br i1 %tobool.not.not, label %if.end, label %cleanup

if.end: ; preds = %entry
  call void @llvm.dbg.value(metadata i32 1, "health_started", metadata !DIExpression())
  br label %cleanup

cleanup: ; preds = %entry, %if.end
  call void @llvm.dbg.value(metadata i32 poison, "health_started", metadata !DIExpression())
  call void @llvm.dbg.label(metadata !16)
  br i1 %tobool.not.not, label %if.then2, label %if.end3

if.then2: ; preds = %cleanup
  %0 = load i32, ptr @result, align 4
  %inc = add nsw i32 %0, 1
  store i32 %inc, ptr @result, align 4
  br label %cleanup4

if.end3: ; preds = %cleanup
  br label %cleanup4

cleanup4:                                         ; preds = %if.end3, %if.then2
  %retval.0 = phi i32 [ %inc, %if.then2 ], [ 0, %if.end3 ]
  ret i32 %retval.0
}
```

## IR diff before and after `InstCombine`

```diff
@@ -2,19 +2,17 @@
 entry:
   call void @llvm.dbg.value(metadata i32 0, "health_started", metadata !DIExpression())
   %call = call i32 @bob()
-  %tobool = icmp ne i32 %call, 0
-  br i1 %tobool, label %cleanup, label %if.end
+ %tobool.not.not = icmp eq i32 %call, 0
+  br i1 %tobool.not.not, label %if.end, label %cleanup

 if.end: ; preds = %entry
   call void @llvm.dbg.value(metadata i32 1, "health_started", metadata !DIExpression())
   br label %cleanup

 cleanup:                                          ; preds = %entry, %if.end
-  %health_started.0 = phi i32 [ 0, %entry ], [ 1, %if.end ]
- call void @llvm.dbg.value(metadata i32 %health_started.0, "health_started", metadata !DIExpression())
+  call void @llvm.dbg.value(metadata i32 poison, "health_started", metadata !DIExpression())
   call void @llvm.dbg.label(metadata !16)
-  %tobool1 = icmp ne i32 %health_started.0, 0
-  br i1 %tobool1, label %if.then2, label %if.end3
+  br i1 %tobool.not.not, label %if.then2, label %if.end3

 if.then2: ; preds = %cleanup
   %0 = load i32, ptr @result, align 4
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWVtv2zgW_jXMy4EMibpYfvCDHY8XBQp0MFvsPBqUSMnsyKRKUmmyv35BUrJ8kds4k51iL0IbW-S5fjw3WURrXgvGlihdo3TzQDqzl2r5Rb0QoR8KSV-Wn_cMUBZ-ENo8ykPBBUNZCC3RGjQ_tA2vONOWYs9IY_Y7bYgyjFoiI4FAIWXDiIAn0nQM4UcoOgNcoHCDwhWVXNSgpV3nBhqpmQazZ0BZ0dWeB7ioJFRSTSshxjG0kgsDsrI3XjbKwtJq7lpL1pCCNbN-x__FMcIx_IMpzaXQ51sreGyIqFG8gidPANF8Fs5CQDjfG9NqFK8Q3iK8rbnZd8WslAeEt03zNHwErZJfWGlmNTcwpyzMw4SRGC9ClrIkLlmcp9m8SMI0I3FSloSmaYTwYjTh48fN-toCKw7hvOYGJeGJ8nh1S7liT9wJKHMcsizMk4SxiKVVmCeUzudZlM6zgoYFTRZ4jrNktOIUqUd5aHnDFPzy3DZSMXUJGUrXn1rDD1wTY9W1vGUNFwyeOPsGnbZn_ZxnQZZ4dMGoTvxhnTmQFyj3RNQM5BNTYPiBWSPSzTXckhayMTOpaoS3_0R4G3-Nkmj-_CWbNvtXJWtFDqBlp0p2RpCF_l_p79mzYUqADSTFdNcYFK-vdgpZIJw_SU6tuoHA_7X7FOEc4QWgeb8Fju08cAHFGwiP3AC8sjB42Vbu4AkAQC2NhCGUjywTAqPj7pF6da7gIn1OtShmOiUA4TXC6wv3j7ujyWi-uQBxAvqNy2KXvzYEJrEfGBIoXUwElZAB5bokigauAASCHJj2G1y4gApqCD5FEJQQSGDP5NA2LPgUzeQozWUB_UZURbtDC4G4ROyaLXwO3ZUUNus2v-8-r_62eyKKk6JhI1Ljtfl9t_q8a2Tp4x3hfBARhifYX1woXY9k_ZXYCni1WrkQc6Z8-nVXSqGNticUWmq_qA0p_9j1xXVx20iLIbjgwpdBgL_LSFnZ7BzoYPnTkdjvm5eWHT0bAcgxIIy5MKfyp84lcKU-cBquj2RFqWJan5r10dvyKJvuIGDLG3v34e8r2HBdKn7gghipYNuQui_qwdUFtz5giqy_zoNkvLxZif_o76LxKwwbXO-0OZgbYnr-zH_Mb4sZ5ECrZCPrju2YoDeEVl5K-EOh37UtijxfPPK_SYznH6ThN4rB72MNjl8r5gg4E3Sn2deOiZJ9p_jZiWmoGtMzy574KedYOZRrfVaOqw1DNXD5n4Uz-DwMNaUUlFsW0ljyW1U9s86DFH3TA5ddkR1etkD6lEJZ6FScyfcTl97LrqGg2IFwAXZ4sK4QAw0j2rhZzJp_ZgzOv-2ZYnaM4xo67Q3x815ve6cUE6Z5sTTayFbDl04bKFglFQOzJ2ZqQPvw20BxNYZONhQ3BfnpklXWb6qlq9EN8BgDSsKhRbvFXSdsbaQ7i8vYtZkw6uWkhpekacB2fSvAqpjRop71dTc_MEMoMcRpcNV5us4-wpES4Wjz4Zfn1p4Fl-Kq7yOcOp22sbsvvfHjjDASGmmnbEfKy0MLgnlqL8IF00BdKODRyGP33GjsiPup4XSNV7NjeemHHL8SrwDFa2gVo9ppRjj1oN2PWPQuiBXq2pUTu8eZ6Jbhzogzjx2651bZR4B4A-2ee4zT9XDgXgq4ofXRbURnIt3O_eBMWPAucE2b4BA8NQHhKMqmwi2aircpS2_FXnQZaGbPBJ6Ivvgi_DxdfD1Z3bquzvssPJxP_lQbSah1xRrRGmWR6Udh_Aik4bWA5ISJi9KxEUpB6G8DCM7raKDTxtaufouL8jWyJ0I5uc7B-B4MfgjCj3Qe16YSaDDoGO_-jEaoFDNPpJlInhGUE8bTJArPkig-zSLFzADsIP-Op5MPvwGpDFP_7yvf7yszIY39P-Y7-_ra_jLwTvWUqdbzP9tn7vCilVxbs35eD3jlId9dz_-b6_R7lt83l_z_0DJNeVUNDwFE0LvKtuXtl5IQJSEENmqiBSC8dt_m4Dd6ay8L9F9foV9booP7Zv_gTw7_eP2mlmD53rErwGvbwl_fF37UGOCkM7w9hW-1kODf9KwS_PxnFRdCP6dBvq1DBn_iMek6Te9-Troj417VouGeHv2WJn0s1g90GdNFvCAPbBll8xwvskWcPeyXeZLQPF8QRjMyxzReJPMixPOU5FG0WMT5A1_iEMdhHObRPE7jbJaTPCoWC8qqbF7laYKSkB0Ib2buEKWqH7jWHVtmEc6yB-e-dq9BMXa_SHNRSR8tCGM3-8crLrQp-3aDMUo3D2rpfs8uulrb-ODa6FGB4aZhy5MeBVTJVp-93PStrH-T-sJFDUYO70wfOtUs73vZiPDWuaUR3jrP_hUAAP__BIVpnA">