[IROutliner] Deduplicating functions that only require inputs.
authorAndrew Litteken <andrew.litteken@gmail.com>
Thu, 27 Aug 2020 20:16:37 +0000 (15:16 -0500)
committerAndrew Litteken <andrew.litteken@gmail.com>
Sat, 19 Dec 2020 23:26:29 +0000 (17:26 -0600)
Extracted regions can have both inputs and outputs.  In addition, the
CodeExtractor removes inputs that are only used in llvm.assumes, and
sunken allocas (values are used entirely in the extracted region as
denoted by lifetime intrinsics).  We also cannot combine sections that
have different constants in the same structural location, and these
constants will have to elevated to argument. This patch deduplicates
extracted functions that only have inputs and non of the special cases.

We test that correctly deduplicate in:
test/Transforms/IROutliner/outlining-same-globals.ll
test/Transforms/IROutliner/outlining-same-constants.ll
test/Transforms/IROutliner/outlining-different-structure.ll

21 files changed:
llvm/include/llvm/Transforms/IPO/IROutliner.h
llvm/lib/Transforms/IPO/IROutliner.cpp
llvm/test/Transforms/IROutliner/extraction.ll
llvm/test/Transforms/IROutliner/illegal-assumes.ll
llvm/test/Transforms/IROutliner/illegal-branches.ll
llvm/test/Transforms/IROutliner/illegal-callbr.ll
llvm/test/Transforms/IROutliner/illegal-calls.ll
llvm/test/Transforms/IROutliner/illegal-catchpad.ll
llvm/test/Transforms/IROutliner/illegal-cleanup.ll
llvm/test/Transforms/IROutliner/illegal-frozen.ll
llvm/test/Transforms/IROutliner/illegal-gep.ll
llvm/test/Transforms/IROutliner/illegal-invoke.ll
llvm/test/Transforms/IROutliner/illegal-landingpad.ll
llvm/test/Transforms/IROutliner/illegal-memset.ll
llvm/test/Transforms/IROutliner/illegal-phi-nodes.ll
llvm/test/Transforms/IROutliner/legal-debug.ll
llvm/test/Transforms/IROutliner/outlining-address-taken.ll
llvm/test/Transforms/IROutliner/outlining-different-constants.ll
llvm/test/Transforms/IROutliner/outlining-different-structure.ll
llvm/test/Transforms/IROutliner/outlining-same-constants.ll
llvm/test/Transforms/IROutliner/outlining-same-globals.ll

