diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/IR/Attributes.cpp | 28 | ||||
| -rw-r--r-- | llvm/test/Transforms/Inline/inline-min-legal-vector-width.ll | 17 |
2 files changed, 32 insertions, 13 deletions
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index cdc13843465..ff46debb7a9 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -1685,28 +1685,32 @@ adjustCallerStackProbeSize(Function &Caller, const Function &Callee) { } /// If the inlined function defines a min legal vector width, then ensure -/// the calling function has the same or larger min legal vector width. This -/// function is called after the inlining decision has been made so we have to -/// merge the attribute this way. Heuristics that would use +/// the calling function has the same or larger min legal vector width. If the +/// caller has the attribute, but the callee doesn't, we need to remove the +/// attribute from the caller since we can't make any guarantees about the +/// caller's requirements. +/// This function is called after the inlining decision has been made so we have +/// to merge the attribute this way. Heuristics that would use /// min-legal-vector-width to determine inline compatibility would need to be /// handled as part of inline cost analysis. static void adjustMinLegalVectorWidth(Function &Caller, const Function &Callee) { - if (Callee.hasFnAttribute("min-legal-vector-width")) { - uint64_t CalleeVectorWidth; - Callee.getFnAttribute("min-legal-vector-width") - .getValueAsString() - .getAsInteger(0, CalleeVectorWidth); - if (Caller.hasFnAttribute("min-legal-vector-width")) { + if (Caller.hasFnAttribute("min-legal-vector-width")) { + if (Callee.hasFnAttribute("min-legal-vector-width")) { uint64_t CallerVectorWidth; Caller.getFnAttribute("min-legal-vector-width") .getValueAsString() .getAsInteger(0, CallerVectorWidth); - if (CallerVectorWidth < CalleeVectorWidth) { + uint64_t CalleeVectorWidth; + Callee.getFnAttribute("min-legal-vector-width") + .getValueAsString() + .getAsInteger(0, CalleeVectorWidth); + if (CallerVectorWidth < CalleeVectorWidth) Caller.addFnAttr(Callee.getFnAttribute("min-legal-vector-width")); - } } else { - Caller.addFnAttr(Callee.getFnAttribute("min-legal-vector-width")); + // If the callee doesn't have the attribute then we don't know anything + // and must drop the attribute from the caller. + Caller.removeFnAttr("min-legal-vector-width"); } } } diff --git a/llvm/test/Transforms/Inline/inline-min-legal-vector-width.ll b/llvm/test/Transforms/Inline/inline-min-legal-vector-width.ll index cc00b5e00a7..ec727419f01 100644 --- a/llvm/test/Transforms/Inline/inline-min-legal-vector-width.ll +++ b/llvm/test/Transforms/Inline/inline-min-legal-vector-width.ll @@ -8,6 +8,13 @@ define internal void @innerLarge() "min-legal-vector-width"="512" { ret void } +define internal void @innerNoAttribute() { + ret void +} + +; We should not add an attribute during inlining. No attribute means unknown. +; Inlining doesn't change the fact that we don't know anything about this +; function. define void @outerNoAttribute() { call void @innerLarge() ret void @@ -23,7 +30,15 @@ define void @outerConflictingAttributeLarge() "min-legal-vector-width"="512" { ret void } -; CHECK: define void @outerNoAttribute() #0 +; We should remove the attribute after inlining since the callee's +; vector width requirements are unknown. +define void @outerAttribute() "min-legal-vector-width"="128" { + call void @innerNoAttribute() + ret void +} + +; CHECK: define void @outerNoAttribute() { ; CHECK: define void @outerConflictingAttributeSmall() #0 ; CHECK: define void @outerConflictingAttributeLarge() #0 +; CHECK: define void @outerAttribute() { ; CHECK: attributes #0 = { "min-legal-vector-width"="512" } |

