Considering the following c++ code:
enum class TestEnum ... #define CHECK_GDB_TEST(s) ... __attribute__((noinline)) uint64_t TestBasicTypeNormal(uint8_t a, int8_t b, uint16_t c, int16_t d, uint32_t e, int32_t f, uint64_t g, int64_t h, char i, const char *j, const char k[], float l, double m, TestEnum n) { CHECK_GDB_TEST("coro_variable_test"); uint64_t sum = a + b + c + d + e + f + g + h; double sum_f = l + m; CHECK_GDB_TEST("coro_variable_test"); printf("%lu %lf %f %lf %c %s %s %s\n", sum, sum_f, l, m, i, j, k, n == TestEnum::TYPE_A ? "TYPE_A" : "TYPE_B"); return sum; }
When we use gdb or lldb to debug this elf, we get the following ouput:
Breakpoint 1, TestBasicTypeNormal (a=<optimized out>, a@entry=1 '\001', b=b@entry=10 '\n', c=c@entry=100, d=d@entry=1000, e=e@entry=10000, f=-854629579, f@entry=100000, g=100000000000, h=1000000000000, i=99 'c', j=0x4009b2 "hello", k=0x4009b8 "world", l=<optimized out>, m=0.87654321000000002, n=TestEnum::TYPE_B) 22 printf("%lu %lf %f %lf %c %s %s %s\n", sum, sum_f, l, m, i, j, k, n == TestEnum::TYPE_A ? "TYPE_A" : "TYPE_B"); (gdb)
We can find the variable l become -854629579. It is wried, because we did not change the value of l.
And after downloading the dwarf info:
0x00001e3a: DW_TAG_formal_parameter DW_AT_location (0x0000015e: [0x0000000000400740, 0x000000000040077c): DW_OP_reg9 R9 [0x000000000040077c, 0x000000000040082e): DW_OP_breg7 RSP+8) DW_AT_name ("f") DW_AT_decl_line (16) DW_AT_type (0x00001254 "int32_t")
It shows f should be in [rsp + 8] between 0x000000000040077c and 0x000000000040082e.
But it is not right after checking the assembly code:
40075a: 44 89 4c 24 08 mov %r9d,0x8(%rsp) ----> r9d is l, and it save to the rsp+8 .... 4007bc: f2 0f 11 44 24 08 movsd %xmm0,0x8(%rsp) ----> save xmm0 to the rsp+8 without notify the dwarf
So the problem is clear, llvm failed to calculate dwarf interval for spill location.
I use this patch to fix the problems, but I do not know whether it is right.
@jmorse In addition, when regalloc tries to spill vreg to stack. llvm forget to mark kill flags for copy instruction. I think it might be useful for dwarf construction. What's your opinions?