index 25e42e1..01f8700 100644 (file)
@@ -70,6 +70,17 @@ struct OutlinableRegion {
   IRInstructionData *NewFront = nullptr;
   IRInstructionData *NewBack = nullptr;
 
+  /// The number of extracted inputs from the CodeExtractor.
+  unsigned NumExtractedInputs;
+
+  /// Mapping the extracted argument number to the argument number in the
+  /// overall function.  Since there will be inputs, such as elevated constants
+  /// that are not the same in each region in a SimilarityGroup, or values that
+  /// cannot be sunk into the extracted section in every region, we must keep
+  /// track of which extracted argument maps to which overall argument.
+  DenseMap<unsigned, unsigned> ExtractedArgToAgg;
+  DenseMap<unsigned, unsigned> AggArgToExtracted;
+
   /// Used to create an outlined function.
   CodeExtractor *CE = nullptr;
 
@@ -154,6 +165,17 @@ private:
   pruneIncompatibleRegions(std::vector<IRSimilarityCandidate> &CandidateVec,
                            OutlinableGroup &CurrentGroup);
 
+  /// Create the function based on the overall types found in the current
+  /// regions being outlined.
+  ///
+  /// \param M - The module to outline from.
+  /// \param [in,out] CG - The OutlinableGroup for the regions to be outlined.
+  /// \param [in] FunctionNameSuffix - How many functions have we previously
+  /// created.
+  /// \returns the newly created function.
+  Function *createFunction(Module &M, OutlinableGroup &CG,
+                           unsigned FunctionNameSuffix);
+
   /// Identify the needed extracted inputs in a section, and add to the overall
   /// function if needed.
   ///
@@ -167,6 +189,19 @@ private:
   /// \returns True if it was successfully outlined.
   bool extractSection(OutlinableRegion &Region);
 
+  /// For the similarities found, and the extracted sections, create a single
+  /// outlined function with appropriate output blocks as necessary.
+  ///
+  /// \param [in] M - The module to outline from
+  /// \param [in] CurrentGroup - The set of extracted sections to consolidate.
+  /// \param [in,out] FuncsToRemove - List of functions to remove from the
+  /// module after outlining is completed.
+  /// \param [in,out] OutlinedFunctionNum - the number of new outlined
+  /// functions.
+  void deduplicateExtractedSections(Module &M, OutlinableGroup &CurrentGroup,
+                                    std::vector<Function *> &FuncsToRemove,
+                                    unsigned &OutlinedFunctionNum);
+
   /// The set of outlined Instructions, identified by their location in the
   /// sequential ordering of instructions in a Module.
   DenseSet<unsigned> Outlined;
index 7a1fdd4..4031eed 100644 (file)
@@ -38,10 +38,26 @@ struct OutlinableGroup {
   /// The sections that could be outlined
   std::vector<OutlinableRegion *> Regions;
 
+  /// The argument types for the function created as the overall function to
+  /// replace the extracted function for each region.
+  std::vector<Type *> ArgumentTypes;
+  /// The FunctionType for the overall function.
+  FunctionType *OutlinedFunctionType = nullptr;
+  /// The Function for the collective overall function.
+  Function *OutlinedFunction = nullptr;
+
   /// Flag for whether we should not consider this group of OutlinableRegions
   /// for extraction.
   bool IgnoreGroup = false;
 
+  /// Flag for whether the \ref ArgumentTypes have been defined after the
+  /// extraction of the first region.
+  bool InputTypesSet = false;
+
+  /// The number of input values in \ref ArgumentTypes.  Anything after this
+  /// index in ArgumentTypes is an output argument.
+  unsigned NumAggregateInputs = 0;
+
   /// For the \ref Regions, we look at every Value.  If it is a constant,
   /// we check whether it is the same in Region.
   ///
@@ -182,18 +198,19 @@ constantMatches(Value *V, unsigned GVN,
   return false;
 }
 
-/// Find whether \p Region matches the global value numbering to Constant mapping
-/// found so far.
+/// Find whether \p Region matches the global value numbering to Constant
+/// mapping found so far.
 ///
 /// \param Region - The OutlinableRegion we are checking for constants
+/// \param GVNToConstant - The mapping of global value number to Constants.
 /// \param NotSame - The set of global value numbers that do not have the same
 /// constant in each region.
 /// \returns true if all Constants are the same in every use of a Constant in \p
 /// Region and false if not
 static bool
 collectRegionsConstants(OutlinableRegion &Region,
-                       DenseMap<unsigned, Constant *> &GVNToConstant,
-                       DenseSet<unsigned> &NotSame) {
+                        DenseMap<unsigned, Constant *> &GVNToConstant,
+                        DenseSet<unsigned> &NotSame) {
   IRSimilarityCandidate &C = *Region.Candidate;
   for (IRInstructionData &ID : C) {
 
@@ -248,6 +265,48 @@ void OutlinableGroup::findSameConstants(DenseSet<unsigned> &NotSame) {
     }
 }
 
+Function *IROutliner::createFunction(Module &M, OutlinableGroup &Group,
+                                     unsigned FunctionNameSuffix) {
+  assert(!Group.OutlinedFunction && "Function is already defined!");
+
+  Group.OutlinedFunctionType = FunctionType::get(
+      Type::getVoidTy(M.getContext()), Group.ArgumentTypes, false);
+
+  // These functions will only be called from within the same module, so
+  // we can set an internal linkage.
+  Group.OutlinedFunction = Function::Create(
+      Group.OutlinedFunctionType, GlobalValue::InternalLinkage,
+      "outlined_ir_func_" + std::to_string(FunctionNameSuffix), M);
+
+  Group.OutlinedFunction->addFnAttr(Attribute::OptimizeForSize);
+  Group.OutlinedFunction->addFnAttr(Attribute::MinSize);
+
+  return Group.OutlinedFunction;
+}
+
+/// Move each BasicBlock in \p Old to \p New.
+///
+/// \param [in] Old - the function to move the basic blocks from.
+/// \param [in] New - The function to move the basic blocks to.
+/// \returns the first return block for the function in New.
+static BasicBlock *moveFunctionData(Function &Old, Function &New) {
+  Function::iterator CurrBB, NextBB, FinalBB;
+  BasicBlock *NewEnd = nullptr;
+  std::vector<Instruction *> DebugInsts;
+  for (CurrBB = Old.begin(), FinalBB = Old.end(); CurrBB != FinalBB;
+       CurrBB = NextBB) {
+    NextBB = std::next(CurrBB);
+    CurrBB->removeFromParent();
+    CurrBB->insertInto(&New);
+    Instruction *I = CurrBB->getTerminator();
+    if (ReturnInst *RI = dyn_cast<ReturnInst>(I))
+      NewEnd = &(*CurrBB);
+  }
+
+  assert(NewEnd && "No return instruction for new function?");
+  return NewEnd;
+}
+
 /// Find the GVN for the inputs that have been found by the CodeExtractor,
 /// excluding the ones that will be removed by llvm.assumes as these will be
 /// removed by the CodeExtractor.
@@ -256,8 +315,8 @@ void OutlinableGroup::findSameConstants(DenseSet<unsigned> &NotSame) {
 /// analyzing.
 /// \param [in] CurrentInputs - The set of inputs found by the
 /// CodeExtractor.
-/// \param [out] CurrentInputNumbers - The global value numbers for the extracted
-/// arguments.
+/// \param [out] CurrentInputNumbers - The global value numbers for the
+/// extracted arguments.
 static void mapInputsToGVNs(IRSimilarityCandidate &C,
                             SetVector<Value *> &CurrentInputs,
                             std::vector<unsigned> &EndInputNumbers) {
@@ -278,7 +337,8 @@ static void mapInputsToGVNs(IRSimilarityCandidate &C,
 /// function.
 ///
 /// \param [in,out] Region - The region of code to be analyzed.
-/// \param [out] Inputs - The global value numbers for the extracted arguments.
+/// \param [out] InputGVNs - The global value numbers for the extracted
+/// arguments.
 /// \param [out] ArgInputs - The values of the inputs to the extracted function.
 static void getCodeExtractorArguments(OutlinableRegion &Region,
                                       std::vector<unsigned> &InputGVNs,
@@ -332,8 +392,65 @@ static void getCodeExtractorArguments(OutlinableRegion &Region,
   mapInputsToGVNs(C, OverallInputs, InputGVNs);
 }
 
-void IROutliner::findAddInputsOutputs(
-    Module &M, OutlinableRegion &Region) {
+/// Look over the inputs and map each input argument to an argument in the
+/// overall function for the regions.  This creates a way to replace the
+/// arguments of the extracted function, with the arguments of the new overall
+/// function.
+///
+/// \param [in,out] Region - The region of code to be analyzed.
+/// \param [in] InputsGVNs - The global value numbering of the input values
+/// collected.
+/// \param [in] ArgInputs - The values of the arguments to the extracted
+/// function.
+static void
+findExtractedInputToOverallInputMapping(OutlinableRegion &Region,
+                                        std::vector<unsigned> InputGVNs,
+                                        SetVector<Value *> &ArgInputs) {
+
+  IRSimilarityCandidate &C = *Region.Candidate;
+  OutlinableGroup &Group = *Region.Parent;
+
+  // This counts the argument number in the overall function.
+  unsigned TypeIndex = 0;
+
+  // This counts the argument number in the extracted function.
+  unsigned OriginalIndex = 0;
+
+  // Find the mapping of the extracted arguments to the arguments for the
+  // overall function.
+  for (unsigned InputVal : InputGVNs) {
+    Optional<Value *> InputOpt = C.fromGVN(InputVal);
+    assert(InputOpt.hasValue() && "Global value number not found?");
+    Value *Input = InputOpt.getValue();
+
+    if (!Group.InputTypesSet)
+      Group.ArgumentTypes.push_back(Input->getType());
+
+    // It is not a constant, check if it is a sunken alloca.  If it is not,
+    // create the mapping from extracted to overall.  If it is, create the
+    // mapping of the index to the value.
+    unsigned Found = ArgInputs.count(Input);
+    assert(Found && "Input cannot be found!");
+
+    Region.ExtractedArgToAgg.insert(std::make_pair(OriginalIndex, TypeIndex));
+    Region.AggArgToExtracted.insert(std::make_pair(TypeIndex, OriginalIndex));
+    OriginalIndex++;
+    TypeIndex++;
+  }
+
+  // If we do not have definitions for the OutlinableGroup holding the region,
+  // set the length of the inputs here.  We should have the same inputs for
+  // all of the different regions contained in the OutlinableGroup since they
+  // are all structurally similar to one another
+  if (!Group.InputTypesSet) {
+    Group.NumAggregateInputs = TypeIndex;
+    Group.InputTypesSet = true;
+  }
+
+  Region.NumExtractedInputs = OriginalIndex;
+}
+
+void IROutliner::findAddInputsOutputs(Module &M, OutlinableRegion &Region) {
   std::vector<unsigned> Inputs;
   SetVector<Value *> ArgInputs;
 
@@ -341,6 +458,124 @@ void IROutliner::findAddInputsOutputs(
 
   if (Region.IgnoreRegion)
     return;
+
+  // Map the inputs found by the CodeExtractor to the arguments found for
+  // the overall function.
+  findExtractedInputToOverallInputMapping(Region, Inputs, ArgInputs);
+}
+
+/// Replace the extracted function in the Region with a call to the overall
+/// function constructed from the deduplicated similar regions, replacing and
+/// remapping the values passed to the extracted function as arguments to the
+/// new arguments of the overall function.
+///
+/// \param [in] M - The module to outline from.
+/// \param [in] Region - The regions of extracted code to be replaced with a new
+/// function.
+/// \returns a call instruction with the replaced function.
+CallInst *replaceCalledFunction(Module &M, OutlinableRegion &Region) {
+  std::vector<Value *> NewCallArgs;
+  DenseMap<unsigned, unsigned>::iterator ArgPair;
+
+  OutlinableGroup &Group = *Region.Parent;
+  CallInst *Call = Region.Call;
+  assert(Call && "Call to replace is nullptr?");
+  Function *AggFunc = Group.OutlinedFunction;
+  assert(AggFunc && "Function to replace with is nullptr?");
+
+  // If the arguments are the same size, there are not values that need to be
+  // made argument, or different output registers to handle.  We can simply
+  // replace the called function in this case.
+  assert(AggFunc->arg_size() == Call->arg_size() &&
+         "Can only replace calls with the same number of arguments!");
+
+  LLVM_DEBUG(dbgs() << "Replace call to " << *Call << " with call to "
+                    << *AggFunc << " with same number of arguments\n");
+  Call->setCalledFunction(AggFunc);
+  return Call;
+}
+
+// Within an extracted function, replace the argument uses of the extracted
+// region with the arguments of the function for an OutlinableGroup.
+//
+// \param OS [in] - The region of extracted code to be changed.
+static void replaceArgumentUses(OutlinableRegion &Region) {
+  OutlinableGroup &Group = *Region.Parent;
+  assert(Region.ExtractedFunction && "Region has no extracted function?");
+
+  for (unsigned ArgIdx = 0; ArgIdx < Region.ExtractedFunction->arg_size();
+       ArgIdx++) {
+    assert(Region.ExtractedArgToAgg.find(ArgIdx) !=
+               Region.ExtractedArgToAgg.end() &&
+           "No mapping from extracted to outlined?");
+    unsigned AggArgIdx = Region.ExtractedArgToAgg.find(ArgIdx)->second;
+    Argument *AggArg = Group.OutlinedFunction->getArg(AggArgIdx);
+    Argument *Arg = Region.ExtractedFunction->getArg(ArgIdx);
+    // The argument is an input, so we can simply replace it with the overall
+    // argument value
+    LLVM_DEBUG(dbgs() << "Replacing uses of input " << *Arg << " in function "
+                      << *Region.ExtractedFunction << " with " << *AggArg
+                      << " in function " << *Group.OutlinedFunction << "\n");
+    Arg->replaceAllUsesWith(AggArg);
+  }
+}
+
+/// Fill the new function that will serve as the replacement function for all of
+/// the extracted regions of a certain structure from the first region in the
+/// list of regions.  Replace this first region's extracted function with the
+/// new overall function.
+///
+/// \param M [in] - The module we are outlining from.
+/// \param CurrentGroup [in] - The group of regions to be outlined.
+/// \param FuncsToRemove [in,out] - Extracted functions to erase from module
+/// once outlining is complete.
+static void fillOverallFunction(Module &M, OutlinableGroup &CurrentGroup,
+                                std::vector<Function *> &FuncsToRemove) {
+  OutlinableRegion *CurrentOS = CurrentGroup.Regions[0];
+
+  // Move first extracted function's instructions into new function
+  LLVM_DEBUG(dbgs() << "Move instructions from "
+                    << *CurrentOS->ExtractedFunction << " to instruction "
+                    << *CurrentGroup.OutlinedFunction << "\n");
+  moveFunctionData(*CurrentOS->ExtractedFunction,
+                   *CurrentGroup.OutlinedFunction);
+
+  // Transfer the attributes
+  for (Attribute A :
+       CurrentOS->ExtractedFunction->getAttributes().getFnAttributes())
+    CurrentGroup.OutlinedFunction->addFnAttr(A);
+
+  replaceArgumentUses(*CurrentOS);
+
+  // Replace the call to the extracted function with the outlined function.
+  CurrentOS->Call = replaceCalledFunction(M, *CurrentOS);
+
+  // We only delete the extracted funcitons at the end since we may need to
+  // reference instructions contained in them for mapping purposes.
+  FuncsToRemove.push_back(CurrentOS->ExtractedFunction);
+}
+
+void IROutliner::deduplicateExtractedSections(
+    Module &M, OutlinableGroup &CurrentGroup,
+    std::vector<Function *> &FuncsToRemove, unsigned &OutlinedFunctionNum) {
+  createFunction(M, CurrentGroup, OutlinedFunctionNum);
+
+  std::vector<BasicBlock *> OutputStoreBBs;
+
+  OutlinableRegion *CurrentOS;
+
+  fillOverallFunction(M, CurrentGroup, FuncsToRemove);
+
+  // Do the same for the other extracted functions
+  for (unsigned Idx = 1; Idx < CurrentGroup.Regions.size(); Idx++) {
+    CurrentOS = CurrentGroup.Regions[Idx];
+
+    replaceArgumentUses(*CurrentOS);
+    CurrentOS->Call = replaceCalledFunction(M, *CurrentOS);
+    FuncsToRemove.push_back(CurrentOS->ExtractedFunction);
+  }
+
+  OutlinedFunctionNum++;
 }
 
 void IROutliner::pruneIncompatibleRegions(
@@ -471,6 +706,7 @@ unsigned IROutliner::doOutline(Module &M) {
                       });
 
   DenseSet<unsigned> NotSame;
+  std::vector<Function *> FuncsToRemove;
   // Iterate over the possible sets of similarity.
   for (SimilarityGroup &CandidateVec : SimilarityCandidates) {
     OutlinableGroup CurrentGroup;
@@ -516,7 +752,6 @@ unsigned IROutliner::doOutline(Module &M) {
     // Create functions out of all the sections, and mark them as outlined.
     OutlinedRegions.clear();
     for (OutlinableRegion *OS : CurrentGroup.Regions) {
-      OutlinedFunctionNum++;
       bool FunctionOutlined = extractSection(*OS);
       if (FunctionOutlined) {
         unsigned StartIdx = OS->Candidate->getStartIdx();
@@ -529,8 +764,17 @@ unsigned IROutliner::doOutline(Module &M) {
     }
 
     CurrentGroup.Regions = std::move(OutlinedRegions);
+
+    if (CurrentGroup.Regions.empty())
+      continue;
+
+    deduplicateExtractedSections(M, CurrentGroup, FuncsToRemove,
+                                 OutlinedFunctionNum);
   }
 
+  for (Function *F : FuncsToRemove)
+    F->eraseFromParent();
+
   return OutlinedFunctionNum;
 }
 
index 34c784d..2db261b 100644 (file)
@@ -10,7 +10,7 @@ define void @extract1() {
 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @extract1.outlined(i32* [[A]], i32* [[B]], i32* [[C]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], i32* [[C]])
 ; CHECK-NEXT:    ret void
 ;
 entry:
@@ -32,7 +32,7 @@ define void @extract2() {
 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @extract2.outlined(i32* [[A]], i32* [[B]], i32* [[C]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], i32* [[C]])
 ; CHECK-NEXT:    ret void
 ;
 entry:
@@ -65,7 +65,7 @@ define void @extract_outs1() #0 {
 ; CHECK-NEXT:    store i32 [[ADD]], i32* [[OUTPUT]], align 4
 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* [[OUTPUT]], align 4
 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[OUTPUT]], align 4
-; CHECK-NEXT:    call void @extract_outs1.outlined(i32 [[TMP2]], i32 [[ADD]], i32* [[RESULT]])
+; CHECK-NEXT:    call void @outlined_ir_func_1(i32 [[TMP2]], i32 [[ADD]], i32* [[RESULT]])
 ; CHECK-NEXT:    ret void
 ;
 entry:
@@ -102,7 +102,7 @@ define void @extract_outs2() #0 {
 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[TMP0]], [[TMP1]]
 ; CHECK-NEXT:    store i32 [[ADD]], i32* [[OUTPUT]], align 4
 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* [[OUTPUT]], align 4
-; CHECK-NEXT:    call void @extract_outs2.outlined(i32 [[TMP2]], i32 [[ADD]], i32* [[RESULT]])
+; CHECK-NEXT:    call void @outlined_ir_func_1(i32 [[TMP2]], i32 [[ADD]], i32* [[RESULT]])
 ; CHECK-NEXT:    ret void
 ;
 entry:
index c94c886..a401622 100644 (file)
@@ -14,9 +14,9 @@ define void @outline_assumes() {
 ; CHECK-NEXT:    store i1 true, i1* [[D]], align 4
 ; CHECK-NEXT:    [[DL:%.*]] = load i1, i1* [[D]], align 1
 ; CHECK-NEXT:    [[SPLIT_INST:%.*]] = sub i1 [[DL]], [[DL]]
-; CHECK-NEXT:    call void @outline_assumes.outlined(i32* [[A]], i32* [[B]], i32* [[C]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], i32* [[C]])
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[DL]])
-; CHECK-NEXT:    call void @outline_assumes.outlined.1(i32* [[A]], i32* [[B]], i32* [[C]])
+; CHECK-NEXT:    call void @outlined_ir_func_1(i32* [[A]], i32* [[B]], i32* [[C]])
 ; CHECK-NEXT:    ret void
 ;
 entry:
@@ -46,9 +46,9 @@ define void @outline_assumes2() {
 ; CHECK-NEXT:    [[D:%.*]] = alloca i1, align 4
 ; CHECK-NEXT:    store i1 false, i1* [[D]], align 4
 ; CHECK-NEXT:    [[DL:%.*]] = load i1, i1* [[D]], align 1
-; CHECK-NEXT:    call void @outline_assumes2.outlined(i32* [[A]], i32* [[B]], i32* [[C]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], i32* [[C]])
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[DL]])
-; CHECK-NEXT:    call void @outline_assumes2.outlined.2(i32* [[A]], i32* [[B]], i32* [[C]])
+; CHECK-NEXT:    call void @outlined_ir_func_1(i32* [[A]], i32* [[B]], i32* [[C]])
 ; CHECK-NEXT:    ret void
 ;
 entry:
@@ -78,9 +78,9 @@ define void @outline_assumes3() {
 ; CHECK-NEXT:    store i1 true, i1* [[D]], align 4
 ; CHECK-NEXT:    [[DL:%.*]] = load i1, i1* [[D]], align 1
 ; CHECK-NEXT:    [[SPLIT_INST:%.*]] = add i1 [[DL]], [[DL]]
-; CHECK-NEXT:    call void @outline_assumes3.outlined(i32* [[A]], i32* [[B]], i32* [[C]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], i32* [[C]])
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[DL]])
-; CHECK-NEXT:    call void @outline_assumes3.outlined.3(i32* [[A]])
+; CHECK-NEXT:    call void @outlined_ir_func_2(i32* [[A]])
 ; CHECK-NEXT:    ret void
 ;
 entry:
@@ -110,9 +110,9 @@ define void @outline_assumes4() {
 ; CHECK-NEXT:    store i1 false, i1* [[D]], align 4
 ; CHECK-NEXT:    [[DL:%.*]] = load i1, i1* [[D]], align 1
 ; CHECK-NEXT:    [[SPLIT_INST:%.*]] = add i1 [[DL]], [[DL]]
-; CHECK-NEXT:    call void @outline_assumes4.outlined(i32* [[A]], i32* [[B]], i32* [[C]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], i32* [[C]])
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[DL]])
-; CHECK-NEXT:    call void @outline_assumes4.outlined.4(i32* [[A]])
+; CHECK-NEXT:    call void @outlined_ir_func_2(i32* [[A]])
 ; CHECK-NEXT:    ret void
 ;
 entry:
index 2f00c59..23d2e6c 100644 (file)
@@ -10,7 +10,7 @@ define void @function1() {
 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @function1.outlined(i32* [[A]], i32* [[B]], i32* [[C]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], i32* [[C]])
 ; CHECK-NEXT:    br label [[NEXT:%.*]]
 ; CHECK:       next:
 ; CHECK-NEXT:    ret void
@@ -33,7 +33,7 @@ define void @function2() {
 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @function2.outlined(i32* [[A]], i32* [[B]], i32* [[C]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], i32* [[C]])
 ; CHECK-NEXT:    br label [[NEXT:%.*]]
 ; CHECK:       next:
 ; CHECK-NEXT:    ret void
index ee21d3c..c836f71 100644 (file)
@@ -9,11 +9,11 @@ define i32 @function1(i32 %a, i32 %b) {
 ; CHECK-LABEL: @function1(
 ; CHECK-NEXT:  bb0:
 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[A:%.*]], 4
-; CHECK-NEXT:    call void @function1.outlined(i32 [[B:%.*]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[B:%.*]])
 ; CHECK-NEXT:    callbr void asm "xorl $0, $0
 ; CHECK-NEXT:    to label [[NORMAL:%.*]] [label %fail1]
 ; CHECK:       normal:
-; CHECK-NEXT:    call void @function1.outlined.1(i32 [[B]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[B]])
 ; CHECK-NEXT:    ret i32 0
 ; CHECK:       fail1:
 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B]], 1
@@ -39,11 +39,11 @@ define i32 @function2(i32 %a, i32 %b) {
 ; CHECK-LABEL: @function2(
 ; CHECK-NEXT:  bb0:
 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[A:%.*]], 4
-; CHECK-NEXT:    call void @function2.outlined(i32 [[B:%.*]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[B:%.*]])
 ; CHECK-NEXT:    callbr void asm "xorl $0, $0
 ; CHECK-NEXT:    to label [[NORMAL:%.*]] [label %fail1]
 ; CHECK:       normal:
-; CHECK-NEXT:    call void @function2.outlined.2(i32 [[B]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[B]])
 ; CHECK-NEXT:    ret i32 0
 ; CHECK:       fail1:
 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B]], 1
index d073d2d..442df08 100644 (file)
@@ -13,9 +13,9 @@ define void @outline_constants1() {
 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outline_constants1.outlined.1(i32* [[A]], i32* [[B]], i32* [[C]])
+; CHECK-NEXT:    call void @outlined_ir_func_1(i32* [[A]], i32* [[B]], i32* [[C]])
 ; CHECK-NEXT:    call void @f1(i32* [[A]], i32* [[B]])
-; CHECK-NEXT:    call void @outline_constants1.outlined(i32* [[A]], i32* [[B]], i32* [[C]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], i32* [[C]])
 ; CHECK-NEXT:    ret void
 ;
 entry:
@@ -38,9 +38,9 @@ define void @outline_constants2() {
 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outline_constants2.outlined.2(i32* [[A]], i32* [[B]], i32* [[C]])
+; CHECK-NEXT:    call void @outlined_ir_func_1(i32* [[A]], i32* [[B]], i32* [[C]])
 ; CHECK-NEXT:    call void @f1(i32* [[A]], i32* [[B]])
-; CHECK-NEXT:    call void @outline_constants2.outlined(i32* [[A]], i32* [[B]], i32* [[C]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], i32* [[C]])
 ; CHECK-NEXT:    ret void
 ;
 entry:
index a8c91bf..83b8243 100644 (file)
@@ -18,7 +18,7 @@ define void @function1() personality i8 3 {
 ; CHECK-NEXT:    [[CS1:%.*]] = catchswitch within none [label %catchpad1] unwind to caller
 ; CHECK:       catchpad1:
 ; CHECK-NEXT:    [[TMP0:%.*]] = catchpad within [[CS1]] []
-; CHECK-NEXT:    call void @function1.outlined(i32* [[A]], i32* [[B]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]])
 ; CHECK-NEXT:    br label [[NORMAL]]
 ; CHECK:       normal:
 ; CHECK-NEXT:    ret void
@@ -49,7 +49,7 @@ define void @function2() personality i8 3 {
 ; CHECK-NEXT:    [[CS1:%.*]] = catchswitch within none [label %catchpad1] unwind to caller
 ; CHECK:       catchpad1:
 ; CHECK-NEXT:    [[TMP0:%.*]] = catchpad within [[CS1]] []
-; CHECK-NEXT:    call void @function2.outlined(i32* [[A]], i32* [[B]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]])
 ; CHECK-NEXT:    br label [[NORMAL]]
 ; CHECK:       normal:
 ; CHECK-NEXT:    ret void
index 6b2fd12..d48797b 100644 (file)
@@ -16,7 +16,7 @@ define void @function1() personality i8 3 {
 ; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]
 ; CHECK:       exception:
 ; CHECK-NEXT:    [[CLEAN:%.*]] = cleanuppad within none []
-; CHECK-NEXT:    call void @function1.outlined(i32* [[A]], i32* [[B]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]])
 ; CHECK-NEXT:    br label [[NORMAL]]
 ; CHECK:       normal:
 ; CHECK-NEXT:    ret void
@@ -43,7 +43,7 @@ define void @function2() personality i8 3 {
 ; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]
 ; CHECK:       exception:
 ; CHECK-NEXT:    [[CLEAN:%.*]] = cleanuppad within none []
-; CHECK-NEXT:    call void @function2.outlined(i32* [[A]], i32* [[B]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]])
 ; CHECK-NEXT:    br label [[NORMAL]]
 ; CHECK:       normal:
 ; CHECK-NEXT:    ret void
index 796653b..4ab1155 100644 (file)
@@ -10,7 +10,7 @@ define void @function1(i32* %a, i32* %b) {
 ; CHECK-NEXT:    br label [[FIRST:%.*]]
 ; CHECK:       first:
 ; CHECK-NEXT:    [[C:%.*]] = freeze i32* [[A:%.*]]
-; CHECK-NEXT:    call void @function1.outlined(i32* [[C]], i32* [[B:%.*]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[C]], i32* [[B:%.*]])
 ; CHECK-NEXT:    ret void
 ; CHECK:       next:
 ; CHECK-NEXT:    br label [[FIRST]]
@@ -32,7 +32,7 @@ define void @function2(i32* %a, i32* %b) {
 ; CHECK-NEXT:    br label [[FIRST:%.*]]
 ; CHECK:       first:
 ; CHECK-NEXT:    [[C:%.*]] = freeze i32* [[A:%.*]]
-; CHECK-NEXT:    call void @function2.outlined(i32* [[C]], i32* [[B:%.*]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[C]], i32* [[B:%.*]])
 ; CHECK-NEXT:    ret void
 ; CHECK:       next:
 ; CHECK-NEXT:    br label [[FIRST]]
index 0aa2d9a..e99ffb6 100644 (file)
@@ -12,7 +12,7 @@ define void @function1(%struct.ST* %s, i64 %t) {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @function1.outlined(i32* [[A]], i32* [[B]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]])
 ; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], %struct.ST* [[S:%.*]], i64 1
 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_ST]], %struct.ST* [[S]], i64 [[T:%.*]]
 ; CHECK-NEXT:    ret void
@@ -32,7 +32,7 @@ define void @function2(%struct.ST* %s, i64 %t) {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @function2.outlined(i32* [[A]], i32* [[B]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]])
 ; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], %struct.ST* [[S:%.*]], i64 1
 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_ST]], %struct.ST* [[S]], i64 [[T:%.*]]
 ; CHECK-NEXT:    ret void
index b38f489..6c3841a 100644 (file)
@@ -12,7 +12,7 @@ define void @function1() personality i8 3 {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @function1.outlined(i32* [[A]], i32* [[B]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]])
 ; CHECK-NEXT:    invoke void @llvm.donothing()
 ; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]
 ; CHECK:       exception:
@@ -40,7 +40,7 @@ define void @function2() personality i8 3 {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @function2.outlined(i32* [[A]], i32* [[B]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]])
 ; CHECK-NEXT:    invoke void @llvm.donothing()
 ; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]
 ; CHECK:       exception:
index 20f3116..fbcc28c 100644 (file)
@@ -17,7 +17,7 @@ define void @function1() personality i8 3 {
 ; CHECK:       exception:
 ; CHECK-NEXT:    [[CLEANUP:%.*]] = landingpad i8
 ; CHECK-NEXT:    cleanup
-; CHECK-NEXT:    call void @function1.outlined(i32* [[A]], i32* [[B]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]])
 ; CHECK-NEXT:    br label [[NORMAL]]
 ; CHECK:       normal:
 ; CHECK-NEXT:    ret void
@@ -45,7 +45,7 @@ define void @function2() personality i8 3 {
 ; CHECK:       exception:
 ; CHECK-NEXT:    [[CLEANUP:%.*]] = landingpad i8
 ; CHECK-NEXT:    cleanup
-; CHECK-NEXT:    call void @function2.outlined(i32* [[A]], i32* [[B]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]])
 ; CHECK-NEXT:    br label [[NORMAL]]
 ; CHECK:       normal:
 ; CHECK-NEXT:    ret void
index 7dd294e..71f66c2 100644 (file)
@@ -12,7 +12,7 @@ define i64 @function1(i64 %x, i64 %z, i64 %n) {
 ; CHECK-NEXT:    [[POOL:%.*]] = alloca [59 x i64], align 4
 ; CHECK-NEXT:    [[TMP:%.*]] = bitcast [59 x i64]* [[POOL]] to i8*
 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP]], i8 0, i64 236, i1 false)
