diff --git a/llvm/docs/AMDGPUUsage.rst b/llvm/docs/AMDGPUUsage.rst
--- a/llvm/docs/AMDGPUUsage.rst
+++ b/llvm/docs/AMDGPUUsage.rst
@@ -2794,21 +2794,21 @@
                                             of
                                             Operands
    ================================== ===== ======== ===============================
-   DW_OP_LLVM_form_aspace_address     0xe7     0
-   DW_OP_LLVM_push_lane               0xea     0
-   DW_OP_LLVM_offset                  0xe9     0
-   DW_OP_LLVM_offset_uconst           *TBD*    1     ULEB128 byte displacement
-   DW_OP_LLVM_bit_offset              *TBD*    0
-   DW_OP_LLVM_call_frame_entry_reg    *TBD*    1     ULEB128 register number
-   DW_OP_LLVM_undefined               *TBD*    0
-   DW_OP_LLVM_aspace_bregx            *TBD*    2     ULEB128 register number,
+   DW_OP_LLVM_form_aspace_address     0xe1     0
+   DW_OP_LLVM_push_lane               0xe2     0
+   DW_OP_LLVM_offset                  0xe3     0
+   DW_OP_LLVM_offset_uconst           0xe4     1     ULEB128 byte displacement
+   DW_OP_LLVM_bit_offset              0xe5     0
+   DW_OP_LLVM_call_frame_entry_reg    0xe6     1     ULEB128 register number
+   DW_OP_LLVM_undefined               0xe7     0
+   DW_OP_LLVM_aspace_bregx            0xe8     2     ULEB128 register number,
                                                      ULEB128 byte displacement
-   DW_OP_LLVM_aspace_implicit_pointer *TBD*    2     4- or 8-byte offset of DIE,
+   DW_OP_LLVM_aspace_implicit_pointer 0xe9     2     4- or 8-byte offset of DIE,
                                                      SLEB128 byte displacement
-   DW_OP_LLVM_piece_end               *TBD*    0
-   DW_OP_LLVM_extend                  *TBD*    2     ULEB128 bit size,
+   DW_OP_LLVM_piece_end               0xea     0
+   DW_OP_LLVM_extend                  0xeb     2     ULEB128 bit size,
                                                      ULEB128 count
-   DW_OP_LLVM_select_bit_piece        *TBD*    2     ULEB128 bit size,
+   DW_OP_LLVM_select_bit_piece        0xec     2     ULEB128 bit size,
                                                      ULEB128 count
    ================================== ===== ======== ===============================
 
diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.def b/llvm/include/llvm/BinaryFormat/Dwarf.def
--- a/llvm/include/llvm/BinaryFormat/Dwarf.def
+++ b/llvm/include/llvm/BinaryFormat/Dwarf.def
@@ -665,6 +665,20 @@
 // Extensions for Fission proposal.
 HANDLE_DW_OP(0xfb, GNU_addr_index, 0, GNU)
 HANDLE_DW_OP(0xfc, GNU_const_index, 0, GNU)
+// Extensions for AMDGPU proposal.
+// FIXME: These collide with some HP and PGI vendor extensions.
+HANDLE_DW_OP(0xe1, LLVM_form_aspace_address, 4, LLVM)
+HANDLE_DW_OP(0xe2, LLVM_push_lane, 4, LLVM)
+HANDLE_DW_OP(0xe3, LLVM_offset, 4, LLVM)
+HANDLE_DW_OP(0xe4, LLVM_offset_uconst, 4, LLVM)
+HANDLE_DW_OP(0xe5, LLVM_bit_offset, 4, LLVM)
+HANDLE_DW_OP(0xe6, LLVM_call_frame_entry_reg, 4, LLVM)
+HANDLE_DW_OP(0xe7, LLVM_undefined, 4, LLVM)
+HANDLE_DW_OP(0xe8, LLVM_aspace_bregx, 4, LLVM)
+HANDLE_DW_OP(0xe9, LLVM_aspace_implicit_pointer, 4, LLVM)
+HANDLE_DW_OP(0xea, LLVM_piece_end, 4, LLVM)
+HANDLE_DW_OP(0xeb, LLVM_extend, 4, LLVM)
+HANDLE_DW_OP(0xec, LLVM_select_bit_piece, 4, LLVM)
 
 // DWARF languages.
 HANDLE_DW_LANG(0x0001, C89, 0, 2, DWARF)
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
--- a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
@@ -100,6 +100,21 @@
   Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB);
   Descriptions[DW_OP_GNU_const_index] = Desc(Op::Dwarf4, Op::SizeLEB);
   Descriptions[DW_OP_GNU_entry_value] = Desc(Op::Dwarf4, Op::SizeLEB);
