[PATCH] D22713: Fix - CodeExtractor : Inherit Target Dependent Attributes from the parent function.

River Riddle via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 22 18:08:47 PDT 2016


rriddle created this revision.
rriddle added a reviewer: davide.
rriddle added a subscriber: llvm-commits.

   When extracting a set of blocks make sure to inherit all of the target dependent attributes to make sure that the function will be valid for lowering. One example is the "target-features" attribute for x86, if the extracted region has functionality that relies on a specific feature it will fail to be lowered.
   This also allows for extracted functions to be valid for inlining, at least back into the parent function, as the target attributes are tested when inlining for compatibility.

https://reviews.llvm.org/D22713

Files:
  /Users/rriddle/Desktop/llvm/llvm/lib/Transforms/Utils/CodeExtractor.cpp
  /Users/rriddle/Desktop/llvm/llvm/test/Transforms/CodeExtractor/2016-07-20-InheritAttributes.ll

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
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);
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D22713.65201.patch
Type: text/x-patch
Size: 3873 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160723/2fe77dbe/attachment.bin>


More information about the llvm-commits mailing list