diff --git a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp --- a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp +++ b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp @@ -25,12 +25,14 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" +#include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" +#include "llvm/IR/NoFolder.h" #include "llvm/IR/PassManager.h" #include "llvm/IR/Type.h" #include "llvm/IR/Use.h" @@ -967,16 +969,16 @@ for (unsigned Ri = 0; Ri != RetCount; ++Ri) if (NewRetIdxs[Ri] != -1) { Value *V; + IRBuilder IRB(InsertPt); if (RetTypes.size() > 1) // We are still returning a struct, so extract the value from our // return value - V = ExtractValueInst::Create(NewCB, NewRetIdxs[Ri], "newret", - InsertPt); + V = IRB.CreateExtractValue(NewCB, NewRetIdxs[Ri], "newret"); else // We are now returning a single element, so just insert that V = NewCB; // Insert the value at the old position - RetVal = InsertValueInst::Create(RetVal, V, Ri, "oldret", InsertPt); + RetVal = IRB.CreateInsertValue(RetVal, V, Ri, "oldret"); } // Now, replace all uses of the old call instruction with the return // struct we built @@ -1019,6 +1021,7 @@ if (F->getReturnType() != NF->getReturnType()) for (BasicBlock &BB : *NF) if (ReturnInst *RI = dyn_cast(BB.getTerminator())) { + IRBuilder IRB(RI); Value *RetVal = nullptr; if (!NFTy->getReturnType()->isVoidTy()) { @@ -1033,14 +1036,14 @@ RetVal = UndefValue::get(NRetTy); for (unsigned RetI = 0; RetI != RetCount; ++RetI) if (NewRetIdxs[RetI] != -1) { - ExtractValueInst *EV = - ExtractValueInst::Create(OldRet, RetI, "oldret", RI); + Value *EV = IRB.CreateExtractValue(OldRet, RetI, "oldret"); + if (RetTypes.size() > 1) { // We're still returning a struct, so reinsert the value into // our new return value at the new index - RetVal = InsertValueInst::Create(RetVal, EV, NewRetIdxs[RetI], - "newret", RI); + RetVal = IRB.CreateInsertValue(RetVal, EV, NewRetIdxs[RetI], + "newret"); } else { // We are now only returning a simple value, so just return the // extracted value. diff --git a/llvm/test/DebugInfo/X86/dbgloc-insert-extract-val-instrs.ll b/llvm/test/DebugInfo/X86/dbgloc-insert-extract-val-instrs.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/X86/dbgloc-insert-extract-val-instrs.ll @@ -0,0 +1,57 @@ +;; Check that every instruction inserted by -deadargelim has a debug location. +;; The test was generated by using -debugify option. + +; RUN: opt < %s -deadargelim -S 2>&1 | FileCheck %s + +; CHECK-LABEL: fn +; CHECK: %oldret = extractvalue { i32, i32, i16 } %z, 0, !dbg ![[LOC:.*]] +; CHECK: %newret = insertvalue { i32, i32 } undef, i32 %oldret, 0, !dbg ![[LOC:.*]] +; CHECK: %oldret1 = extractvalue { i32, i32, i16 } %z, 1, !dbg ![[LOC:.*]] +; CHECK: %newret2 = insertvalue { i32, i32 } %newret, i32 %oldret1, 1, !dbg ![[LOC:.*]] + +; CHECK-LABEL: fn1 +; CHECK: %newret = extractvalue { i32, i32 } %ret, 0, !dbg ![[LOC2:.*]] +; CHECK: %oldret = insertvalue { i32, i32, i16 } undef, i32 %newret, 0, !dbg ![[LOC2:.*]] +; CHECK: %newret1 = extractvalue { i32, i32 } %ret, 1, !dbg ![[LOC2:.*]] +; CHECK: %oldret2 = insertvalue { i32, i32, i16 } %oldret, i32 %newret1, 1, !dbg ![[LOC2:.*]] + +; ModuleID = 'test.ll' +source_filename = "test.ll" + +define internal { i32, i32, i16 } @fn() !dbg !6 { + %x = insertvalue { i32, i32, i16 } undef, i32 1, 0, !dbg !8 + %y = insertvalue { i32, i32, i16 } %x, i32 2, 1, !dbg !9 + %z = insertvalue { i32, i32, i16 } %y, i16 3, 2, !dbg !10 + ret { i32, i32, i16 } %z, !dbg !11 +} + +define i32 @fn1() !dbg !12 { + %ret = call { i32, i32, i16 } @fn(), !dbg !13 + %b = extractvalue { i32, i32, i16 } %ret, 0, !dbg !14 + %c = extractvalue { i32, i32, i16 } %ret, 1, !dbg !15 + %d = add i32 %b, %c, !dbg !16 + ret i32 %d, !dbg !17 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!5} + +!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "test.ll", directory: "/") +!2 = !{} +!5 = !{i32 2, !"Debug Info Version", i32 3} +!6 = distinct !DISubprogram(name: "fn", linkageName: "fn", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) +!7 = !DISubroutineType(types: !2) +!8 = !DILocation(line: 1, column: 1, scope: !6) +!9 = !DILocation(line: 2, column: 1, scope: !6) +!10 = !DILocation(line: 3, column: 1, scope: !6) +!11 = !DILocation(line: 4, column: 1, scope: !6) +!12 = distinct !DISubprogram(name: "fn1", linkageName: "fn1", scope: null, file: !1, line: 5, type: !7, scopeLine: 5, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) +!13 = !DILocation(line: 5, column: 1, scope: !12) +!14 = !DILocation(line: 6, column: 1, scope: !12) +!15 = !DILocation(line: 7, column: 1, scope: !12) +!16 = !DILocation(line: 8, column: 1, scope: !12) +!17 = !DILocation(line: 9, column: 1, scope: !12) + +; CHECK: ![[LOC]] = !DILocation(line: 4 +; CHECK: ![[LOC2]] = !DILocation(line: 5