summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Silva <chisophugis@gmail.com>2016-08-01 03:15:32 +0000
committerSean Silva <chisophugis@gmail.com>2016-08-01 03:15:32 +0000
commita0a802abe3eafe698d1304c4e8b187ab85fa3942 (patch)
tree6ebd90bf70e3801bab98cc46f443aec786e5c3a2
parent72be9a6937a1045816c6f2c761a35663d739c47f (diff)
downloadbcm5719-llvm-a0a802abe3eafe698d1304c4e8b187ab85fa3942.tar.gz
bcm5719-llvm-a0a802abe3eafe698d1304c4e8b187ab85fa3942.zip
Fix - CodeExtractor : Inherit Target Dependent Attributes from the parent function.
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. Patch by River Riddle! Differential Revision: https://reviews.llvm.org/D22713 llvm-svn: 277315
-rw-r--r--llvm/lib/Transforms/Utils/CodeExtractor.cpp17
-rw-r--r--llvm/test/Transforms/CodeExtractor/InheritTargetAttributes.ll40
2 files changed, 56 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
index 6816eb48f29..c514c9c9cd4 100644
--- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
@@ -351,7 +351,22 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
// 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.
+ // FIXME: This should be changed to check to see if a specific
+ // attribute can not be inherited.
+ AttributeSet OldFnAttrs = oldFunction->getAttributes().getFnAttributes();
+ AttrBuilder AB(OldFnAttrs, 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.
diff --git a/llvm/test/Transforms/CodeExtractor/InheritTargetAttributes.ll b/llvm/test/Transforms/CodeExtractor/InheritTargetAttributes.ll
new file mode 100644
index 00000000000..41d883c8c37
--- /dev/null
+++ b/llvm/test/Transforms/CodeExtractor/InheritTargetAttributes.ll
@@ -0,0 +1,40 @@
+; RUN: opt < %s -partial-inliner | llc -filetype=null
+; RUN: opt < %s -partial-inliner -S | FileCheck %s
+; This testcase checks to see if CodeExtractor properly inherits
+; target specific attributes for the extracted function. This can
+; cause certain instructions that depend on the attributes to not
+; be lowered. Like in this test where we try to 'select' the blendvps
+; intrinsic on x86 that requires the +sse4.1 target feature.
+
+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: define {{.*}} @inlinedFunc.1_if.then{{.*}} [[COUNT1:#[0-9]+]]
+; CHECK: [[COUNT1]] = { {{.*}} "target-cpu"="x86-64" "target-features"="+sse4.1" }
OpenPOWER on IntegriCloud