Fix LLVM's use of DW_OP_bit_piece in DWARF expressions.

LLVM's use of DW_OP_bit_piece is incorrect and a based on a
misunderstanding of the wording in the DWARF specification. The offset
argument of DW_OP_bit_piece refers to the offset into the location
that is on the top of the DWARF expression stack, and not an offset
into the source variable. This has since also been clarified in the
DWARF specification.

This patch fixes all uses of DW_OP_bit_piece to emit the correct
offset and simplifies the DwarfExpression class to semi-automaticaly
emit empty DW_OP_pieces to adjust the offset of the source variable,
thus simplifying the code using DwarfExpression.

While this is an incompatible bugfix, in practice I don't expect this
to be much of a problem since LLVM's old interpretation and the
correct interpretation of DW_OP_bit_piece differ only when there are
gaps in the fragmented locations of the described variables or if
individual fragments are smaller than a byte. LLDB at least won't
interpret locations with gaps in them because is has no way to present
undefined bits in a variable, and there is a high probability that an
old-form expression will be malformed when interpreted correctly,
because the DW_OP_bit_piece offset will be outside of the location at
the top of the stack.

As a nice side-effect, this patch enables us to use a more efficient
encoding for subregisters: In order to express a sub-register at a
non-zero offset we now use a DW_OP_bit_piece instead of shifting the
value into place manually.

This patch also adds missing test coverage for code paths that weren't
exercised before.

<rdar://problem/29335809>
Differential Revision: https://reviews.llvm.org/D27550

llvm-svn: 289266
diff --git a/llvm/test/DebugInfo/AArch64/frameindices.ll b/llvm/test/DebugInfo/AArch64/frameindices.ll
index 4514f01..2c0d75a 100644
--- a/llvm/test/DebugInfo/AArch64/frameindices.ll
+++ b/llvm/test/DebugInfo/AArch64/frameindices.ll
@@ -5,8 +5,8 @@
 ; CHECK: DW_TAG_inlined_subroutine
 ; CHECK:    "_Z3f111A"
 ; CHECK: DW_TAG_formal_parameter
-; CHECK: DW_AT_location [DW_FORM_block1]    (<0x0b> 91 51 9d 78 08 91 4a 9d 38 88 01 )
-;  -- fbreg -47, bit-piece 120 8 , fbreg -54, bit-piece 56 136 ------^
+; CHECK: DW_AT_location [DW_FORM_block1]    (<0x0c> 93 01 91 51 93 0f 93 01 91 4a 93 07 )
+;  -- piece 0x00000001, fbreg -47, piece 0x0000000f, piece 0x00000001, fbreg -54, piece 0x00000007 ------^
 ; CHECK: DW_AT_abstract_origin {{.*}} "p1"
 ;
 ; long a;