-; CHECK-NEXT:    call void @function1.outlined(i64 [[N:%.*]], i64 [[X:%.*]], i64 [[Z:%.*]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i64 [[N:%.*]], i64 [[X:%.*]], i64 [[Z:%.*]])
 ; CHECK-NEXT:    ret i64 0
 ;
 entry:
@@ -31,7 +31,7 @@ define i64 @function2(i64 %x, i64 %z, i64 %n) {
 ; CHECK-NEXT:    [[POOL:%.*]] = alloca [59 x i64], align 4
 ; CHECK-NEXT:    [[TMP:%.*]] = bitcast [59 x i64]* [[POOL]] to i8*
 ; CHECK-NEXT:    call void @llvm.memset.p0i8.i64(i8* align 4 [[TMP]], i8 0, i64 236, i1 false)
-; CHECK-NEXT:    call void @function2.outlined(i64 [[N:%.*]], i64 [[X:%.*]], i64 [[Z:%.*]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i64 [[N:%.*]], i64 [[X:%.*]], i64 [[Z:%.*]])
 ; CHECK-NEXT:    ret i64 0
 ;
 entry:
index 5d9ef53..dc67466 100644 (file)
@@ -10,7 +10,7 @@ define void @function1(i32* %a, i32* %b) {
 ; CHECK-NEXT:    br label [[FIRST:%.*]]
 ; CHECK:       first:
 ; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 3, [[NEXT:%.*]] ]
-; CHECK-NEXT:    call void @function1.outlined(i32* [[A:%.*]], i32* [[B:%.*]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A:%.*]], i32* [[B:%.*]])
 ; CHECK-NEXT:    ret void
 ; CHECK:       next:
 ; CHECK-NEXT:    br label [[FIRST]]
@@ -32,7 +32,7 @@ define void @function2(i32* %a, i32* %b) {
 ; CHECK-NEXT:    br label [[FIRST:%.*]]
 ; CHECK:       first:
 ; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 3, [[NEXT:%.*]] ]
-; CHECK-NEXT:    call void @function2.outlined(i32* [[A:%.*]], i32* [[B:%.*]])
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A:%.*]], i32* [[B:%.*]])
 ; CHECK-NEXT:    ret void
 ; CHECK:       next:
 ; CHECK-NEXT:    br label [[FIRST]]
