#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"
for (unsigned Ri = 0; Ri != RetCount; ++Ri)
if (NewRetIdxs[Ri] != -1) {
Value *V;
+ IRBuilder<NoFolder> 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
if (F->getReturnType() != NF->getReturnType())
for (BasicBlock &BB : *NF)
if (ReturnInst *RI = dyn_cast<ReturnInst>(BB.getTerminator())) {
+ IRBuilder<NoFolder> IRB(RI);
Value *RetVal = nullptr;
if (!NFTy->getReturnType()->isVoidTy()) {
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.
--- /dev/null
+;; 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