diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.h b/llvm/lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.h --- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.h @@ -67,6 +67,18 @@ unsigned getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index); /// @} + + bool areInlineCompatible(const Function *Caller, + const Function *Callee) const { + // Since WebAssembly supports target features at the module level rather + // than the function level, the backend will take the union of all features + // and apply it to each function. That means that any function can be + // inlined into any other function regardless of the features + // used. Frontends should set features on the target machine properly to + // prevent features from being "forgotten" because all the functions that + // use them were inlined and removed from the module. + return true; + } }; } // end namespace llvm diff --git a/llvm/test/Transforms/Inline/WebAssembly/inline-target-features.ll b/llvm/test/Transforms/Inline/WebAssembly/inline-target-features.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/Inline/WebAssembly/inline-target-features.ll @@ -0,0 +1,27 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -mtriple=wasm32-unknown-unknown -S -inline | FileCheck %s + +; Check that having different target attributes or cpus does not +; inhibit inlining. + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +define void @bar() #0 { +; CHECK-LABEL: @bar( +; CHECK-NEXT: tail call void @foo() +; CHECK-NEXT: ret void +; + tail call fastcc void @inline_me() + ret void +} + +define internal void @inline_me() #1 { + tail call void @foo() + ret void +} + +declare void @foo() + +attributes #0 = { "target-cpu"="mvp" "target-features"="+simd128" } +attributes #1 = { "target-cpu"="bleeding-edge" "target-features"="+multivalue" }