Index: lib/Transforms/Scalar/Reassociate.cpp =================================================================== --- lib/Transforms/Scalar/Reassociate.cpp +++ lib/Transforms/Scalar/Reassociate.cpp @@ -2097,6 +2097,20 @@ ReassociateExpression(BO); } +static bool canDropDebugLoc(Instruction *I) { + if (CallInst *CI = dyn_cast(I)) { + CallSite CS = CallSite(CI); + // Inlinable callsites of debug-info-bearing functions in + // debug-info-bearing functions must have debug locations + // attached to them. See rationale in the IR verifier. + if (CI->getFunction()->getSubprogram() && CS.getCalledFunction() && + CS.getCalledFunction()->getSubprogram()) + return false; + } + + return true; +} + void ReassociatePass::ReassociateExpression(BinaryOperator *I) { // First, walk the expression tree, linearizing the tree, collecting the // operand information. @@ -2131,7 +2145,8 @@ DEBUG(dbgs() << "Reassoc to scalar: " << *V << '\n'); I->replaceAllUsesWith(V); if (Instruction *VI = dyn_cast(V)) - VI->setDebugLoc(I->getDebugLoc()); + if (I->getDebugLoc() || canDropDebugLoc(VI)) + VI->setDebugLoc(I->getDebugLoc()); RedoInsts.insert(I); ++NumAnnihil; return; Index: test/Transforms/Reassociate/keep-inlinable-fn-dbgloc.ll =================================================================== --- /dev/null +++ test/Transforms/Reassociate/keep-inlinable-fn-dbgloc.ll @@ -0,0 +1,32 @@ +;RUN: opt -S -reassociate -disable-output < %s + +; Inlinable callsites of debug-info-bearing functions in +; debug-info-bearing functions must have debug locations +; attached to them. Therefore, do not drop debug locations for +; such instructions when reassociating expressions. +; +; This would trigger an "inlinable function call in a function with " +; "debug info must have a !dbg location" error in the verifier otherwise. + +define i16 @fn1() !dbg !3 { + ret i16 undef +} + +define void @fn2() !dbg !6 { + %inlinable_call = call i16 @fn1(), !dbg !7 + %dbgless_instruction = or i16 %inlinable_call, 0 + store i16 %dbgless_instruction, i16* undef, align 1 + unreachable +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 6.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly) +!1 = !DIFile(filename: "foo.c", directory: "/") +!2 = !{i32 2, !"Debug Info Version", i32 3} +!3 = distinct !DISubprogram(name: "fn1", scope: !1, file: !1, line: 2, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: true, unit: !0) +!4 = !DISubroutineType(types: !5) +!5 = !{} +!6 = distinct !DISubprogram(name: "fn2", scope: !1, file: !1, line: 3, type: !4, isLocal: false, isDefinition: true, scopeLine: 3, isOptimized: true, unit: !0) +!7 = !DILocation(line: 7, column: 10, scope: !6)