Index: /Users/rriddle/Desktop/llvm/llvm/lib/Transforms/Utils/CodeExtractor.cpp =================================================================== --- /Users/rriddle/Desktop/llvm/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ /Users/rriddle/Desktop/llvm/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -339,7 +339,20 @@ // If the old function is no-throw, so is the new one. if (oldFunction->doesNotThrow()) newFunction->setDoesNotThrow(); - + + // Inherit the uwtable attribute if we need to. + if(oldFunction->hasUWTable()) + newFunction->setHasUWTable(); + + // Inherit all of the target dependent attributes. + // (e.g. If the extracted region contains a call to an x86.sse + // instruction we need to make sure that the extracted region has the + // "target-features" attribute allowing it to be lowered. + AttributeSet OldAttrs = oldFunction->getAttributes().getFnAttributes(); + AttrBuilder AB(OldAttrs, AttributeSet::FunctionIndex); + for(auto Attr : AB.td_attrs()) + newFunction->addFnAttr(Attr.first, Attr.second); + newFunction->getBasicBlockList().push_back(newRootNode); // Create an iterator to name all of the arguments we inserted. @@ -372,8 +385,14 @@ AI = newFunction->arg_begin(); for (unsigned i = 0, e = inputs.size(); i != e; ++i, ++AI) AI->setName(inputs[i]->getName()); - for (unsigned i = 0, e = outputs.size(); i != e; ++i, ++AI) + for (unsigned i = 0, e = outputs.size(); i != e; ++i, ++AI){ AI->setName(outputs[i]->getName()+".out"); + + // Output parameters are guaranteed to not alias, as they are allocas + // in the original function. + AI->addAttr(Attribute::NoAlias); + AI->addAttr(Attribute::NonNull); + } } // Rewrite branches to basic blocks outside of the loop to new dummy blocks @@ -692,7 +711,7 @@ Function *oldFunction = header->getParent(); // This takes place of the original loop - BasicBlock *codeReplacer = BasicBlock::Create(header->getContext(), + BasicBlock *codeReplacer = BasicBlock::Create(header->getContext(), "codeRepl", oldFunction, header); Index: /Users/rriddle/Desktop/llvm/llvm/test/Transforms/CodeExtractor/2016-07-20-InheritAttributes.ll =================================================================== --- /Users/rriddle/Desktop/llvm/llvm/test/Transforms/CodeExtractor/2016-07-20-InheritAttributes.ll +++ /Users/rriddle/Desktop/llvm/llvm/test/Transforms/CodeExtractor/2016-07-20-InheritAttributes.ll @@ -0,0 +1,34 @@ +; RUN: opt < %s -partial-inliner | llc -filetype=null +; This testcase tests inheriting target attributes + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nounwind readnone +declare <4 x float> @llvm.x86.sse41.blendvps(<4 x float>, <4 x float>, <4 x float>) #0 + +; Function Attrs: nounwind uwtable +define <4 x float> @inlinedFunc(i1, <4 x float>, <4 x float>, <4 x float>) #1 { +entry: + br i1 %0, label %if.then, label %return + if.then: +; Target intrinsic that requires sse4.1 + %target.call = call <4 x float> @llvm.x86.sse41.blendvps(<4 x float> %1, <4 x float> %2, <4 x float> %3) + br label %return +return: ; preds = %entry + %retval = phi <4 x float> [ zeroinitializer, %entry ], [ %target.call, %if.then ] + ret <4 x float> %retval +} + +; Function Attrs: nounwind uwtable +define <4 x float> @dummyCaller(i1, <4 x float>, <4 x float>, <4 x float>) #1 { +entry: + %val = call <4 x float> @inlinedFunc(i1 %0, <4 x float> %1, <4 x float> %2, <4 x float> %3) + ret <4 x float> %val +} + +attributes #0 = { nounwind readnone } +attributes #1 = { nounwind uwtable "target-cpu"="x86-64" "target-features"="+sse4.1" } + +; CHECK-LABEL: @inlinedFunc.1_if.then +; CHECK: #1