[llvm] r278371 - Improve virtual register handling when computing debug information

Benjamin Kramer via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 12 03:21:49 PDT 2016


I get random crashes on dbgvalue.ll, and it crashes consistently with
asan and valgrind, stack trace below. I disabled the test for now in
r278495, can you take a look?

==26942==ERROR: AddressSanitizer: SEGV on unknown address
0x000000000000 (pc 0x000005133f5a bp 0x7ffc45c1e790 sp 0x7ffc45c1e6a0
T0)
==26942==The signal is caused by a READ memory access.
==26942==Hint: address points to the zero page.
    #0 0x5133f59 in
llvm::MCRegisterInfo::DwarfLLVMRegPair::operator<(llvm::MCRegisterInfo::DwarfLLVMRegPair)
const llvm/include/llvm/MC/MCRegisterInfo.h:145:57
    #1 0x5133696 in llvm::MCRegisterInfo::DwarfLLVMRegPair const*
std::lower_bound<llvm::MCRegisterInfo::DwarfLLVMRegPair const*,
llvm::MCRegisterInfo::DwarfLLVMRegPair>(llvm::MCRegisterInfo::DwarfLLVMRegPair
const*, llvm::MCRegisterInfo::DwarfLLVMRegPair const*,
llvm::MCRegisterInfo::DwarfLLVMRegPair const&)
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_algobase.h:965:18
    #2 0x5132755 in llvm::MCRegisterInfo::getDwarfRegNum(unsigned int,
bool) const llvm/lib/MC/MCRegisterInfo.cpp:66:31
    #3 0x3e933c1 in
llvm::DwarfExpression::AddMachineRegPiece(llvm::TargetRegisterInfo
const&, unsigned int, unsigned int, unsigned int)
llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp:92:17
    #4 0x3eaeb6b in llvm::DwarfUnit::addRegisterOpPiece(llvm::DIELoc&,
unsigned int, unsigned int, unsigned int)
llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp:371:8
    #5 0x3ff64c7 in llvm::DwarfCompileUnit::addAddress(llvm::DIE&,
llvm::dwarf::Attribute, llvm::MachineLocation const&)
llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:756:16
    #6 0x3ff6293 in
llvm::DwarfCompileUnit::updateSubprogramScopeDIE(llvm::DISubprogram
const*) llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:307:7
    #7 0x3ffbed0 in
llvm::DwarfCompileUnit::constructSubprogramScopeDIE(llvm::LexicalScope*)
llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp:596:19
    #8 0x3e11e02 in
llvm::DwarfDebug::endFunction(llvm::MachineFunction const*)
llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp:1156:9
    #9 0x3da5a79 in llvm::AsmPrinter::EmitFunctionBody()
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:977:17
    #10 0xae59a7 in
llvm::AsmPrinter::runOnMachineFunction(llvm::MachineFunction&)
llvm/include/llvm/CodeGen/AsmPrinter.h:209:5
    #11 0x383382f in (anonymous
namespace)::WebAssemblyAsmPrinter::runOnMachineFunction(llvm::MachineFunction&)
llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp:63:24
    #12 0x439c3ae in
llvm::MachineFunctionPass::runOnFunction(llvm::Function&)
llvm/lib/CodeGen/MachineFunctionPass.cpp:60:13
    #13 0x4e187f4 in
llvm::FPPassManager::runOnFunction(llvm::Function&)
llvm/lib/IR/LegacyPassManager.cpp:1522:27
    #14 0x4e18f09 in llvm::FPPassManager::runOnModule(llvm::Module&)
llvm/lib/IR/LegacyPassManager.cpp:1543:16
    #15 0x4e1a0eb in (anonymous
namespace)::MPPassManager::runOnModule(llvm::Module&)
llvm/lib/IR/LegacyPassManager.cpp:1599:27
    #16 0x4e193f6 in llvm::legacy::PassManagerImpl::run(llvm::Module&)
llvm/lib/IR/LegacyPassManager.cpp:1702:44
    #17 0x4e1aba8 in llvm::legacy::PassManager::run(llvm::Module&)
