Index: llvm/lib/Transforms/IPO/ArgumentPromotion.cpp =================================================================== --- llvm/lib/Transforms/IPO/ArgumentPromotion.cpp +++ llvm/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -58,11 +58,13 @@ #include "llvm/IR/DataLayout.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/Metadata.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" @@ -242,6 +244,7 @@ assert(CS.getCalledFunction() == F); Instruction *Call = CS.getInstruction(); const AttributeList &CallPAL = CS.getAttributes(); + IRBuilder IRB(Call); // Loop over the operands, inserting GEP and loads in the caller as // appropriate. @@ -260,11 +263,11 @@ ConstantInt::get(Type::getInt32Ty(F->getContext()), 0), nullptr}; for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { Idxs[1] = ConstantInt::get(Type::getInt32Ty(F->getContext()), i); - Value *Idx = GetElementPtrInst::Create( - STy, *AI, Idxs, (*AI)->getName() + "." + Twine(i), Call); + auto *Idx = + IRB.CreateGEP(STy, *AI, Idxs, (*AI)->getName() + "." + Twine(i)); // TODO: Tell AA about the new values? - Args.push_back(new LoadInst(STy->getElementType(i), Idx, - Idx->getName() + ".val", Call)); + Args.push_back(IRB.CreateLoad(STy->getElementType(i), Idx, + Idx->getName() + ".val")); ArgAttrVec.push_back(AttributeSet()); } } else if (!I->use_empty()) { @@ -294,14 +297,13 @@ ElTy = cast(ElTy)->getTypeAtIndex(II); } // And create a GEP to extract those indices. - V = GetElementPtrInst::Create(ArgIndex.first, V, Ops, - V->getName() + ".idx", Call); + V = IRB.CreateGEP(ArgIndex.first, V, Ops, V->getName() + ".idx"); Ops.clear(); } // Since we're replacing a load make sure we take the alignment // of the previous load. LoadInst *newLoad = - new LoadInst(OrigLoad->getType(), V, V->getName() + ".val", Call); + IRB.CreateLoad(OrigLoad->getType(), V, V->getName() + ".val"); newLoad->setAlignment(OrigLoad->getAlignment()); // Transfer the AA info too. AAMDNodes AAInfo; Index: llvm/test/Transforms/ArgumentPromotion/dbg.ll =================================================================== --- llvm/test/Transforms/ArgumentPromotion/dbg.ll +++ llvm/test/Transforms/ArgumentPromotion/dbg.ll @@ -11,13 +11,32 @@ ret void } -define void @caller(i32** %Y) { -; CHECK: call void @test(i32 % - call void @test(i32** %Y) +%struct.pair = type { i32, i32 } + +; CHECK: define internal void @test_byval(i32 %{{.*}}, i32 %{{.*}}) +define internal void @test_byval(%struct.pair* byval %P) { + ret void +} + +; CHECK-LABEL: define {{.*}} @caller( +define void @caller(i32** %Y, %struct.pair* %P) { +; CHECK: load i32*, {{.*}} !dbg [[LOC_1:![0-9]+]] +; CHECK-NEXT: load i32, {{.*}} !dbg [[LOC_1]] +; CHECK-NEXT: call void @test(i32 %{{.*}}), !dbg [[LOC_1]] + call void @test(i32** %Y), !dbg !1 + +; CHECK: getelementptr %struct.pair, {{.*}} !dbg [[LOC_2:![0-9]+]] +; CHECK-NEXT: load i32, i32* {{.*}} !dbg [[LOC_2]] +; CHECK-NEXT: getelementptr %struct.pair, {{.*}} !dbg [[LOC_2]] +; CHECK-NEXT: load i32, i32* {{.*}} !dbg [[LOC_2]] +; CHECK-NEXT: call void @test_byval(i32 %{{.*}}, i32 %{{.*}}), !dbg [[LOC_2]] + call void @test_byval(%struct.pair* %P), !dbg !6 ret void } ; CHECK: [[SP]] = distinct !DISubprogram(name: "test", +; CHECK: [[LOC_1]] = !DILocation(line: 8 +; CHECK: [[LOC_2]] = !DILocation(line: 9 !llvm.module.flags = !{!0} !llvm.dbg.cu = !{!3} @@ -27,3 +46,4 @@ !2 = distinct !DISubprogram(name: "test", file: !5, line: 3, isLocal: true, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !3, scopeLine: 3, scope: null) !3 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: LineTablesOnly, file: !5) !5 = !DIFile(filename: "test.c", directory: "") +!6 = !DILocation(line: 9, scope: !2)