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

    <tr>
        <th>Summary</th>
        <td>
            SROA affects DWARF ranges causing variable not available when debugging
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

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

<pre>
    In this minimized C example, the pointer variable `l_47`, assigned at line 6 in the inner scope {} inside the main function, is marked as not available at line 9 and becomes available with its correct value at line 10.

Apparently this behavior is caused by SROA. By debugging and analyzing the DWARF with opt-bisect-limit, after SROA there is no longer a DW_AT_location for the variable and the value goes away.

SimplifyCFG eventually adds the location, but only for addresses associated with line 10. Looking at the assembly, line 9 ends up being associated with the `&a` operation done both at line 6 and line 9 in the source program. Perhaps, line 9 could go with the next assembly instruction or even the movdqa operations that assign `b[e]`? 

The issue happens when the optimization level is Os. With Og/O1/O2/O3 the variable is optimized out.

We tested clang and lldb 14.0.0 commit 116dc70 on x64.
```
$ cat a.c
int a,  c,  d;
int *b[4];
int main() 
  {
  int f; {
    int *l_47 = &a;
    int e = 0;
    for (; e < 4; e++)
      b[e] = &a;
    f =  c;
  }
  d = f; }
```
LLDB trace:
```
$ clang -Os -g a.c -o opt
$ lldb opt
(lldb) target create "opt"
Current executable set to '/tmp/opt' (x86_64).
(lldb) b main
Breakpoint 1: where = opt`main at a.c:9:12, address = 0x0000000000401108
(lldb) r
Process 26700 launched: '/tmp/opt' (x86_64)
Process 26700 stopped
* thread #1, name = 'opt', stop reason = breakpoint 1.1
    frame #0: 0x0000000000401108 opt`main at a.c:9:12
   6        int *l_47 = &a;
   7        int e = 0;
   8        for (; e < 4; e++)
-> 9          b[e] = &a;
   10       f =  c;
   11     }
   12     d = f; }
(lldb) frame var
(int) f = <variable not available>

(int) e = 0
(int *) l_47 = <variable not available>

(lldb) n
Process 26700 stopped
* thread #1, name = 'opt', stop reason = step over
    frame #0: 0x0000000000401127 opt`main at a.c:10:10
   7        int e = 0;
   8        for (; e < 4; e++)
   9          b[e] = &a;
-> 10       f =  c;
   11     }
   12     d = f; }
(lldb) frame var
(int) f = <variable not available>

(int) e = 0
(int *) l_47 = 0x0000000000404040
```
ASM at -Os:
```
0000000000401108 <main>:
  401108:       b8 40 40 40 00          mov    $0x404040,%eax
  40110d:       66 48 0f 6e c0          movq   %rax,%xmm0
  401112:       66 0f 70 c0 44          pshufd $0x44,%xmm0,%xmm0
  401117:       66 0f 7f 05 31 2f 00    movdqa %xmm0,0x2f31(%rip)        # 404050 <b>
  40111e:       00 
  40111f:       66 0f 7f 05 39 2f 00    movdqa %xmm0,0x2f39(%rip)        # 404060 <b+0x10>
  401126:       00 
  401127:       8b 05 43 2f 00 00       mov    0x2f43(%rip),%eax        # 404070 <c>
  40112d:       89 05 41 2f 00 00       mov    %eax,0x2f41(%rip)        # 404074 <d>
  401133:       31 c0                   xor    %eax,%eax
  401135:       c3                      ret
```

DWARF info at -Os:
```
0x000000de:       DW_TAG_variable
                    DW_AT_location      (0x00000000: 
                       [0x000000000040110d, 0x000000000040112d): DW_OP_reg0 RAX)
                    DW_AT_name  ("l_47")
                    DW_AT_decl_file     ("/tmp/a.c")
                    DW_AT_decl_line     (6)
                    DW_AT_type  (0x00000091 "int *")
```
The location range for `l_47` does not include the instruction at `401108`, which in the line number table is associated with line 9, while line 10 goes with the instruction at `401127`. In turn, `401108` reads the address of variable a, which is used both to assign `l_47` at line 6 and then `b[e]` at line 9. Perhaps line 6 should go with `401108` and line 9 with a later one?

DWARF before SROA at -Os:
```
0x000000d1:       DW_TAG_variable
                    DW_AT_location      (DW_OP_fbreg -8)
                    DW_AT_name  ("l_47")
                    DW_AT_decl_file     ("/tmp/a.c")
                    DW_AT_decl_line     (6)
                    DW_AT_type  (0x00000091 "int *")
```

DWARF after SROA at -Os:
```
0x000000e1:       DW_TAG_variable
                    DW_AT_name  ("l_47")
                    DW_AT_decl_file     ("/tmp/a.c")
                    DW_AT_decl_line     (6)
                    DW_AT_type  (0x00000091 "int *")
```                

SimplifyCFG eventually adds range information.

DWARF info at -Os before SimplifyCFG:
```
0x000000e1:       DW_TAG_variable
                    DW_AT_name  ("l_47")
                    DW_AT_decl_file     ("/tmp/a.c")
                    DW_AT_decl_line     (6)
                    DW_AT_type  (0x00000091 "int *")