llvm/lib/IR/LegacyPassManager.cpp:1733:14
    #18 0xa74420 in compileModule(char**, llvm::LLVMContext&)
llvm/tools/llc/llc.cpp:505:8
    #19 0xa7097f in main llvm/tools/llc/llc.cpp:273:22
    #20 0x7faccec3cf44 in __libc_start_main eglibc-2.19/csu/libc-start.c:287
    #21 0x99b244 in _start (llvm-asan/bin/llc+0x99b244)

On Thu, Aug 11, 2016 at 7:52 PM, Dominic Chen via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: ddcc
> Date: Thu Aug 11 12:52:40 2016
> New Revision: 278371
>
> URL: http://llvm.org/viewvc/llvm-project?rev=278371&view=rev
> Log:
> Improve virtual register handling when computing debug information
>
> Summary: Some backends, like WebAssembly, use virtual registers instead of physical registers. This crashes the DbgValueHistoryCalculator pass, which assumes that all registers are physical. Instead, skip virtual registers when iterating aliases, and assume that they are clobbered.
>
> Reviewers: dexonsmith, dschuff, aprantl
>
> Subscribers: yurydelendik, llvm-commits, jfb, sunfish
>
> Differential Revision: https://reviews.llvm.org/D22590
>
> Added:
>     llvm/trunk/test/CodeGen/WebAssembly/dbgvalue.ll
> Modified:
>     llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp?rev=278371&r1=278370&r2=278371&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp Thu Aug 11 12:52:40 2016
> @@ -31,7 +31,7 @@ static unsigned isDescribedByReg(const M
>    assert(MI.isDebugValue());
>    assert(MI.getNumOperands() == 4);
>    // If location of variable is described using a register (directly or
> -  // indirecltly), this register is always a first operand.
> +  // indirectly), this register is always a first operand.
>    return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : 0;
>  }
>
> @@ -164,7 +164,9 @@ static void collectChangingRegs(const Ma
>        // Look for register defs and register masks. Register masks are
>        // typically on calls and they clobber everything not in the mask.
>        for (const MachineOperand &MO : MI.operands()) {
> -        if (MO.isReg() && MO.isDef() && MO.getReg()) {
> +        // Skip virtual registers since they are handled by the parent.
> +        if (MO.isReg() && MO.isDef() && MO.getReg() &&
> +            !TRI->isVirtualRegister(MO.getReg())) {
>            for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid();
>                 ++AI)
>              Regs.set(*AI);
> @@ -192,12 +194,18 @@ void llvm::calculateDbgValueHistory(cons
>          // some variables.
>          for (const MachineOperand &MO : MI.operands()) {
>            if (MO.isReg() && MO.isDef() && MO.getReg()) {
> +            // If this is a virtual register, only clobber it since it doesn't
> +            // have aliases.
> +            if (TRI->isVirtualRegister(MO.getReg()))
> +              clobberRegisterUses(RegVars, MO.getReg(), Result, MI);
>              // If this is a register def operand, it may end a debug value
>              // range.
> -            for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid();
> -                 ++AI)
> -              if (ChangingRegs.test(*AI))
> -                clobberRegisterUses(RegVars, *AI, Result, MI);
> +            else {
> +              for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid();
> +                   ++AI)
> +                if (ChangingRegs.test(*AI))
> +                  clobberRegisterUses(RegVars, *AI, Result, MI);
> +            }
>            } else if (MO.isRegMask()) {
>              // If this is a register mask operand, clobber all debug values in
>              // non-CSRs.
> @@ -238,7 +246,8 @@ void llvm::calculateDbgValueHistory(cons
>      if (!MBB.empty() && &MBB != &MF->back()) {
>        for (auto I = RegVars.begin(), E = RegVars.end(); I != E;) {
>          auto CurElem = I++; // CurElem can be erased below.
> -        if (ChangingRegs.test(CurElem->first))
> +        if (TRI->isVirtualRegister(CurElem->first) ||
> +            ChangingRegs.test(CurElem->first))
>            clobberRegisterUses(RegVars, CurElem, Result, MBB.back());
>        }
>      }
>
> Added: llvm/trunk/test/CodeGen/WebAssembly/dbgvalue.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/dbgvalue.ll?rev=278371&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/WebAssembly/dbgvalue.ll (added)
> +++ llvm/trunk/test/CodeGen/WebAssembly/dbgvalue.ll Thu Aug 11 12:52:40 2016
> @@ -0,0 +1,69 @@
> +; RUN: llc < %s -O0 -verify-machineinstrs -mtriple=wasm32-unknown-unknown | FileCheck %s
> +; CHECK: BB#0
> +; CHECK: #DEBUG_VALUE: usage:self <- %vreg4
> +; CHECK: BB#1
> +; CHECK: DW_TAG_variable
> +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
> +target triple = "wasm32-unknown-unknown"
> +
> +%0 = type opaque
> +
> + at key = external local_unnamed_addr global [15 x i8], align 1
> + at .str = external unnamed_addr constant [33 x i8], align 1
> +
> +; Function Attrs: nounwind
> +define internal i32 @0(i8*) local_unnamed_addr !dbg !14 !type !22 {
> +  tail call void @llvm.dbg.value(metadata i8* %0, i64 0, metadata !21, metadata !23), !dbg !24
> +  %2 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([33 x i8], [33 x i8]* @.str, i32 0, i32 0), i8* %0), !dbg !25
> +  br i1 1, label %a, label %b
> +a:
> +  %3 = add i32 %2, %2
> +  br label %c
> +
> +b:
> +  %4 = sub i32 %2, %2
> +  br label %c
> +
> +c:
> +  %5 = phi i32 [ %3, %a ], [ %4, %b ]
> +  %6 = add i32 ptrtoint (i32 (i8*)* @0 to i32), %5
> +  ret i32 %6, !dbg !26
> +}
> +
> +; Function Attrs: nounwind
> +declare i32 @printf(i8* nocapture readonly, ...) local_unnamed_addr
> +
> +; Function Attrs: nounwind readnone
> +declare void @llvm.dbg.value(metadata, i64, metadata, metadata)
> +
> +!llvm.dbg.cu = !{!0}
> +!llvm.module.flags = !{!11, !12}
> +!llvm.ident = !{!13}
> +
> +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0 (trunk 273884) (llvm/trunk 273897)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3)
> +!1 = !DIFile(filename: "crash.c", directory: "wasm/tests")
> +!2 = !{}
> +!3 = !{!4}
> +!4 = distinct !DIGlobalVariable(name: "key", scope: !0, file: !1, line: 7, type: !5, isLocal: false, isDefinition: true, variable: [15 x i8]* @key)
> +!5 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 120, align: 8, elements: !9)
> +!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "uint8_t", file: !7, line: 185, baseType: !8)
> +!7 = !DIFile(filename: "wasm/emscripten/system/include/libc/bits/alltypes.h", directory: "wasm/tests")
> +!8 = !DIBasicType(name: "unsigned char", size: 8, align: 8, encoding: DW_ATE_unsigned_char)
> +!9 = !{!10}
> +!10 = !DISubrange(count: 15)
> +!11 = !{i32 2, !"Dwarf Version", i32 4}
> +!12 = !{i32 2, !"Debug Info Version", i32 3}
> +!13 = !{!"clang version 3.9.0 (trunk 273884) (llvm/trunk 273897)"}
> +!14 = distinct !DISubprogram(name: "usage", scope: !1, file: !1, line: 15, type: !15, isLocal: false, isDefinition: true, scopeLine: 15, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !20)
> +!15 = !DISubroutineType(types: !16)
> +!16 = !{!17, !18}
> +!17 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
> +!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 32, align: 32)
> +!19 = !DIBasicType(name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char)
> +!20 = !{!21}
> +!21 = !DILocalVariable(name: "self", arg: 1, scope: !14, file: !1, line: 15, type: !18)
> +!22 = !{i64 0, !"_ZTSFiPcE"}
> +!23 = !DIExpression()
> +!24 = !DILocation(line: 15, column: 17, scope: !14)
> +!25 = !DILocation(line: 16, column: 3, scope: !14)
> +!26 = !DILocation(line: 17, column: 3, scope: !14)
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list