Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -4377,6 +4377,10 @@ - ``DW_OP_plus, 93`` adds ``93`` to the working expression. - ``DW_OP_bit_piece, 16, 8`` specifies the offset and size (``16`` and ``8`` here, respectively) of the variable piece from the working expression. +- ``DW_OP_swap`` swaps top two stack entries. +- ``DW_OP_xderef`` provides extended dereference mechanism. The entry at the top + of the stack is treated as an address. The second stack entry is treated as an + address space identifier. .. code-block:: text @@ -4384,6 +4388,7 @@ !1 = !DIExpression(DW_OP_plus, 3) !2 = !DIExpression(DW_OP_bit_piece, 3, 7) !3 = !DIExpression(DW_OP_deref, DW_OP_plus, 3, DW_OP_bit_piece, 3, 7) + !4 = !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef) DIObjCProperty """""""""""""" Index: lib/CodeGen/AsmPrinter/DwarfExpression.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -273,6 +273,12 @@ case dwarf::DW_OP_stack_value: AddStackValue(); break; + case dwarf::DW_OP_swap: + EmitOp(dwarf::DW_OP_swap); + break; + case dwarf::DW_OP_xderef: + EmitOp(dwarf::DW_OP_xderef); + break; default: llvm_unreachable("unhandled opcode found in expression"); } Index: lib/IR/DebugInfoMetadata.cpp =================================================================== --- lib/IR/DebugInfoMetadata.cpp +++ lib/IR/DebugInfoMetadata.cpp @@ -614,10 +614,17 @@ return false; break; } + case dwarf::DW_OP_swap: { + // Must be more than one implicit element on the stack. + if (getNumElements() == 1) + return false; + break; + } case dwarf::DW_OP_constu: case dwarf::DW_OP_plus: case dwarf::DW_OP_minus: case dwarf::DW_OP_deref: + case dwarf::DW_OP_xderef: break; } } Index: test/Assembler/diexpression.ll =================================================================== --- test/Assembler/diexpression.ll +++ test/Assembler/diexpression.ll @@ -1,16 +1,18 @@ ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s ; RUN: verify-uselistorder %s -; CHECK: !named = !{!0, !1, !2, !3, !4} -!named = !{!0, !1, !2, !3, !4} +; CHECK: !named = !{!0, !1, !2, !3, !4, !5} +!named = !{!0, !1, !2, !3, !4, !5} ; CHECK: !0 = !DIExpression() ; CHECK-NEXT: !1 = !DIExpression(DW_OP_deref) ; CHECK-NEXT: !2 = !DIExpression(DW_OP_plus, 3) ; CHECK-NEXT: !3 = !DIExpression(DW_OP_LLVM_fragment, 3, 7) ; CHECK-NEXT: !4 = !DIExpression(DW_OP_deref, DW_OP_plus, 3, DW_OP_LLVM_fragment, 3, 7) +; CHECK-NEXT: !5 = !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef) !0 = !DIExpression() !1 = !DIExpression(DW_OP_deref) !2 = !DIExpression(DW_OP_plus, 3) !3 = !DIExpression(DW_OP_LLVM_fragment, 3, 7) !4 = !DIExpression(DW_OP_deref, DW_OP_plus, 3, DW_OP_LLVM_fragment, 3, 7) +!5 = !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef) Index: test/Verifier/diexpression-swap.ll =================================================================== --- /dev/null +++ test/Verifier/diexpression-swap.ll @@ -0,0 +1,5 @@ +; RUN: not opt -S < %s 2>&1 | FileCheck %s + +!named = !{!0} +; CHECK: invalid expression +!0 = !DIExpression(DW_OP_swap)