```

After SimplifyCFG, the DWARF is identical to the one reported above for -Os.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztWUtz2zYQ_jX0BWMOX6LEgw6SVWc6k44ziWfSmwckQYkNRTAAaEv99d0FwJck25q2ubRRZEoCsLvfPoFFUp4fl7_WRO1KSfZlXe7LP1lO7gg70H1TMSe4gzlGGl7WignyTEVJ04oRJ_aqp2gOH7iESlluayCkilRlzUhMyloTlnUNZDLjDdDM1858A0OyzJme3VNYVrR1pkpeIyNEQcU35CRJzRWhz7SstMSOdUJonZOUZXzP5Gj-pVQ7UipJMi4EyxRgrdqBzPdcx9s43so8V01DBatVdTS6p2xHn0suEEFGWwkI0iP58vlh5ZL1keQsbbfbst5q4bSm1fFP_IVKbL6uPt8b8bxRt2kpQfptBaZU2jYFGg454WrBUELNScXrLYxTIH9aPT5VPKNoBFIABuTaWxoFmgFUZ8tR6Rd6nGjzpQRnlcXx7v4DYc-gVksr0IzmudS0HXfEk7aK8BpmURKsEExK5Cklz0qqQHGtSmc08pHzb1pxpVnBOrZPqyOysv5gNYhpG7ChXnfCCIl0mMQUPsBETBhNcw7UKYclQ9SgsparDSDJW5FBAAq-FXTvkk9M7GgjR-Iz3lY5GGYQV7OD6oFivCnR6hAjoDLaxwQff86_0wEQmooqG8sIOXVma-bMNog-vCdjgz9iaEsJDgEwDQPal51lCzGAWWR0rEBahR5_kC75ivgetk5w_-DjI8BHOPU2LLUMwH68VRM3f4WsYRItm1XUxmJV5SnxI9dzPbDEHoKO-H6cZ3MwdU0OcdRxACXM2_wMIohz0NbNzADkN6FoVZLpZ-6E62HGCVZojQitMR7HBHaChRMk1jxEZ7n9iisKWD8eM6PAD8sHccIN0ZERnixgesqbjGPAojBgiNN3JNJfnWCt38mwkpDOd5clFHoYNB0GoTJ1X3M9a4FvLprv48fNmihBM-aEq9cNrL10-yDJ7RYtTW45endYoJ03GlngABpTUbFlimSCQSIB_gAXBYFZd9cKLF1Qo1nWKh02EhYrDgvnEFNq38BTU8zRYIdF_BRHwNY9k5MaD-rhNQj7pgs98UErjGhh3ICsYk8Xaxsy4SqBPz_QBc7UEOOwg9e_Is_3vcWZSGFGPgmeIVUQzz2PVBQ2gR3LUe47Slwil4pDFuadLKy0oAz4MQh9hFjTPbORMDcscRSpCKyTkCg4mY4M4PqjaBGaPAg9hHeu4lv26ZjExL7ei_75eOGFLFh089dlw60T_gI1sn-9mRe-1_E-zw-oKnpqlCfED_TQxXwZHG7MBxWunwHV9IQBEd711W-y4wPycfEb6DqrjIbRpDg1mPV6rh3O-sdFFtTshvBnJq4NKoj5S0Hle-bxg4IFFl4VKjqo_kPBMrU-_rtY0ldffkNXQD1_reifVQbAqwssoOtICLGFMVx1hl7AkH173uAAOKBoIwaRd7CwgjsnmDF6mLDKB1ZxTKIF8QoSM5JNWX3XrGYCiDWXw37vjdlAsRqzAR5whAAeUTSwaeSuLXKLKBrxucxxfsaxIN6MhD4JCqupPYQNfLxDUGBqLRBr2aCf7AtyhaARZh6aNe09boWxQRiwnkwVr-BI3sORvIUjtjiCtXfAxJzACeJX4QQjsyxSBBKFFkjvfet6BBGFYxB9BJyimWs02SmMUWwsEi3Lf0WWDSyjefSmB-YRyspPZIXhIAtcPA6__nWAOjSWdR7N4WzgkoUXWMBLMHUx_czT9GNlXfD3stWmfT4KHejGHlcfnroiMz5STl8nbZu1z2IoJfoo8yo5rp6tz84SOe4eZ5tBjo4HdiDz4dOTYFuPfF79fnLivQRP70668AeBbtfhCPk-Vc6y6qkoocRapTSZPZHhRnQ9F92iWS7xFUTq2LCJHRMfT7990R4En_jycdTlEgHHbmb2vP6aAtpNZq4UyjqrWnsBMe4NIVhgnS3O5l7jZVdmu64T1brU7T6Ftl11zdrFtjmxtBXr2mjTt_cN6mWxAeJ0CV7HtEL36mM8eJ6w7Xx34ubF6JpghBe6cX2Bgb01dAVDR9vZYtpwK2xdp_3ucNvSd9wdhdxN-u0JxFH7ricpHOzx9gM6feigz5M0ZeAkZi5HrsxV_9_LVZNOBRz7oUlb_EynVyrp6ALrOh-xv--j_4OFTxlde5Fnqhrua2KvA9k999Vo1-uTa2D503H_yHGT-2OTFCPb2pty6wdJyhzcV2a0whKsLwYBoGANF7hZ0BTaQb1Fgavcm3wZ5kmY0BtVqootTbIVBcuUtBy1983dNN6yXu6CzC1kf1l904pquVOq0Skb3MN7C2W5Td2M7-FHVT13H7eN4H-AOPip7zUlfJlF8yS-2S0jn6Xpwp8XfpokUbygs5nnLRIWFWxesITdgGxWySVsH2C3mr2Yq1G04WxzUy4DLwjw1OiHXuxHbpB4_owxmi6iMGWZ70QegyapchGHy8X2Riw1JNBCwmRVSiWHSft_DUyLA_60VTsulpmAZSWtYZrCh2I3GsRSK_EXopebSA">