diff --git a/llvm/lib/Target/SystemZ/SystemZTargetTransformInfo.cpp b/llvm/lib/Target/SystemZ/SystemZTargetTransformInfo.cpp index 06a0a3a631654..e0b0099466c52 100644 --- a/llvm/lib/Target/SystemZ/SystemZTargetTransformInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZTargetTransformInfo.cpp @@ -422,6 +422,20 @@ bool SystemZTTIImpl::isLSRCostLess(const TargetTransformInfo::LSRCost &C1, C2.ScaleCost, C2.SetupCost); } +bool SystemZTTIImpl::areInlineCompatible(const Function *Caller, + const Function *Callee) const { + const TargetMachine &TM = getTLI()->getTargetMachine(); + + const FeatureBitset &CallerBits = + TM.getSubtargetImpl(*Caller)->getFeatureBits(); + const FeatureBitset &CalleeBits = + TM.getSubtargetImpl(*Callee)->getFeatureBits(); + + // Support only equal feature bitsets. Restriction should be relaxed in the + // future to allow inlining when callee's bits are subset of the caller's. + return CallerBits == CalleeBits; +} + unsigned SystemZTTIImpl::getNumberOfRegisters(unsigned ClassID) const { bool Vector = (ClassID == 1); if (!Vector) diff --git a/llvm/lib/Target/SystemZ/SystemZTargetTransformInfo.h b/llvm/lib/Target/SystemZ/SystemZTargetTransformInfo.h index 512fcc854d532..e64b1f1ccbd93 100644 --- a/llvm/lib/Target/SystemZ/SystemZTargetTransformInfo.h +++ b/llvm/lib/Target/SystemZ/SystemZTargetTransformInfo.h @@ -62,6 +62,10 @@ class SystemZTTIImpl : public BasicTTIImplBase { bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1, const TargetTransformInfo::LSRCost &C2); + + bool areInlineCompatible(const Function *Caller, + const Function *Callee) const; + /// @} /// \name Vector TTI Implementations diff --git a/llvm/test/Transforms/Inline/SystemZ/inline-target-attr.ll b/llvm/test/Transforms/Inline/SystemZ/inline-target-attr.ll new file mode 100644 index 0000000000000..b5c4f42655bb4 --- /dev/null +++ b/llvm/test/Transforms/Inline/SystemZ/inline-target-attr.ll @@ -0,0 +1,42 @@ +; RUN: opt < %s -mtriple=s390x-linux-gnu -S -passes=inline | FileCheck %s +; RUN: opt < %s -mtriple=s390x-linux-gnu -S -passes='cgscc(inline)' | FileCheck %s +; Check that we only inline when we have equal target attributes. + +define i32 @foo() #0 { +entry: + %call = call i32 (...) @baz() + ret i32 %call +; CHECK-LABEL: foo +; CHECK: call i32 (...) @baz() +} + +declare i32 @baz(...) #0 + +define i32 @bar() #1 { +entry: + %call = call i32 @foo() + ret i32 %call +; CHECK-LABEL: bar +; CHECK: call i32 @foo() +} + +define i32 @qux() #0 { +entry: + %call = call i32 @foo() + ret i32 %call +; CHECK-LABEL: qux +; CHECK: call i32 (...) @baz() +} + +define i32 @quux() #2 { +entry: + %call = call i32 @bar() + ret i32 %call +; CHECK-LABEL: quux +; CHECK: call i32 @bar() +} + + +attributes #0 = { "target-cpu"="generic" "target-features"="+guarded-storage" } +attributes #1 = { "target-cpu"="generic" "target-features"="+guarded-storage,+enhanced-sort" } +attributes #2 = { "target-cpu"="generic" "target-features"="+concurrent-functions" } diff --git a/llvm/test/Transforms/Inline/SystemZ/lit.local.cfg b/llvm/test/Transforms/Inline/SystemZ/lit.local.cfg new file mode 100644 index 0000000000000..f9dd98a21cc3e --- /dev/null +++ b/llvm/test/Transforms/Inline/SystemZ/lit.local.cfg @@ -0,0 +1,2 @@ +if not "SystemZ" in config.root.targets: + config.unsupported = True