Index: llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp =================================================================== --- llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp +++ llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp @@ -410,6 +410,9 @@ if (!Info.UsingBlocks.empty()) return false; // If not, we'll have to fall back for the remainder. + // Try to preserve debug information attached to the dead instruction. + salvageDebugInfo(*AI); + // Record debuginfo for the store and remove the declaration's // debuginfo. for (DbgVariableIntrinsic *DII : Info.DbgDeclares) { @@ -506,6 +509,9 @@ LBI.deleteValue(LI); } + // Try to preserve debug information attached to the dead instruction. + salvageDebugInfo(*AI); + // Remove the (now dead) stores and alloca. while (!AI->use_empty()) { StoreInst *SI = cast(AI->user_back()); Index: llvm/test/DebugInfo/dwarfdump-implicit_pointer_mem2reg.c =================================================================== --- /dev/null +++ llvm/test/DebugInfo/dwarfdump-implicit_pointer_mem2reg.c @@ -0,0 +1,67 @@ +// RUN: clang %s -O2 -gdwarf-5 -o %t.o +// RUN: llvm-dwarfdump %t.o | FileCheck %s + +// CHECK-LABEL: DW_AT_name ("arr1") + +// 1. Test if more than one member location list is printed +// (for pointer to scalar) +// CHECK-LABEL: DW_AT_location ( +// CHECK-NEXT: : DW_OP_lit0, DW_OP_stack_value +// CHECK-NEXT: : DW_OP_implicit_pointer {{0x.+}} +0 +// CHECK-NEXT: DW_AT_name ("ptr2") + +// 2. Test if More than one member location list is printed +// (for pointer to pointer to scalar) +// CHECK-LABEL: DW_AT_location ( +// CHECK-NEXT: : DW_OP_lit0, DW_OP_stack_value +// CHECK-NEXT: : DW_OP_implicit_pointer {{0x.+}} +0 +// CHECK-NEXT: DW_AT_name ("ptrptr2") + +// 3. Test if one member location list is printed +// (for pointer to pointer to array) +// CHECK-LABEL: DW_AT_location ( +// CHECK-NEXT: : DW_OP_implicit_pointer {{0x.+}} +0 +// CHECK-NEXT: DW_AT_name ("ptrptr3") +// +// 4. Test if one member location list is printed +// (for pointer to pointer to scalar) +// CHECK-LABEL: DW_AT_location ( +// CHECK-NEXT: : DW_OP_implicit_pointer {{0x.+}} +0 +// CHECK-NEXT: DW_AT_name ("ptrptr1") + +// 5. Test if one member location list is printed +// (for pointer to array) +// CHECK-LABEL: DW_AT_location ( +// CHECK-NEXT: : DW_OP_implicit_pointer {{0x.+}} +0 +// CHECK-NEXT: DW_AT_name ("ptr3") + +// 6. Test if one member location list is printed +// (for pointer to scalar) +// CHECK-LABEL: DW_AT_location ( +// CHECK-NEXT: : DW_OP_implicit_pointer {{0x.+}} +0 +// CHECK-NEXT: DW_AT_name ("ptr1") + +static const char *b = "opq"; +volatile int v; +int main() { + int var1 = 4; + int var2 = 5; + int arr1[2] = {2, 3}; + int *ptr1; + int *ptr2 = 0; + int *ptr3; + int **ptrptr1; + int **ptrptr2 = 0; + int **ptrptr3; + + v++; + ptr1 = &var1; + ptr2 = &var2; + ptr3 = arr1; + ptrptr1 = &ptr1; + ptrptr2 = &ptr2; + ptrptr3 = &ptr3; + v++; + + return arr1[0] + arr1[1] + *ptr1 + *ptr2 + **ptrptr1 + **ptrptr2 - 5; +} Index: llvm/test/DebugInfo/implicit_pointer_mem2reg.c =================================================================== --- /dev/null +++ llvm/test/DebugInfo/implicit_pointer_mem2reg.c @@ -0,0 +1,34 @@ +// RUN: clang %s -O2 -gdwarf-5 -S -emit-llvm -o %t.ll +// RUN: FileCheck %s --input-file=%t.ll + +// CHECK: !DIExpression(DW_OP_LLVM_implicit_pointer, DW_OP_LLVM_arg0, 0) +// CHECK: !DIExpression(DW_OP_LLVM_implicit_pointer, DW_OP_LLVM_arg0, 0) +// CHECK: !DIExpression(DW_OP_LLVM_implicit_pointer, DW_OP_LLVM_arg0, 0) +// CHECK: !DIExpression(DW_OP_LLVM_implicit_pointer, DW_OP_LLVM_arg0, 0) +// CHECK: !DIExpression(DW_OP_LLVM_implicit_pointer, DW_OP_LLVM_arg0, 0) +// CHECK: !DIExpression(DW_OP_LLVM_implicit_pointer, DW_OP_LLVM_arg0, 0) + +static const char *b = "opq"; +volatile int v; +int main() { + int var1 = 4; + int var2 = 5; + int arr1[2] = {2, 3}; + int *ptr1; + int *ptr2 = 0; + int *ptr3; + int **ptrptr1; + int **ptrptr2 = 0; + int **ptrptr3; + + v++; + ptr1 = &var1; + ptr2 = &var2; + ptr3 = arr1; + ptrptr1 = &ptr1; + ptrptr2 = &ptr2; + ptrptr3 = &ptr3; + v++; + + return arr1[0] + arr1[1] + *ptr1 + *ptr2 + **ptrptr1 + **ptrptr2 - 5; +}