if (F.isDeclaration())
continue;
- // Skip propagating attributes and features to
- // address taken functions.
- if (F.hasAddressTaken()) {
- if (!Roots.count(&F))
- NewRoots.insert(&F);
- continue;
- }
-
const FnProperties CalleeProps(*TM, F);
SmallVector<std::pair<CallBase *, Function *>, 32> ToReplace;
SmallSet<CallBase *, 32> Visited;
const FnProperties CallerProps(*TM, *Caller);
- // Convergence is allowed if the caller has its
- // address taken because all callee's (attributes + features)
- // may not agree as the callee may be the target of
- // more than one function (called directly or indirectly).
- if (Caller->hasAddressTaken() || CalleeProps == CallerProps) {
+ if (CalleeProps == CallerProps) {
if (!Roots.count(&F))
NewRoots.insert(&F);
continue;
+++ /dev/null
-; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -amdgpu-propagate-attributes-early %s | FileCheck %s
-
-; Complicated call graph where a function is called
-; directly from a kernel abd also from a function
-; whose address is taken.
-
-; CHECK-LABEL: define float @common_callee.gc() #0 {
-define float @common_callee.gc() {
- ret float 0.0
-}
-
-; CHECK-LABEL: define float @foo() {
-define float @foo() {
- ret float 0.0
-}
-
-; CHECK-LABEL: define float @bar() {
-define float @bar() {
- ret float 0.0
-}
-
-; CHECK-LABEL: define float @baz() {
-define float @baz() {
- ret float 0.0
-}
-
-define amdgpu_kernel void @switch_indirect_kernel(float *%result, i32 %type) #1 {
- %fn = alloca float ()*
- switch i32 %type, label %sw.default [
- i32 1, label %sw.bb
- i32 2, label %sw.bb2
- i32 3, label %sw.bb3
- ]
-
-sw.bb:
- store float ()* @foo, float ()** %fn
- br label %sw.epilog
-
-sw.bb2:
- store float ()* @bar, float ()** %fn
- br label %sw.epilog
-
-sw.bb3:
- store float ()* @baz, float ()** %fn
- br label %sw.epilog
-
-sw.default:
- br label %sw.epilog
-
-sw.epilog:
- %fp = load float ()*, float ()** %fn
- %direct_call = call contract float @common_callee.gc()
- %indirect_call = call contract float %fp()
- store float %indirect_call, float* %result
- ret void
-}
-
-attributes #0 = { "amdgpu-flat-work-group-size"="1,256" "target-features"="-wavefrontsize16,-wavefrontsize32,+wavefrontsize64" }
-attributes #1 = { "amdgpu-flat-work-group-size"="1,256" }
+++ /dev/null
-; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -amdgpu-propagate-attributes-early %s | FileCheck %s
-
-; Test to check if we skip propgating attributes even if
-; a function is called directly as well as
-; indirectly. "baz" is called directly as well indirectly.
-
-; CHECK-LABEL: define float @foo() {
-define float @foo() {
- ret float 0.0
-}
-
-; CHECK-LABEL: define float @bar() {
-define float @bar() {
- ret float 0.0
-}
-
-; CHECK-LABEL: define float @baz() {
-define float @baz() {
- ret float 0.0
-}
-
-define amdgpu_kernel void @switch_indirect_kernel(float *%result, i32 %type) #1 {
- %fn = alloca float ()*
- switch i32 %type, label %sw.default [
- i32 1, label %sw.bb
- i32 2, label %sw.bb2
- i32 3, label %sw.bb3
- ]
-
-sw.bb:
- store float ()* @foo, float ()** %fn
- br label %sw.epilog
-
-sw.bb2:
- store float ()* @bar, float ()** %fn
- br label %sw.epilog
-
-sw.bb3:
- store float ()* @baz, float ()** %fn
- br label %sw.epilog
-
-sw.default:
- br label %sw.epilog
-
-sw.epilog:
- %fp = load float ()*, float ()** %fn
- %direct_call = call contract float @baz()
- %indirect_call = call contract float %fp()
- store float %indirect_call, float* %result
- ret void
-}
-
-attributes #1 = { "amdgpu-flat-work-group-size"="1,256" }
+++ /dev/null
-; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -amdgpu-propagate-attributes-early %s | FileCheck %s
-
-; Test to check if we skip attributes on address
-; taken functions but pass to direct callees.
-
-; CHECK-LABEL: define float @foo() {
-define float @foo() {
- ret float 0.0
-}
-
-; CHECK-LABEL: define float @bar() {
-define float @bar() {
- ret float 0.0
-}
-
-; CHECK-LABEL: define float @baz() {
-define float @baz() {
- ret float 0.0
-}
-
-; CHECK-LABEL: define float @baz2() #0 {
-define float @baz2() {
- ret float 0.0
-}
-
-define amdgpu_kernel void @switch_indirect_kernel(float *%result, i32 %type) #1 {
- %fn = alloca float ()*
- switch i32 %type, label %sw.default [
- i32 1, label %sw.bb
- i32 2, label %sw.bb2
- i32 3, label %sw.bb3
- ]
-
-sw.bb:
- store float ()* @foo, float ()** %fn
- br label %sw.epilog
-
-sw.bb2:
- store float ()* @bar, float ()** %fn
- br label %sw.epilog
-
-sw.bb3:
- store float ()* @baz, float ()** %fn
- br label %sw.epilog
-
-sw.default:
- br label %sw.epilog
-
-sw.epilog:
- %fp = load float ()*, float ()** %fn
- %direct_call = call contract float @baz2()
- %indirect_call = call contract float %fp()
- store float %indirect_call, float* %result
- ret void
-}
-
-attributes #0 = { "amdgpu-flat-work-group-size"="1,256" "target-features"="-wavefrontsize16,-wavefrontsize32,+wavefrontsize64" }
-attributes #1 = { "amdgpu-flat-work-group-size"="1,256"}
+++ /dev/null
-; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -amdgpu-propagate-attributes-early %s | FileCheck %s
-
-; Test to check if we skip attributes on address
-; taken functions in a simple call graph.
-
-; CHECK-LABEL: define float @foo() {
-define float @foo() {
- ret float 0.0
-}
-
-; CHECK-LABEL: define float @bar() {
-define float @bar() {
- ret float 0.0
-}
-
-; CHECK-LABEL: define float @baz() {
-define float @baz() {
- ret float 0.0
-}
-
-define amdgpu_kernel void @switch_indirect_kernel(float *%result, i32 %type) #1 {
- %fn = alloca float ()*
- switch i32 %type, label %sw.default [
- i32 1, label %sw.bb
- i32 2, label %sw.bb2
- i32 3, label %sw.bb3
- ]
-
-sw.bb:
- store float ()* @foo, float ()** %fn
- br label %sw.epilog
-
-sw.bb2:
- store float ()* @bar, float ()** %fn
- br label %sw.epilog
-
-sw.bb3:
- store float ()* @baz, float ()** %fn
- br label %sw.epilog
-
-sw.default:
- br label %sw.epilog
-
-sw.epilog:
- %fp = load float ()*, float ()** %fn
- %indirect_call = call contract float %fp()
- store float %indirect_call, float* %result
- ret void
-}
-
-attributes #1 = { "amdgpu-flat-work-group-size"="1,256" }
-