index 63ddd50..0a7ded9 100644 (file)
@@ -13,7 +13,7 @@ define void @function1() !dbg !6 {
 ; CHECK-NEXT:    call void @llvm.dbg.value(metadata i32* [[B]], [[META11:metadata !.*]], metadata !DIExpression()), [[DBG18]]
 ; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4, [[DBG19:!dbg !.*]]
 ; CHECK-NEXT:    call void @llvm.dbg.value(metadata i32* [[C]], [[META12:metadata !.*]], metadata !DIExpression()), [[DBG19]]
-; CHECK-NEXT:    call void @function1.outlined(i32* [[A]], i32* [[B]], i32* [[C]]), [[DBG20:!dbg !.*]]
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], i32* [[C]]), [[DBG20:!dbg !.*]]
 ; CHECK-NEXT:    ret void, [[DBG21:!dbg !.*]]
 ;
 entry:
@@ -44,7 +44,7 @@ define void @function2() !dbg !27 {
 ; CHECK-NEXT:    call void @llvm.dbg.value(metadata i32* [[B]], [[META25:metadata !.*]], metadata !DIExpression()), [[DBG31]]
 ; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4, [[DBG32:!dbg !.*]]
 ; CHECK-NEXT:    call void @llvm.dbg.value(metadata i32* [[C]], [[META26:metadata !.*]], metadata !DIExpression()), [[DBG32]]
-; CHECK-NEXT:    call void @function2.outlined(i32* [[A]], i32* [[B]], i32* [[C]]), [[DBG33:!dbg !.*]]
+; CHECK-NEXT:    call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], i32* [[C]]), [[DBG33:!dbg !.*]]
 ; CHECK-NEXT:    ret void, [[DBG34:!dbg !.*]]
 ;
 entry:
index dbae8e8..6f1d56f 100644 (file)
@@ -34,7 +34,7 @@ define void @outline_2() {
 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @[[FUNCTION_2:.*]](i32* [[A]], i32* [[B]], i32* [[C]])
+; CHECK-NEXT:    call void @[[FUNCTION_1]](i32* [[A]], i32* [[B]], i32* [[C]])
 ; CHECK-NEXT:    ret void
 ;
 entry:
@@ -81,7 +81,7 @@ new_block:
   ret void
 }
 
-; CHECK: define internal void @[[FUNCTION_2]](i32* [[ARG0:%.*]], i32* [[ARG1:%.*]], i32* [[ARG2:%.*]])
+; CHECK: define internal void @[[FUNCTION_1]](i32* [[ARG0:%.*]], i32* [[ARG1:%.*]], i32* [[ARG2:%.*]])
 ; CHECK: entry_to_outline:
 ; CHECK-NEXT:    store i32 2, i32* [[ARG0]], align 4
 ; CHECK-NEXT:    store i32 3, i32* [[ARG1]], align 4
index edcfe3c..d5937ca 100644 (file)
@@ -39,7 +39,7 @@ define void @outline_constants2() {
 ; CHECK-NEXT:    store i32 2, i32* [[A]], align 4
 ; CHECK-NEXT:    store i32 3, i32* [[B]], align 4
 ; CHECK-NEXT:    store i32 4, i32* [[C]], align 4
-; CHECK-NEXT:    call void @[[FUNCTION_1:.*]](i32* [[A]], i32* [[B]], i32* [[C]])
+; CHECK-NEXT:    call void @[[FUNCTION_0]](i32* [[A]], i32* [[B]], i32* [[C]])
 ; CHECK-NEXT:    ret void
 ;
 entry:
index 35a742e..ed978b2 100644 (file)
@@ -39,7 +39,7 @@ define void @outline_constants2() {
 ; CHECK-NEXT:    store i32 2, i32* [[A]], align 4
 ; CHECK-NEXT:    store i32 3, i32* [[B]], align 4
 ; CHECK-NEXT:    store i32 4, i32* [[C]], align 4
-; CHECK-NEXT:    call void @[[FUNCTION_1:.*]](i32* [[A]], i32* [[B]], i32* [[C]])
+; CHECK-NEXT:    call void @[[FUNCTION_0]](i32* [[A]], i32* [[B]], i32* [[C]])
 ; CHECK-NEXT:    ret void
 ;
 entry:
index 4020463..b98ac2e 100644 (file)
@@ -32,7 +32,7 @@ define void @outline_constants2() {
 ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
 ; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @[[FUNCTION_1:.*]](i32* [[A]], i32* [[B]], i32* [[C]])
+; CHECK-NEXT:    call void @[[FUNCTION_0]](i32* [[A]], i32* [[B]], i32* [[C]])
 ; CHECK-NEXT:    ret void
 ;
 entry:
index 9e28cc9..b065eae 100644 (file)
@@ -10,7 +10,7 @@
 define void @outline_globals1() {
 ; CHECK-LABEL: @outline_globals1(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @[[FUNCTION_0:.*]]()
+; CHECK-NEXT:    call void @outlined_ir_func_0()
 ; CHECK-NEXT:    ret void
 ;
 entry:
@@ -23,7 +23,7 @@ entry:
 define void @outline_globals2() {
 ; CHECK-LABEL: @outline_globals2(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @[[FUNCTION_1:.*]]()
+; CHECK-NEXT:    call void @outlined_ir_func_0()
 ; CHECK-NEXT:    ret void
 ;
 entry:
@@ -33,14 +33,7 @@ entry:
   ret void
 }
 
-; CHECK: define internal void @[[FUNCTION_0]]()
-; CHECK: entry_to_outline:
-; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @global1, align 4
-; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* @global2, align 4
-; CHECK-NEXT: [[ADD:%.*]] = add i32 [[TMP1]], [[TMP2]]
-
-
-; CHECK: define internal void @[[FUNCTION_1]]()
+; CHECK: define internal void @outlined_ir_func_0()
 ; CHECK: entry_to_outline:
 ; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @global1, align 4
 ; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* @global2, align 4