Index: llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp =================================================================== --- llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp +++ 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. Index: llvm/test/DebugInfo/X86/dbgloc-insert-extract-val-instrs.ll =================================================================== --- /dev/null +++ llvm/test/DebugInfo/X86/dbgloc-insert-extract-val-instrs.ll @@ -0,0 +1,229 @@ +;; Check that every instruction inserted by -deadargelim has a debug location. +;; The test was generated by using -debugify option. + +; RUN: opt < %s -deadargelim -check-debugify -S 2>&1 \ +; RUN: | FileCheck %s -check-prefix=DEBUG + +; DEBUG: %oldret = extractvalue { i16, i32 } %B, 1, !dbg ![[RET1:.*]] +; DEBUG: %oldret = extractvalue { i32, i16 } %B, 0, !dbg ![[RET2:.*]] +; DEBUG: %oldret = insertvalue { i16, i32 } undef, i32 %ret, 1, !dbg ![[RET3:.*]] +; DEBUG: %oldret = extractvalue { i32, i32, i16 } %C, 0, !dbg ![[RET4:.*]] +; DEBUG: %newret = insertvalue { i32, i32 } undef, i32 %oldret, 0, !dbg ![[RET4:.*]] +; DEBUG: %oldret1 = extractvalue { i32, i32, i16 } %C, 1, !dbg ![[RET4:.*]] +; DEBUG: %newret2 = insertvalue { i32, i32 } %newret, i32 %oldret1, 1, !dbg ![[RET4:.*]] +; DEBUG: %oldret = extractvalue { { i32 }, { i16, i16 } } %C, 0, !dbg ![[RET5:.*]] +; DEBUG: %oldret = insertvalue { i32, i16 } undef, i32 %ret, 0, !dbg ![[RET6:.*]] +; DEBUG: %newret = extractvalue { i32, i32 } %ret1, 0, !dbg ![[RET7:.*]] +; DEBUG: %oldret1 = insertvalue { i32, i32, i16 } undef, i32 %newret, 0, !dbg ![[RET7:.*]] +; DEBUG: %newret2 = extractvalue { i32, i32 } %ret1, 1, !dbg ![[RET7:.*]] +; DEBUG: %oldret3 = insertvalue { i32, i32, i16 } %oldret1, i32 %newret2, 1, !dbg ![[RET7:.*]] +; DEBUG: %oldret4 = insertvalue { { i32 }, { i16, i16 } } undef, { i32 } %ret2, 0, !dbg ![[RET8:.*]] + +; ModuleID = 'insert-extract-value.ll' +source_filename = "insert-extract-value.ll" + +define internal { i16, i32 } @test(i16 %DEADARG) !dbg !6 { + %A = insertvalue { i16, i32 } undef, i16 1, 0, !dbg !12 + call void @llvm.dbg.value(metadata { i16, i32 } %A, metadata !9, metadata !DIExpression()), !dbg !12 + %B = insertvalue { i16, i32 } %A, i32 1001, 1, !dbg !13 + call void @llvm.dbg.value(metadata { i16, i32 } %B, metadata !11, metadata !DIExpression()), !dbg !13 + ret { i16, i32 } %B, !dbg !14 +} + +define internal { i32, i16 } @test2() !dbg !15 { + %DEAD = call i16 @test4(), !dbg !21 + call void @llvm.dbg.value(metadata i16 %DEAD, metadata !17, metadata !DIExpression()), !dbg !21 + %A = insertvalue { i32, i16 } undef, i32 1, 0, !dbg !22 + call void @llvm.dbg.value(metadata { i32, i16 } %A, metadata !19, metadata !DIExpression()), !dbg !22 + %B = insertvalue { i32, i16 } %A, i16 %DEAD, 1, !dbg !23 + call void @llvm.dbg.value(metadata { i32, i16 } %B, metadata !20, metadata !DIExpression()), !dbg !23 + ret { i32, i16 } %B, !dbg !24 +} + +define internal i32 @test3(i16 %A) !dbg !25 { + %ret = call { i16, i32 } @test(i16 %A), !dbg !31 + call void @llvm.dbg.value(metadata { i16, i32 } %ret, metadata !27, metadata !DIExpression()), !dbg !31 + %DEAD = extractvalue { i16, i32 } %ret, 0, !dbg !32 + call void @llvm.dbg.value(metadata i16 %DEAD, metadata !28, metadata !DIExpression()), !dbg !32 + %LIVE = extractvalue { i16, i32 } %ret, 1, !dbg !33 + call void @llvm.dbg.value(metadata i32 %LIVE, metadata !29, metadata !DIExpression()), !dbg !33 + ret i32 %LIVE, !dbg !34 +} + +define internal i16 @test4() !dbg !35 { + call void @llvm.dbg.value(metadata i32 0, metadata !37, metadata !DIExpression()), !dbg !38 + ret i16 0, !dbg !38 +} + +define internal { i32, i32, i16 } @test5() !dbg !39 { + %A = insertvalue { i32, i32, i16 } undef, i32 1, 0, !dbg !45 + call void @llvm.dbg.value(metadata { i32, i32, i16 } %A, metadata !41, metadata !DIExpression()), !dbg !45 + %B = insertvalue { i32, i32, i16 } %A, i32 2, 1, !dbg !46 + call void @llvm.dbg.value(metadata { i32, i32, i16 } %B, metadata !43, metadata !DIExpression()), !dbg !46 + %C = insertvalue { i32, i32, i16 } %B, i16 3, 2, !dbg !47 + call void @llvm.dbg.value(metadata { i32, i32, i16 } %C, metadata !44, metadata !DIExpression()), !dbg !47 + ret { i32, i32, i16 } %C, !dbg !48 +} + +define internal { { i32 }, { i16, i16 } } @test6() !dbg !49 { + %A = insertvalue { { i32 }, { i16, i16 } } undef, i32 1, 0, 0, !dbg !54 + call void @llvm.dbg.value(metadata { { i32 }, { i16, i16 } } %A, metadata !51, metadata !DIExpression()), !dbg !54 + %B = insertvalue { { i32 }, { i16, i16 } } %A, i16 2, 1, 0, !dbg !55 + call void @llvm.dbg.value(metadata { { i32 }, { i16, i16 } } %B, metadata !52, metadata !DIExpression()), !dbg !55 + %C = insertvalue { { i32 }, { i16, i16 } } %B, i16 3, 1, 1, !dbg !56 + call void @llvm.dbg.value(metadata { { i32 }, { i16, i16 } } %C, metadata !53, metadata !DIExpression()), !dbg !56 + ret { { i32 }, { i16, i16 } } %C, !dbg !57 +} + +define i32 @main() !dbg !58 { + %ret = call { i32, i16 } @test2(), !dbg !77 + call void @llvm.dbg.value(metadata { i32, i16 } %ret, metadata !60, metadata !DIExpression()), !dbg !77 + %LIVE = extractvalue { i32, i16 } %ret, 0, !dbg !78 + call void @llvm.dbg.value(metadata i32 %LIVE, metadata !61, metadata !DIExpression()), !dbg !78 + %DEAD = extractvalue { i32, i16 } %ret, 1, !dbg !79 + call void @llvm.dbg.value(metadata i16 %DEAD, metadata !62, metadata !DIExpression()), !dbg !79 + %Y = add i32 %LIVE, -123, !dbg !80 + call void @llvm.dbg.value(metadata i32 %Y, metadata !63, metadata !DIExpression()), !dbg !80 + %LIVE2 = call i32 @test3(i16 %DEAD), !dbg !81 + call void @llvm.dbg.value(metadata i32 %LIVE2, metadata !64, metadata !DIExpression()), !dbg !81 + %Z = add i32 %LIVE2, %Y, !dbg !82 + call void @llvm.dbg.value(metadata i32 %Z, metadata !65, metadata !DIExpression()), !dbg !82 + %ret1 = call { i32, i32, i16 } @test5(), !dbg !83 + call void @llvm.dbg.value(metadata { i32, i32, i16 } %ret1, metadata !66, metadata !DIExpression()), !dbg !83 + %LIVE3 = extractvalue { i32, i32, i16 } %ret1, 0, !dbg !84 + call void @llvm.dbg.value(metadata i32 %LIVE3, metadata !67, metadata !DIExpression()), !dbg !84 + %LIVE4 = extractvalue { i32, i32, i16 } %ret1, 1, !dbg !85 + call void @llvm.dbg.value(metadata i32 %LIVE4, metadata !68, metadata !DIExpression()), !dbg !85 + %DEAD2 = extractvalue { i32, i32, i16 } %ret1, 2, !dbg !86 + call void @llvm.dbg.value(metadata i16 %DEAD2, metadata !69, metadata !DIExpression()), !dbg !86 + %V = add i32 %LIVE3, %LIVE4, !dbg !87 + call void @llvm.dbg.value(metadata i32 %V, metadata !70, metadata !DIExpression()), !dbg !87 + %W = add i32 %Z, %V, !dbg !88 + call void @llvm.dbg.value(metadata i32 %W, metadata !71, metadata !DIExpression()), !dbg !88 + %ret2 = call { { i32 }, { i16, i16 } } @test6(), !dbg !89 + call void @llvm.dbg.value(metadata { { i32 }, { i16, i16 } } %ret2, metadata !72, metadata !DIExpression()), !dbg !89 + %LIVE5 = extractvalue { { i32 }, { i16, i16 } } %ret2, 0, 0, !dbg !90 + call void @llvm.dbg.value(metadata i32 %LIVE5, metadata !73, metadata !DIExpression()), !dbg !90 + %DEAD3 = extractvalue { { i32 }, { i16, i16 } } %ret2, 1, 0, !dbg !91 + call void @llvm.dbg.value(metadata i16 %DEAD3, metadata !74, metadata !DIExpression()), !dbg !91 + %DEAD4 = extractvalue { { i32 }, { i16, i16 } } %ret2, 1, 1, !dbg !92 + call void @llvm.dbg.value(metadata i16 %DEAD4, metadata !75, metadata !DIExpression()), !dbg !92 + %Q = add i32 %W, %LIVE5, !dbg !93 + call void @llvm.dbg.value(metadata i32 %Q, metadata !76, metadata !DIExpression()), !dbg !93 + ret i32 %Q, !dbg !94 +} + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #0 + +attributes #0 = { nounwind readnone speculatable willreturn } + +!llvm.dbg.cu = !{!0} +!llvm.debugify = !{!3, !4} +!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: "insert-extract-value.ll", directory: "/") +!2 = !{} +!3 = !{i32 38} +!4 = !{i32 32} +!5 = !{i32 2, !"Debug Info Version", i32 3} +!6 = distinct !DISubprogram(name: "test", linkageName: "test", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8) +!7 = !DISubroutineType(types: !2) +!8 = !{!9, !11} +!9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10) +!10 = !DIBasicType(name: "ty64", size: 64, encoding: DW_ATE_unsigned) +!11 = !DILocalVariable(name: "2", scope: !6, file: !1, line: 2, type: !10) +!12 = !DILocation(line: 1, column: 1, scope: !6) +!13 = !DILocation(line: 2, column: 1, scope: !6) +!14 = !DILocation(line: 3, column: 1, scope: !6) +!15 = distinct !DISubprogram(name: "test2", linkageName: "test2", scope: null, file: !1, line: 4, type: !7, scopeLine: 4, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !16) +!16 = !{!17, !19, !20} +!17 = !DILocalVariable(name: "3", scope: !15, file: !1, line: 4, type: !18) +!18 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned) +!19 = !DILocalVariable(name: "4", scope: !15, file: !1, line: 5, type: !10) +!20 = !DILocalVariable(name: "5", scope: !15, file: !1, line: 6, type: !10) +!21 = !DILocation(line: 4, column: 1, scope: !15) +!22 = !DILocation(line: 5, column: 1, scope: !15) +!23 = !DILocation(line: 6, column: 1, scope: !15) +!24 = !DILocation(line: 7, column: 1, scope: !15) +!25 = distinct !DISubprogram(name: "test3", linkageName: "test3", scope: null, file: !1, line: 8, type: !7, scopeLine: 8, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !26) +!26 = !{!27, !28, !29} +!27 = !DILocalVariable(name: "6", scope: !25, file: !1, line: 8, type: !10) +!28 = !DILocalVariable(name: "7", scope: !25, file: !1, line: 9, type: !18) +!29 = !DILocalVariable(name: "8", scope: !25, file: !1, line: 10, type: !30) +!30 = !DIBasicType(name: "ty32", size: 32, encoding: DW_ATE_unsigned) +!31 = !DILocation(line: 8, column: 1, scope: !25) +!32 = !DILocation(line: 9, column: 1, scope: !25) +!33 = !DILocation(line: 10, column: 1, scope: !25) +!34 = !DILocation(line: 11, column: 1, scope: !25) +!35 = distinct !DISubprogram(name: "test4", linkageName: "test4", scope: null, file: !1, line: 12, type: !7, scopeLine: 12, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !36) +!36 = !{!37} +!37 = !DILocalVariable(name: "9", scope: !35, file: !1, line: 12, type: !30) +!38 = !DILocation(line: 12, column: 1, scope: !35) +!39 = distinct !DISubprogram(name: "test5", linkageName: "test5", scope: null, file: !1, line: 13, type: !7, scopeLine: 13, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !40) +!40 = !{!41, !43, !44} +!41 = !DILocalVariable(name: "10", scope: !39, file: !1, line: 13, type: !42) +!42 = !DIBasicType(name: "ty96", size: 96, encoding: DW_ATE_unsigned) +!43 = !DILocalVariable(name: "11", scope: !39, file: !1, line: 14, type: !42) +!44 = !DILocalVariable(name: "12", scope: !39, file: !1, line: 15, type: !42) +!45 = !DILocation(line: 13, column: 1, scope: !39) +!46 = !DILocation(line: 14, column: 1, scope: !39) +!47 = !DILocation(line: 15, column: 1, scope: !39) +!48 = !DILocation(line: 16, column: 1, scope: !39) +!49 = distinct !DISubprogram(name: "test6", linkageName: "test6", scope: null, file: !1, line: 17, type: !7, scopeLine: 17, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !50) +!50 = !{!51, !52, !53} +!51 = !DILocalVariable(name: "13", scope: !49, file: !1, line: 17, type: !10) +!52 = !DILocalVariable(name: "14", scope: !49, file: !1, line: 18, type: !10) +!53 = !DILocalVariable(name: "15", scope: !49, file: !1, line: 19, type: !10) +!54 = !DILocation(line: 17, column: 1, scope: !49) +!55 = !DILocation(line: 18, column: 1, scope: !49) +!56 = !DILocation(line: 19, column: 1, scope: !49) +!57 = !DILocation(line: 20, column: 1, scope: !49) +!58 = distinct !DISubprogram(name: "main", linkageName: "main", scope: null, file: !1, line: 21, type: !7, scopeLine: 21, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !59) +!59 = !{!60, !61, !62, !63, !64, !65, !66, !67, !68, !69, !70, !71, !72, !73, !74, !75, !76} +!60 = !DILocalVariable(name: "16", scope: !58, file: !1, line: 21, type: !10) +!61 = !DILocalVariable(name: "17", scope: !58, file: !1, line: 22, type: !30) +!62 = !DILocalVariable(name: "18", scope: !58, file: !1, line: 23, type: !18) +!63 = !DILocalVariable(name: "19", scope: !58, file: !1, line: 24, type: !30) +!64 = !DILocalVariable(name: "20", scope: !58, file: !1, line: 25, type: !30) +!65 = !DILocalVariable(name: "21", scope: !58, file: !1, line: 26, type: !30) +!66 = !DILocalVariable(name: "22", scope: !58, file: !1, line: 27, type: !42) +!67 = !DILocalVariable(name: "23", scope: !58, file: !1, line: 28, type: !30) +!68 = !DILocalVariable(name: "24", scope: !58, file: !1, line: 29, type: !30) +!69 = !DILocalVariable(name: "25", scope: !58, file: !1, line: 30, type: !18) +!70 = !DILocalVariable(name: "26", scope: !58, file: !1, line: 31, type: !30) +!71 = !DILocalVariable(name: "27", scope: !58, file: !1, line: 32, type: !30) +!72 = !DILocalVariable(name: "28", scope: !58, file: !1, line: 33, type: !10) +!73 = !DILocalVariable(name: "29", scope: !58, file: !1, line: 34, type: !30) +!74 = !DILocalVariable(name: "30", scope: !58, file: !1, line: 35, type: !18) +!75 = !DILocalVariable(name: "31", scope: !58, file: !1, line: 36, type: !18) +!76 = !DILocalVariable(name: "32", scope: !58, file: !1, line: 37, type: !30) +!77 = !DILocation(line: 21, column: 1, scope: !58) +!78 = !DILocation(line: 22, column: 1, scope: !58) +!79 = !DILocation(line: 23, column: 1, scope: !58) +!80 = !DILocation(line: 24, column: 1, scope: !58) +!81 = !DILocation(line: 25, column: 1, scope: !58) +!82 = !DILocation(line: 26, column: 1, scope: !58) +!83 = !DILocation(line: 27, column: 1, scope: !58) +!84 = !DILocation(line: 28, column: 1, scope: !58) +!85 = !DILocation(line: 29, column: 1, scope: !58) +!86 = !DILocation(line: 30, column: 1, scope: !58) +!87 = !DILocation(line: 31, column: 1, scope: !58) +!88 = !DILocation(line: 32, column: 1, scope: !58) +!89 = !DILocation(line: 33, column: 1, scope: !58) +!90 = !DILocation(line: 34, column: 1, scope: !58) +!91 = !DILocation(line: 35, column: 1, scope: !58) +!92 = !DILocation(line: 36, column: 1, scope: !58) +!93 = !DILocation(line: 37, column: 1, scope: !58) +!94 = !DILocation(line: 38, column: 1, scope: !58) + +; --- synthetic DILocations: +; DEBUG-DAG: ![[RET1]] = !DILocation(line: 3, column: 1 +; DEBUG-DAG: ![[RET2]] = !DILocation(line: 7, column: 1 +; DEBUG-DAG: ![[RET3]] = !DILocation(line: 8, column: 1 +; DEBUG-DAG: ![[RET4]] = !DILocation(line: 16, column: 1 +; DEBUG-DAG: ![[RET5]] = !DILocation(line: 20, column: 1 +; DEBUG-DAG: ![[RET6]] = !DILocation(line: 21, column: 1 +; DEBUG-DAG: ![[RET7]] = !DILocation(line: 27, column: 1 +; DEBUG-DAG: ![[RET8]] = !DILocation(line: 33, column: 1