Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -775,6 +775,28 @@ bool Deref = MI->getOperand(0).isReg() && MI->getOperand(1).isImm(); int64_t Offset = Deref ? MI->getOperand(1).getImm() : 0; + for (unsigned i = 0; i < Expr->getNumElements(); ++i) { + if (Deref) { + // We currently don't support extra Offsets or derefs after the first + // one. Bail out early instead of emitting an incorrect comment + OS << " [complex expression]"; + AP.OutStreamer->emitRawComment(OS.str()); + return true; + } + uint64_t Op = Expr->getElement(i); + if (Op == dwarf::DW_OP_deref) { + Deref = true; + continue; + } + uint64_t ExtraOffset = Expr->getElement(i++); + if (Op == dwarf::DW_OP_plus) + Offset += ExtraOffset; + else { + assert(Op == dwarf::DW_OP_minus); + Offset -= ExtraOffset; + } + } + // Register or immediate value. Register 0 means undef. if (MI->getOperand(0).isFPImm()) { APFloat APF = APFloat(MI->getOperand(0).getFPImm()->getValueAPF()); Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -951,7 +951,7 @@ "Expected inlined-at fields to agree"); uint64_t Offset = DI->getOffset(); // A dbg.value for an alloca is always indirect. - bool IsIndirect = isa<AllocaInst>(V) || Offset != 0; + bool IsIndirect = Offset != 0; SDDbgValue *SDV; if (Val.getNode()) { if (!EmitFuncArgumentDbgValue(V, Variable, Expr, dl, Offset, IsIndirect, @@ -4528,12 +4528,10 @@ // Check unused arguments map. N = UnusedArgNodeMap[V]; if (N.getNode()) { - // A dbg.value for an alloca is always indirect. - bool IsIndirect = isa<AllocaInst>(V) || Offset != 0; if (!EmitFuncArgumentDbgValue(V, Variable, Expression, dl, Offset, - IsIndirect, N)) { + false, N)) { SDV = DAG.getDbgValue(Variable, Expression, N.getNode(), N.getResNo(), - IsIndirect, Offset, dl, SDNodeOrder); + false, Offset, dl, SDNodeOrder); DAG.AddDbgValue(SDV, N.getNode(), false); } } else if (!V->use_empty() ) { Index: lib/Transforms/Utils/Local.cpp =================================================================== --- lib/Transforms/Utils/Local.cpp +++ lib/Transforms/Utils/Local.cpp @@ -1071,8 +1071,14 @@ if (LdStHasDebugValue(DIVar, LI)) return true; - Builder.insertDbgValueIntrinsic(LI->getOperand(0), 0, DIVar, DIExpr, - DDI->getDebugLoc(), LI); + // We are now tracking the loaded value instead of the address. In the + // future if multi-location support is added to the IR, it might be + // preferable to keep tracking both the loaded value and the original + // address in case the alloca can not be elided. + Instruction *DbgValue = + Builder.insertDbgValueIntrinsic(LI, 0, DIVar, DIExpr, + DDI->getDebugLoc(), (Instruction*) nullptr); + DbgValue->insertAfter(LI); return true; } @@ -1114,9 +1120,14 @@ // This is a call by-value or some other instruction that // takes a pointer to the variable. Insert a *value* // intrinsic that describes the alloca. + SmallVector<uint64_t, 1> NewDIExpr; + auto *DIExpr = DDI->getExpression(); + NewDIExpr.push_back(dwarf::DW_OP_deref); + if (DIExpr) + NewDIExpr.append(DIExpr->elements_begin(), DIExpr->elements_end()); DIB.insertDbgValueIntrinsic(AI, 0, DDI->getVariable(), - DDI->getExpression(), DDI->getDebugLoc(), - CI); + DIB.createExpression(NewDIExpr), + DDI->getDebugLoc(), CI); } DDI->eraseFromParent(); } Index: test/CodeGen/ARM/debug-info-blocks.ll =================================================================== --- test/CodeGen/ARM/debug-info-blocks.ll +++ test/CodeGen/ARM/debug-info-blocks.ll @@ -1,5 +1,5 @@ ; RUN: llc -O0 < %s | FileCheck %s -; CHECK: @DEBUG_VALUE: foobar_func_block_invoke_0:mydata <- [%SP+{{[0-9]+}}] +; CHECK: @DEBUG_VALUE: foobar_func_block_invoke_0:mydata <- [complex expression] ; Radar 9331779 target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32" target triple = "thumbv7-apple-ios" Index: test/DebugInfo/AArch64/coalescing.ll =================================================================== --- test/DebugInfo/AArch64/coalescing.ll +++ test/DebugInfo/AArch64/coalescing.ll @@ -60,6 +60,6 @@ !13 = !{i32 2, !"Debug Info Version", i32 3} !14 = !{!"clang version 3.6.0 (trunk 223149) (llvm/trunk 223115)"} !15 = !DILocation(line: 5, column: 3, scope: !4) -!16 = !DIExpression() +!16 = !DIExpression(DW_OP_deref) !17 = !DILocation(line: 4, column: 12, scope: !4) !18 = !DILocation(line: 8, column: 1, scope: !4) Index: test/DebugInfo/Mips/dsr-fixed-objects.ll =================================================================== --- test/DebugInfo/Mips/dsr-fixed-objects.ll +++ test/DebugInfo/Mips/dsr-fixed-objects.ll @@ -55,11 +55,11 @@ } -; F1: DW_AT_location [DW_FORM_sec_offset] (0x00000033) +; F1: DW_AT_location [DW_FORM_sec_offset] (0x00000032) ; F1: DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000006b] = "x") ; x -> DW_OP_reg1(51) -; F1: 0x00000033: Beginning address offset: 0x0000000000000080 +; F1: 0x00000032: Beginning address offset: 0x0000000000000080 ; F1: Ending address offset: 0x0000000000000088 ; F1: Location description: 51 Index: test/DebugInfo/X86/array.ll =================================================================== --- test/DebugInfo/X86/array.ll +++ test/DebugInfo/X86/array.ll @@ -35,13 +35,13 @@ %array = alloca [4 x i32], align 16 tail call void @llvm.dbg.value(metadata i32 %argc, i64 0, metadata !19, metadata !DIExpression()), !dbg !35 tail call void @llvm.dbg.value(metadata i8** %argv, i64 0, metadata !20, metadata !DIExpression()), !dbg !35 - tail call void @llvm.dbg.value(metadata [4 x i32]* %array, i64 0, metadata !21, metadata !DIExpression()), !dbg !36 + tail call void @llvm.dbg.value(metadata [4 x i32]* %array, i64 0, metadata !21, metadata !DIExpression(DW_OP_deref)), !dbg !36 %1 = bitcast [4 x i32]* %array to i8*, !dbg !36 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* bitcast ([4 x i32]* @main.array to i8*), i64 16, i32 16, i1 false), !dbg !36 - tail call void @llvm.dbg.value(metadata [4 x i32]* %array, i64 0, metadata !21, metadata !DIExpression()), !dbg !36 + tail call void @llvm.dbg.value(metadata [4 x i32]* %array, i64 0, metadata !21, metadata !DIExpression(DW_OP_deref)), !dbg !36 %2 = getelementptr inbounds [4 x i32], [4 x i32]* %array, i64 0, i64 0, !dbg !37 call void @f(i32* %2), !dbg !37 - tail call void @llvm.dbg.value(metadata [4 x i32]* %array, i64 0, metadata !21, metadata !DIExpression()), !dbg !36 + tail call void @llvm.dbg.value(metadata [4 x i32]* %array, i64 0, metadata !21, metadata !DIExpression(DW_OP_deref)), !dbg !36 %3 = load i32, i32* %2, align 16, !dbg !38, !tbaa !30 ret i32 %3, !dbg !38 } Index: test/DebugInfo/X86/dbg-value-const-byref.ll =================================================================== --- test/DebugInfo/X86/dbg-value-const-byref.ll +++ test/DebugInfo/X86/dbg-value-const-byref.ll @@ -56,7 +56,7 @@ %call1 = call i32 (...) @f1() #3, !dbg !19 call void @llvm.dbg.value(metadata i32 %call1, i64 0, metadata !10, metadata !DIExpression()), !dbg !19 store i32 %call1, i32* %i, align 4, !dbg !19, !tbaa !20 - call void @llvm.dbg.value(metadata i32* %i, i64 0, metadata !10, metadata !DIExpression()), !dbg !24 + call void @llvm.dbg.value(metadata i32* %i, i64 0, metadata !10, metadata !DIExpression(DW_OP_deref)), !dbg !24 call void @f2(i32* %i) #3, !dbg !24 ret i32 0, !dbg !25 } Index: test/DebugInfo/X86/debug-loc-asan.ll =================================================================== --- test/DebugInfo/X86/debug-loc-asan.ll +++ /dev/null @@ -1,182 +0,0 @@ -; RUN: llc -O0 -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s - -; Verify that we have correct debug info for local variables in code -; instrumented with AddressSanitizer. - -; Generated from the source file test.cc: -; int bar(int y) { -; return y + 2; -; } -; with "clang++ -S -emit-llvm -fsanitize=address -O0 -g test.cc" - -; First, argument variable "y" resides in %rdi: -; CHECK: DEBUG_VALUE: bar:y <- %RDI - -; Then its address is stored in a location on a stack: -; CHECK: movq %rdi, [[OFFSET:[0-9]+]](%rsp) -; CHECK-NEXT: [[START_LABEL:.Ltmp[0-9]+]] -; CHECK-NEXT: DEBUG_VALUE: bar:y <- [%RSP+[[OFFSET]]] -; This location should be valid until the end of the function. - -; CHECK: .Ldebug_loc{{[0-9]+}}: -; We expect two location ranges for the variable. - -; First, its address is stored in %rdi: -; CHECK: .quad .Lfunc_begin0-.Lfunc_begin0 -; CHECK-NEXT: .quad [[START_LABEL]]-.Lfunc_begin0 -; CHECK: DW_OP_breg5 - -; Then it's addressed via %rsp: -; CHECK: .quad [[START_LABEL]]-.Lfunc_begin0 -; CHECK-NEXT: .Lfunc_end0-.Lfunc_begin0 -; CHECK: DW_OP_breg7 -; CHECK-NEXT: [[OFFSET]] -; CHECK: DW_OP_deref - -; ModuleID = 'test.cc' -target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux-gnu" - -@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 1, void ()* @asan.module_ctor }] -@__asan_option_detect_stack_use_after_return = external global i32 -@__asan_gen_ = private unnamed_addr constant [16 x i8] c"1 32 4 6 y.addr\00", align 1 - -; Function Attrs: nounwind sanitize_address uwtable -define i32 @_Z3bari(i32 %y) #0 !dbg !4 { -entry: - %MyAlloca = alloca [64 x i8], align 32 - %0 = ptrtoint [64 x i8]* %MyAlloca to i64 - %1 = load i32, i32* @__asan_option_detect_stack_use_after_return - %2 = icmp ne i32 %1, 0 - br i1 %2, label %3, label %5 - -; <label>:3 ; preds = %entry - %4 = call i64 @__asan_stack_malloc_0(i64 64, i64 %0) - br label %5 - -; <label>:5 ; preds = %entry, %3 - %6 = phi i64 [ %0, %entry ], [ %4, %3 ] - %7 = add i64 %6, 32 - %8 = inttoptr i64 %7 to i32* - %9 = inttoptr i64 %6 to i64* - store i64 1102416563, i64* %9 - %10 = add i64 %6, 8 - %11 = inttoptr i64 %10 to i64* - store i64 ptrtoint ([16 x i8]* @__asan_gen_ to i64), i64* %11 - %12 = add i64 %6, 16 - %13 = inttoptr i64 %12 to i64* - store i64 ptrtoint (i32 (i32)* @_Z3bari to i64), i64* %13 - %14 = lshr i64 %6, 3 - %15 = add i64 %14, 2147450880 - %16 = add i64 %15, 0 - %17 = inttoptr i64 %16 to i64* - store i64 -868083100587789839, i64* %17 - %18 = ptrtoint i32* %8 to i64 - %19 = lshr i64 %18, 3 - %20 = add i64 %19, 2147450880 - %21 = inttoptr i64 %20 to i8* - %22 = load i8, i8* %21 - %23 = icmp ne i8 %22, 0 - call void @llvm.dbg.declare(metadata i32* %8, metadata !12, metadata !14), !dbg !DILocation(scope: !4) - br i1 %23, label %24, label %30 - -; <label>:24 ; preds = %5 - %25 = and i64 %18, 7 - %26 = add i64 %25, 3 - %27 = trunc i64 %26 to i8 - %28 = icmp sge i8 %27, %22 - br i1 %28, label %29, label %30 - -; <label>:29 ; preds = %24 - call void @__asan_report_store4(i64 %18) - call void asm sideeffect "", ""() - unreachable - -; <label>:30 ; preds = %24, %5 - store i32 %y, i32* %8, align 4 - %31 = ptrtoint i32* %8 to i64, !dbg !13 - %32 = lshr i64 %31, 3, !dbg !13 - %33 = add i64 %32, 2147450880, !dbg !13 - %34 = inttoptr i64 %33 to i8*, !dbg !13 - %35 = load i8, i8* %34, !dbg !13 - %36 = icmp ne i8 %35, 0, !dbg !13 - br i1 %36, label %37, label %43, !dbg !13 - -; <label>:37 ; preds = %30 - %38 = and i64 %31, 7, !dbg !13 - %39 = add i64 %38, 3, !dbg !13 - %40 = trunc i64 %39 to i8, !dbg !13 - %41 = icmp sge i8 %40, %35, !dbg !13 - br i1 %41, label %42, label %43 - -; <label>:42 ; preds = %37 - call void @__asan_report_load4(i64 %31), !dbg !13 - call void asm sideeffect "", ""() - unreachable - -; <label>:43 ; preds = %37, %30 - %44 = load i32, i32* %8, align 4, !dbg !13 - %add = add nsw i32 %44, 2, !dbg !13 - store i64 1172321806, i64* %9, !dbg !13 - %45 = icmp ne i64 %6, %0, !dbg !13 - br i1 %45, label %46, label %53, !dbg !13 - -; <label>:46 ; preds = %43 - %47 = add i64 %15, 0, !dbg !13 - %48 = inttoptr i64 %47 to i64*, !dbg !13 - store i64 -723401728380766731, i64* %48, !dbg !13 - %49 = add i64 %6, 56, !dbg !13 - %50 = inttoptr i64 %49 to i64*, !dbg !13 - %51 = load i64, i64* %50, !dbg !13 - %52 = inttoptr i64 %51 to i8*, !dbg !13 - store i8 0, i8* %52, !dbg !13 - br label %56, !dbg !13 - -; <label>:53 ; preds = %43 - %54 = add i64 %15, 0, !dbg !13 - %55 = inttoptr i64 %54 to i64*, !dbg !13 - store i64 0, i64* %55, !dbg !13 - br label %56, !dbg !13 - -; <label>:56 ; preds = %53, %46 - ret i32 %add, !dbg !13 -} - -; Function Attrs: nounwind readnone -declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 - -define internal void @asan.module_ctor() { - call void @__asan_init_v3() - ret void -} - -declare void @__asan_init_v3() - -declare void @__asan_report_load4(i64) - -declare void @__asan_report_store4(i64) - -declare i64 @__asan_stack_malloc_0(i64, i64) - -attributes #0 = { nounwind sanitize_address uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -attributes #1 = { nounwind readnone } - -!llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!9, !10} -!llvm.ident = !{!11} - -!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 (209308)", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2) -!1 = !DIFile(filename: "test.cc", directory: "/llvm_cmake_gcc") -!2 = !{} -!3 = !{!4} -!4 = distinct !DISubprogram(name: "bar", linkageName: "_Z3bari", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 1, file: !1, scope: !5, type: !6, variables: !2) -!5 = !DIFile(filename: "test.cc", directory: "/llvm_cmake_gcc") -!6 = !DISubroutineType(types: !7) -!7 = !{!8, !8} -!8 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) -!9 = !{i32 2, !"Dwarf Version", i32 4} -!10 = !{i32 2, !"Debug Info Version", i32 3} -!11 = !{!"clang version 3.5.0 (209308)"} -!12 = !DILocalVariable(name: "y", line: 1, arg: 1, scope: !4, file: !5, type: !8) -!13 = !DILocation(line: 2, scope: !4) -!14 = !DIExpression(DW_OP_deref) Index: test/DebugInfo/X86/op_deref.ll =================================================================== --- test/DebugInfo/X86/op_deref.ll +++ test/DebugInfo/X86/op_deref.ll @@ -20,11 +20,11 @@ ; right now, so we check the asm output: ; RUN: llc -O0 -mtriple=x86_64-apple-darwin %s -o - -filetype=asm | FileCheck %s -check-prefix=ASM-CHECK ; vla should have a register-indirect address at one point. -; ASM-CHECK: DEBUG_VALUE: vla <- %RCX +; ASM-CHECK: DEBUG_VALUE: vla <- [%RCX+0] ; ASM-CHECK: DW_OP_breg2 ; RUN: llvm-as %s -o - | llvm-dis - | FileCheck %s --check-prefix=PRETTY-PRINT -; PRETTY-PRINT: DIExpression(DW_OP_deref, DW_OP_deref) +; PRETTY-PRINT: DIExpression(DW_OP_deref) define void @testVLAwithSize(i32 %s) nounwind uwtable ssp !dbg !5 { entry: @@ -108,4 +108,4 @@ !27 = !DILocation(line: 8, column: 1, scope: !13) !28 = !DIFile(filename: "bar.c", directory: "/Users/echristo/tmp") !29 = !{i32 1, !"Debug Info Version", i32 3} -!30 = !DIExpression(DW_OP_deref, DW_OP_deref) +!30 = !DIExpression(DW_OP_deref) Index: test/DebugInfo/X86/reference-argument.ll =================================================================== --- test/DebugInfo/X86/reference-argument.ll +++ test/DebugInfo/X86/reference-argument.ll @@ -3,7 +3,7 @@ ; extracted from debuginfo-tests/aggregate-indirect-arg.cpp ; v should not be a pointer. -; CHECK: ##DEBUG_VALUE: foo:v <- %RSI +; CHECK: ##DEBUG_VALUE: foo:v <- [%RSI+0] ; rdar://problem/13658587 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" Index: test/DebugInfo/X86/vla.ll =================================================================== --- test/DebugInfo/X86/vla.ll +++ test/DebugInfo/X86/vla.ll @@ -1,7 +1,6 @@ ; RUN: llc -O0 -mtriple=x86_64-apple-darwin -filetype=asm %s -o - | FileCheck %s ; Ensure that we generate an indirect location for the variable length array a. -; CHECK: ##DEBUG_VALUE: vla:a <- %RDX -; CHECK: DW_OP_breg1 +; CHECK: ##DEBUG_VALUE: vla:a <- [%RDX+0] ; rdar://problem/13658587 ; ; generated from: Index: test/Transforms/Util/simplify-dbg-declare-load.ll =================================================================== --- /dev/null +++ test/Transforms/Util/simplify-dbg-declare-load.ll @@ -0,0 +1,52 @@ +; RUN: opt -instcombine -S < %s | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%foo = type { i64, i32, i32 } + +; Function Attrs: nounwind readnone +declare void @llvm.dbg.declare(metadata, metadata, metadata) #0 +declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #0 + +; Function Attrs: sspreq +define void @julia_fastshortest_6256() #1 { +top: + %cp = alloca %foo, align 8 + call void @llvm.dbg.declare(metadata %foo* %cp, metadata !1, metadata !16), !dbg !17 + br i1 undef, label %idxend, label %fail + +fail: ; preds = %top + unreachable + +idxend: ; preds = %top +; CHECK-NOT call void @llvm.dbg.value(metadata %foo* %cp, i64 0, metadata !1, metadata !16), !dbg !17 + %0 = load %foo, %foo* %cp, align 8 +; CHECK: call void @llvm.dbg.value(metadata %foo %0, i64 0, metadata !1, metadata !16), !dbg !17 + store %foo %0, %foo* undef, align 8 + ret void +} + +attributes #0 = { nounwind readnone } +attributes #1 = { sspreq } + +!llvm.module.flags = !{!0} +!llvm.dbg.cu = !{} + +!0 = !{i32 1, !"Debug Info Version", i32 3} +!1 = !DILocalVariable(name: "cp", scope: !2, file: !3, line: 106, type: !12) +!2 = distinct !DISubprogram(name: "fastshortest", linkageName: "julia_fastshortest_6256", scope: null, file: !3, type: !4, isLocal: false, isDefinition: true, isOptimized: true, variables: !11) +!3 = !DIFile(filename: "grisu/fastshortest.jl", directory: ".") +!4 = !DISubroutineType(types: !5) +!5 = !{!6, !7} +!6 = !DIBasicType(name: "Float64", size: 64, align: 64, encoding: DW_ATE_unsigned) +!7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64, align: 64) +!8 = !DICompositeType(tag: DW_TAG_structure_type, name: "jl_value_t", file: !9, line: 71, align: 64, elements: !10) +!9 = !DIFile(filename: "julia.h", directory: "") +!10 = !{!7} +!11 = !{} +!12 = !DICompositeType(tag: DW_TAG_structure_type, name: "Float", size: 128, align: 64, elements: !13, runtimeLang: DW_LANG_Julia) +!13 = !{!14, !15, !15} +!14 = !DIBasicType(name: "UInt64", size: 64, align: 64, encoding: DW_ATE_unsigned) +!15 = !DIBasicType(name: "Int32", size: 32, align: 32, encoding: DW_ATE_unsigned) +!16 = !DIExpression() +!17 = !DILocation(line: 106, scope: !2)