diff --git a/llvm/test/DebugInfo/MIR/ARM/lit.local.cfg b/llvm/test/DebugInfo/MIR/ARM/lit.local.cfg
new file mode 100644
index 0000000..98c6700
--- /dev/null
+++ b/llvm/test/DebugInfo/MIR/ARM/lit.local.cfg
@@ -0,0 +1,3 @@
+if not 'ARM' in config.root.targets:
+    config.unsupported = True
+
diff --git a/llvm/test/DebugInfo/MIR/ARM/split-superreg-piece.mir b/llvm/test/DebugInfo/MIR/ARM/split-superreg-piece.mir
new file mode 100644
index 0000000..422e7ed
--- /dev/null
+++ b/llvm/test/DebugInfo/MIR/ARM/split-superreg-piece.mir
@@ -0,0 +1,125 @@
+# RUN: llc -filetype=obj -o - %s | llvm-dwarfdump - | FileCheck %s
+# CHECK: .debug_info contents:
+# CHECK: DW_TAG_variable
+# CHECK-NEXT: DW_AT_location [DW_FORM_data4]	([[OFS:.*]])
+# CHECK-NEXT: DW_AT_name {{.*}}"vec"
+# CHECK: .debug_loc contents:
+# CHECK: [[OFS]]: Beginning address offset: 0x0000000000000016
+# CHECK:             Ending address offset: 0x000000000000001e
+# CHECK:              Location description: 93 10 90 80 02 93 08 90 81 02 93 08 
+#                  piece 0x00000010, d0, piece 0x00000008, d1, piece 0x00000008
+--- |
+  ; Generate from (and then manually modified to incorporate a DW_OP_LLVM_fragment):
+  ; typedef float vec2 __attribute__((vector_size(16)));
+  ; vec2 v();
+  ; float f() {
+  ;   vec2 vec = v();
+  ;   return vec[0] + vec[1];
+  ; }
+
+  target datalayout = "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
+  target triple = "thumbv7s-apple-ios5.0.0"
+  
+  define float @f() local_unnamed_addr #0 !dbg !9 {
+  entry:
+    %call = tail call <4 x float> bitcast (<4 x float> (...)* @v to <4 x float> ()*)() #0, !dbg !19
+    tail call void @llvm.dbg.value(metadata <4 x float> %call, i64 0, metadata !14, metadata !20), !dbg !21
+    %vecext = extractelement <4 x float> %call, i32 0, !dbg !22
+    %vecext1 = extractelement <4 x float> %call, i32 1, !dbg !23
+    %add = fadd float %vecext, %vecext1, !dbg !24
+    ret float %add, !dbg !25
+  }
+  
+  declare arm_aapcs_vfpcc <4 x float> @v(...) local_unnamed_addr #0
+  
+  declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #0
+  
+  attributes #0 = { nounwind readnone }
+  
+  !llvm.dbg.cu = !{!0}
+  !llvm.module.flags = !{!3, !4, !5, !6, !7}
+  !llvm.ident = !{!8}
+  
+  !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 4.0.0 (trunk 286322) (llvm/trunk 286305)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+  !1 = !DIFile(filename: "v.c", directory: "/")
+  !2 = !{}
+  !3 = !{i32 2, !"Dwarf Version", i32 2}
+  !4 = !{i32 2, !"Debug Info Version", i32 3}
+  !5 = !{i32 1, !"wchar_size", i32 4}
+  !6 = !{i32 1, !"min_enum_size", i32 4}
+  !7 = !{i32 1, !"PIC Level", i32 2}
+  !8 = !{!"clang version 4.0.0 (trunk 286322) (llvm/trunk 286305)"}
+  !9 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !10, isLocal: false, isDefinition: true, scopeLine: 3, isOptimized: true, unit: !0, variables: !13)
+  !10 = !DISubroutineType(types: !11)
+  !11 = !{!12}
+  !12 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
+  !13 = !{!14}
+  !14 = !DILocalVariable(name: "vec", scope: !9, file: !1, line: 4, type: !15)
+  !15 = !DIDerivedType(tag: DW_TAG_typedef, name: "vec2", file: !1, line: 1, baseType: !16)
+  !16 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 256, flags: DIFlagVector, elements: !17)
+  !17 = !{!18}
+  !18 = !DISubrange(count: 8)
+  !19 = !DILocation(line: 4, column: 13, scope: !9)
+  !20 = !DIExpression(DW_OP_LLVM_fragment, 128, 128)
+  !21 = !DILocation(line: 4, column: 7, scope: !9)
+  !22 = !DILocation(line: 5, column: 9, scope: !9)
+  !23 = !DILocation(line: 5, column: 18, scope: !9)
+  !24 = !DILocation(line: 5, column: 16, scope: !9)
+  !25 = !DILocation(line: 5, column: 2, scope: !9)
+
+...
+---
+name:            f
+alignment:       1
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+calleeSavedRegisters: [ '%lr', '%d8', '%d9', '%d10', '%d11', '%d12', '%d13', 
+                        '%d14', '%d15', '%q4', '%q5', '%q6', '%q7', '%r4', 
+                        '%r5', '%r6', '%r7', '%r8', '%r10', '%r11', '%s16', 
+                        '%s17', '%s18', '%s19', '%s20', '%s21', '%s22', 
+                        '%s23', '%s24', '%s25', '%s26', '%s27', '%s28', 
+                        '%s29', '%s30', '%s31', '%d8_d10', '%d9_d11', '%d10_d12', 
+                        '%d11_d13', '%d12_d14', '%d13_d15', '%q4_q5', '%q5_q6', 
+                        '%q6_q7', '%q4_q5_q6_q7', '%r4_r5', '%r6_r7', '%r10_r11', 
+                        '%d8_d9_d10', '%d9_d10_d11', '%d10_d11_d12', '%d11_d12_d13', 
+                        '%d12_d13_d14', '%d13_d14_d15', '%d8_d10_d12', 
+                        '%d9_d11_d13', '%d10_d12_d14', '%d11_d13_d15', 
+                        '%d8_d10_d12_d14', '%d9_d11_d13_d15', '%d9_d10', 
+                        '%d11_d12', '%d13_d14', '%d9_d10_d11_d12', '%d11_d12_d13_d14' ]
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       4
+  offsetAdjustment: 0
+  maxAlignment:    4
+  adjustsStack:    true
+  hasCalls:        true
+  maxCallFrameSize: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+stack:           
+  - { id: 0, type: spill-slot, offset: -4, size: 4, alignment: 4, callee-saved-register: '%lr' }
+body:             |
+  bb.0.entry:
+    liveins: %lr
+  
+    early-clobber %sp = frame-setup t2STR_PRE killed undef %lr, %sp, -4, 14, _
+    frame-setup CFI_INSTRUCTION def_cfa_offset 4
+    frame-setup CFI_INSTRUCTION offset %lr, -4
+    tBL 14, _, @v, csr_ios, implicit-def dead %lr, implicit %sp, implicit-def %sp, implicit-def %r0, implicit-def %r1, implicit-def %r2, implicit-def %r3, debug-location !19
+    %d1 = VMOVDRR killed %r2, killed %r3, 14, _, implicit-def %q0, debug-location !19
+    %d0 = VMOVDRR killed %r0, killed %r1, 14, _, implicit killed %q0, implicit-def %q0, debug-location !19
+    DBG_VALUE debug-use %q0, debug-use _, !14, !20, debug-location !21
+    %s4 = VMOVS %s1, 14, _, implicit-def %d2, debug-location !24
+    %d0 = VADDfd %d0, killed %d2, 14, _, implicit killed %q0, debug-location !24
+    %r0 = VMOVRS %s0, 14, _, implicit killed %d0, debug-location !25
+    %lr, %sp = t2LDR_POST %sp, 4, 14, _, debug-location !25
+    tBX_RET 14, _, implicit %r0, debug-location !25
+
+...
diff --git a/llvm/test/DebugInfo/MIR/ARM/split-superreg.mir b/llvm/test/DebugInfo/MIR/ARM/split-superreg.mir
new file mode 100644
index 0000000..9b56f9f
--- /dev/null
+++ b/llvm/test/DebugInfo/MIR/ARM/split-superreg.mir
@@ -0,0 +1,125 @@
+# RUN: llc -filetype=obj -o - %s | llvm-dwarfdump - | FileCheck %s
+# CHECK: .debug_info contents:
+# CHECK: DW_TAG_variable
+# CHECK-NEXT: DW_AT_location [DW_FORM_data4]	([[OFS:.*]])
+# CHECK-NEXT: DW_AT_name {{.*}}"vec"
+# CHECK: .debug_loc contents:
+# CHECK: [[OFS]]: Beginning address offset: 0x0000000000000016
+# CHECK:             Ending address offset: 0x000000000000001e
+# CHECK:              Location description: 90 80 02 93 08 90 81 02 93 08 
+#                                           d0, piece 0x00000008, d1, piece 0x00000008
+--- |
+  ; Generated from:
+  ; typedef float vec2 __attribute__((vector_size(16)));
+  ; vec2 v();
+  ; float f() {
+  ;   vec2 vec = v();
+  ;   return vec[0] + vec[1];
+  ; }
+
+  target datalayout = "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
+  target triple = "thumbv7s-apple-ios5.0.0"
+  
+  define float @f() local_unnamed_addr #0 !dbg !9 {
+  entry:
+    %call = tail call <4 x float> bitcast (<4 x float> (...)* @v to <4 x float> ()*)() #0, !dbg !19
+    tail call void @llvm.dbg.value(metadata <4 x float> %call, i64 0, metadata !14, metadata !20), !dbg !21
+    %vecext = extractelement <4 x float> %call, i32 0, !dbg !22
+    %vecext1 = extractelement <4 x float> %call, i32 1, !dbg !23
+    %add = fadd float %vecext, %vecext1, !dbg !24
+    ret float %add, !dbg !25
+  }
+  
+  declare arm_aapcs_vfpcc <4 x float> @v(...) local_unnamed_addr #0
+  
+  declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #0
+  
+  attributes #0 = { nounwind readnone }
+  
+  !llvm.dbg.cu = !{!0}
+  !llvm.module.flags = !{!3, !4, !5, !6, !7}
+  !llvm.ident = !{!8}
+  
+  !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 4.0.0 (trunk 286322) (llvm/trunk 286305)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+  !1 = !DIFile(filename: "v.c", directory: "/")
+  !2 = !{}
+  !3 = !{i32 2, !"Dwarf Version", i32 2}
+  !4 = !{i32 2, !"Debug Info Version", i32 3}
+  !5 = !{i32 1, !"wchar_size", i32 4}
+  !6 = !{i32 1, !"min_enum_size", i32 4}
+  !7 = !{i32 1, !"PIC Level", i32 2}
+  !8 = !{!"clang version 4.0.0 (trunk 286322) (llvm/trunk 286305)"}
+  !9 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !10, isLocal: false, isDefinition: true, scopeLine: 3, isOptimized: true, unit: !0, variables: !13)
+  !10 = !DISubroutineType(types: !11)
+  !11 = !{!12}
+  !12 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
+  !13 = !{!14}
+  !14 = !DILocalVariable(name: "vec", scope: !9, file: !1, line: 4, type: !15)
+  !15 = !DIDerivedType(tag: DW_TAG_typedef, name: "vec2", file: !1, line: 1, baseType: !16)
+  !16 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 128, flags: DIFlagVector, elements: !17)
+  !17 = !{!18}
+  !18 = !DISubrange(count: 4)
+  !19 = !DILocation(line: 4, column: 13, scope: !9)
+  !20 = !DIExpression()
+  !21 = !DILocation(line: 4, column: 7, scope: !9)
+  !22 = !DILocation(line: 5, column: 9, scope: !9)
+  !23 = !DILocation(line: 5, column: 18, scope: !9)
+  !24 = !DILocation(line: 5, column: 16, scope: !9)
+  !25 = !DILocation(line: 5, column: 2, scope: !9)
+
+...
+---
+name:            f
+alignment:       1
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+calleeSavedRegisters: [ '%lr', '%d8', '%d9', '%d10', '%d11', '%d12', '%d13', 
+                        '%d14', '%d15', '%q4', '%q5', '%q6', '%q7', '%r4', 
+                        '%r5', '%r6', '%r7', '%r8', '%r10', '%r11', '%s16', 
+                        '%s17', '%s18', '%s19', '%s20', '%s21', '%s22', 
+                        '%s23', '%s24', '%s25', '%s26', '%s27', '%s28', 
+                        '%s29', '%s30', '%s31', '%d8_d10', '%d9_d11', '%d10_d12', 
+                        '%d11_d13', '%d12_d14', '%d13_d15', '%q4_q5', '%q5_q6', 
+                        '%q6_q7', '%q4_q5_q6_q7', '%r4_r5', '%r6_r7', '%r10_r11', 
+                        '%d8_d9_d10', '%d9_d10_d11', '%d10_d11_d12', '%d11_d12_d13', 
+                        '%d12_d13_d14', '%d13_d14_d15', '%d8_d10_d12', 
+                        '%d9_d11_d13', '%d10_d12_d14', '%d11_d13_d15', 
+                        '%d8_d10_d12_d14', '%d9_d11_d13_d15', '%d9_d10', 
+                        '%d11_d12', '%d13_d14', '%d9_d10_d11_d12', '%d11_d12_d13_d14' ]
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       4
+  offsetAdjustment: 0
+  maxAlignment:    4
+  adjustsStack:    true
+  hasCalls:        true
+  maxCallFrameSize: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+stack:           
+  - { id: 0, type: spill-slot, offset: -4, size: 4, alignment: 4, callee-saved-register: '%lr' }
+body:             |
+  bb.0.entry:
+    liveins: %lr
+  
+    early-clobber %sp = frame-setup t2STR_PRE killed undef %lr, %sp, -4, 14, _
+    frame-setup CFI_INSTRUCTION def_cfa_offset 4
+    frame-setup CFI_INSTRUCTION offset %lr, -4
+    tBL 14, _, @v, csr_ios, implicit-def dead %lr, implicit %sp, implicit-def %sp, implicit-def %r0, implicit-def %r1, implicit-def %r2, implicit-def %r3, debug-location !19
+    %d1 = VMOVDRR killed %r2, killed %r3, 14, _, implicit-def %q0, debug-location !19
+    %d0 = VMOVDRR killed %r0, killed %r1, 14, _, implicit killed %q0, implicit-def %q0, debug-location !19
+    DBG_VALUE debug-use %q0, debug-use _, !14, !20, debug-location !21
+    %s4 = VMOVS %s1, 14, _, implicit-def %d2, debug-location !24
+    %d0 = VADDfd %d0, killed %d2, 14, _, implicit killed %q0, debug-location !24
+    %r0 = VMOVRS %s0, 14, _, implicit killed %d0, debug-location !25
+    %lr, %sp = t2LDR_POST %sp, 4, 14, _, debug-location !25
+    tBX_RET 14, _, implicit %r0, debug-location !25
+
+...
diff --git a/llvm/test/DebugInfo/MIR/X86/bit-piece-dh.mir b/llvm/test/DebugInfo/MIR/X86/bit-piece-dh.mir
new file mode 100644
index 0000000..34a10bd
--- /dev/null
+++ b/llvm/test/DebugInfo/MIR/X86/bit-piece-dh.mir
@@ -0,0 +1,102 @@
+# RUN: llc -filetype=obj -o - %s | llvm-dwarfdump - | FileCheck %s
+# CHECK: .debug_info contents:
+# CHECK: DW_TAG_variable
+# CHECK-NEXT: DW_AT_location [DW_FORM_sec_offset]	([[OFS:.*]])
+# CHECK-NEXT: DW_AT_name {{.*}}"dh"
+# CHECK: .debug_loc contents:
+# CHECK: [[OFS]]: Beginning address offset: 0x0000000000000002
+# CHECK:             Ending address offset: 0x000000000000000c
+# CHECK:              Location description: 51 9d 08 08
+#                                           rdx, bit-piece 8 8
+--- |
+  ; Manually created after:
+  ; char f(int i) {
+  ;   char dh = i>>8;
+  ;   return dh;
+  ; }
+
+  target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+  target triple = "x86_64-apple-macosx10.12.0"
+  
+  define signext i8 @f(i32 %i) local_unnamed_addr #0 !dbg !7 {
+  entry:
+    tail call void @llvm.dbg.value(metadata i32 %i, i64 0, metadata !13, metadata !15), !dbg !16
+    %shr1 = lshr i32 %i, 8, !dbg !17
+    %conv = trunc i32 %shr1 to i8, !dbg !18
+    tail call void @llvm.dbg.value(metadata i8 %conv, i64 0, metadata !14, metadata !15), !dbg !19
+    ret i8 %conv, !dbg !20
+  }
+  
+  declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #0
+  
+  attributes #0 = { nounwind readnone }
+  
+  !llvm.dbg.cu = !{!0}
+  !llvm.module.flags = !{!3, !4, !5}
+  !llvm.ident = !{!6}
+  
+  !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 4.0.0 (trunk 288677) (llvm/trunk 288679)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+  !1 = !DIFile(filename: "t.c", directory: "/")
+  !2 = !{}
+  !3 = !{i32 2, !"Dwarf Version", i32 4}
+  !4 = !{i32 2, !"Debug Info Version", i32 3}
+  !5 = !{i32 1, !"PIC Level", i32 2}
+  !6 = !{!"clang version 4.0.0 (trunk 288677) (llvm/trunk 288679)"}
+  !7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !12)
+  !8 = !DISubroutineType(types: !9)
+  !9 = !{!10, !11}
+  !10 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
+  !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+  !12 = !{!13, !14}
+  !13 = !DILocalVariable(name: "i", arg: 1, scope: !7, file: !1, line: 1, type: !11)
+  !14 = !DILocalVariable(name: "dh", scope: !7, file: !1, line: 2, type: !10)
+  !15 = !DIExpression()
+  !16 = !DILocation(line: 1, column: 12, scope: !7)
+  !17 = !DILocation(line: 2, column: 14, scope: !7)
+  !18 = !DILocation(line: 2, column: 13, scope: !7)
+  !19 = !DILocation(line: 2, column: 8, scope: !7)
+  !20 = !DILocation(line: 3, column: 3, scope: !7)
+
+...
+---
+name:            f
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+liveins:         
+  - { reg: '%edi' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       8
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  maxCallFrameSize: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+fixedStack:      
+  - { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16 }
+body:             |
+  bb.0.entry:
+    liveins: %edi, %rbp
+  
+    frame-setup PUSH64r killed %rbp, implicit-def %rsp, implicit %rsp
+    CFI_INSTRUCTION def_cfa_offset 16
+    CFI_INSTRUCTION offset %rbp, -16
+    %rbp = frame-setup MOV64rr %rsp
+    CFI_INSTRUCTION def_cfa_register %rbp
+    DBG_VALUE debug-use %dh, debug-use _, !14, !15, debug-location !16
+    %edi = SHR32ri killed %edi, 8, implicit-def dead %eflags, debug-location !17
+    %eax = MOVSX32rr8 %dil, implicit killed %edi, debug-location !20
+    %rbp = POP64r implicit-def %rsp, implicit %rsp, debug-location !20
+    RETQ %eax, debug-location !20
+
+...
diff --git a/llvm/test/DebugInfo/X86/PR26148.ll b/llvm/test/DebugInfo/X86/PR26148.ll
index 0b2b082..b544ab5 100644
--- a/llvm/test/DebugInfo/X86/PR26148.ll
+++ b/llvm/test/DebugInfo/X86/PR26148.ll
@@ -21,8 +21,8 @@
 ;
 ; CHECK: 0x00000025: Beginning address offset: 0x0000000000000004
 ; CHECK:                Ending address offset: 0x0000000000000004
-; CHECK:                 Location description: 10 03 93 04 55 93 04
-; constu 0x00000003, piece 0x00000004, rdi, piece 0x00000004
+; CHECK:                 Location description: 10 03 93 04 55 93 02
+; constu 0x00000003, piece 0x00000004, rdi, piece 0x00000002
 ; CHECK:             Beginning address offset: 0x0000000000000004
 ; CHECK:                Ending address offset: 0x0000000000000014
 ; CHECK:                 Location description: 10 03 93 04 10 00
diff --git a/llvm/test/DebugInfo/X86/dw_op_minus_direct.ll b/llvm/test/DebugInfo/X86/dw_op_minus_direct.ll
new file mode 100644
index 0000000..a84c506
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/dw_op_minus_direct.ll
@@ -0,0 +1,48 @@
+; Test dwarf codegen of DW_OP_minus.
+; RUN: llc -filetype=obj < %s | llvm-dwarfdump - | FileCheck %s
+
+; This was derived manually from:
+; int inc(int i) {
+;  return i+1;
+; }
+
+; CHECK: Beginning address offset: 0x0000000000000000
+; CHECK:    Ending address offset: 0x0000000000000004
+; CHECK:     Location description: 50 10 01 1c 93 04
+;                                  rax, constu 0x00000001, minus, piece 0x00000004
+source_filename = "minus.c"
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.12.0"
+
+define i32 @inc(i32 %i) local_unnamed_addr #1 !dbg !7 {
+entry:
+  %add = add nsw i32 %i, 1, !dbg !15
+  tail call void @llvm.dbg.value(metadata i32 %add, i64 0, metadata !12, metadata !13), !dbg !14
+  ret i32 %add, !dbg !16
+}
+
+declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #1
+
+attributes #1 = { nounwind readnone }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 4.0.0 (trunk 286322) (llvm/trunk 286305)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "minus.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"PIC Level", i32 2}
+!6 = !{!"clang version 4.0.0 (trunk 286322) (llvm/trunk 286305)"}
+!7 = distinct !DISubprogram(name: "inc", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10, !10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12}
+!12 = !DILocalVariable(name: "i", arg: 1, scope: !7, file: !1, line: 1, type: !10)
+!13 = !DIExpression(DW_OP_minus, 1)
+!14 = !DILocation(line: 1, column: 13, scope: !7)
+!15 = !DILocation(line: 2, column: 11, scope: !7)
+!16 = !DILocation(line: 2, column: 3, scope: !7)