+  Descriptions[DW_OP_LLVM_form_aspace_address] = Desc(Op::Dwarf4);
+  Descriptions[DW_OP_LLVM_push_lane] = Desc(Op::Dwarf4);
+  Descriptions[DW_OP_LLVM_offset] = Desc(Op::Dwarf4);
+  Descriptions[DW_OP_LLVM_offset_uconst] = Desc(Op::Dwarf4, Op::SizeLEB);
+  Descriptions[DW_OP_LLVM_bit_offset] = Desc(Op::Dwarf4);
+  Descriptions[DW_OP_LLVM_call_frame_entry_reg] = Desc(Op::Dwarf4, Op::SizeLEB);
+  Descriptions[DW_OP_LLVM_undefined] = Desc(Op::Dwarf4);
+  Descriptions[DW_OP_LLVM_aspace_bregx] =
+      Desc(Op::Dwarf4, Op::SizeLEB, Op::SizeLEB);
+  Descriptions[DW_OP_LLVM_aspace_implicit_pointer] =
+      Desc(Op::Dwarf4, Op::SizeRefAddr, Op::SignedSizeLEB);
+  Descriptions[DW_OP_LLVM_piece_end] = Desc(Op::Dwarf4);
+  Descriptions[DW_OP_LLVM_extend] = Desc(Op::Dwarf4, Op::SizeLEB, Op::SizeLEB);
+  Descriptions[DW_OP_LLVM_select_bit_piece] =
+      Desc(Op::Dwarf4, Op::SizeLEB, Op::SizeLEB);
 
   Descriptions[DW_OP_convert] = Desc(Op::Dwarf5, Op::BaseTypeRef);
   Descriptions[DW_OP_entry_value] = Desc(Op::Dwarf5, Op::SizeLEB);
@@ -213,8 +228,10 @@
   unsigned OpNum = 0;
 
   if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
-      Opcode == DW_OP_regval_type)
+      Opcode == DW_OP_regval_type || Opcode == DW_OP_LLVM_aspace_bregx)
     DwarfRegNum = Operands[OpNum++];
+  else if (Opcode == DW_OP_LLVM_call_frame_entry_reg)
+    DwarfRegNum = Operands[OpNum];
   else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx)
     DwarfRegNum = Opcode - DW_OP_breg0;
   else
@@ -223,7 +240,7 @@
   if (Optional<unsigned> LLVMRegNum = MRI->getLLVMRegNum(DwarfRegNum, isEH)) {
     if (const char *RegName = MRI->getName(*LLVMRegNum)) {
       if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
-          Opcode == DW_OP_bregx)
+          Opcode == DW_OP_bregx || Opcode == DW_OP_LLVM_aspace_bregx)
         OS << format(" %s%+" PRId64, RegName, Operands[OpNum]);
       else
         OS << ' ' << RegName;
@@ -254,7 +271,9 @@
   if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
       (Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) ||
       Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
-      Opcode == DW_OP_regval_type)
+      Opcode == DW_OP_regval_type ||
+      Opcode == DW_OP_LLVM_call_frame_entry_reg ||
+      Opcode == DW_OP_LLVM_aspace_bregx)
     if (prettyPrintRegisterOp(U, OS, Opcode, Operands, RegInfo, isEH))
       return true;
 
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/amdgpu_proposal.s b/llvm/test/tools/llvm-dwarfdump/X86/amdgpu_proposal.s
new file mode 100644
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/amdgpu_proposal.s
@@ -0,0 +1,40 @@
+# RUN: llvm-mc %s -filetype=obj -triple=i686-pc-linux -o %t
+# RUN: llvm-dwarfdump -v %t | FileCheck %s
+
+# Check that we can decode new ops described at
+# llvm/docs/AMDGPUUsage.rst#expression-operation-encodings
+
+# FIXME: Is there a better approach than using `DW_CFA_expression reg0 <op>`?
+
+# CHECK:      .eh_frame contents:
+# CHECK:      FDE
+
+foo:
+ .cfi_startproc
+ # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_form_aspace_address
+ .cfi_escape 0x10, 0x00, 0x01, 0xe1
+ # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_push_lane
+ .cfi_escape 0x10, 0x00, 0x01, 0xe2
+ # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_offset
+ .cfi_escape 0x10, 0x00, 0x01, 0xe3
+ # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_offset_uconst 0x0
+ .cfi_escape 0x10, 0x00, 0x02, 0xe4, 0x00
+ # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_bit_offset
+ .cfi_escape 0x10, 0x00, 0x01, 0xe5
+ # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_call_frame_entry_reg EAX
+ .cfi_escape 0x10, 0x00, 0x02, 0xe6, 0x00
+ # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_undefined
+ .cfi_escape 0x10, 0x00, 0x01, 0xe7
+ # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_aspace_bregx EAX+2
+ .cfi_escape 0x10, 0x00, 0x03, 0xe8, 0x0, 0x2
+ # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_aspace_implicit_pointer 0x1 +2
+ .cfi_escape 0x10, 0x00, 0x06, 0xe9, 0x1, 0x0, 0x0, 0x0, 0x2
+ # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_piece_end
+ .cfi_escape 0x10, 0x00, 0x01, 0xea
+ # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_extend 0x0 0x0
+ .cfi_escape 0x10, 0x00, 0x03, 0xeb, 0x0, 0x0
+ # CHECK-NEXT: DW_CFA_expression: reg0 DW_OP_LLVM_select_bit_piece 0x0 0x0
+ .cfi_escape 0x10, 0x00, 0x03, 0xec, 0x0, 0x0
+ .cfi_endproc
+
+# CHECK-NEXT:     DW_CFA_nop: