diff --git a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp index 90f019620b5037..25c03e7fe479c5 100644 --- a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp +++ b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp @@ -2981,6 +2981,8 @@ struct AAHeapToSharedFunction : public AAHeapToShared { auto &OMPInfoCache = static_cast(A.getInfoCache()); auto &RFI = OMPInfoCache.RFIs[OMPRTL___kmpc_alloc_shared]; + if (!RFI.Declaration) + return; Attributor::SimplifictionCallbackTy SCB = [](const IRPosition &, const AbstractAttribute *, @@ -3085,6 +3087,9 @@ struct AAHeapToSharedFunction : public AAHeapToShared { ChangeStatus updateImpl(Attributor &A) override { auto &OMPInfoCache = static_cast(A.getInfoCache()); auto &RFI = OMPInfoCache.RFIs[OMPRTL___kmpc_alloc_shared]; + if (!RFI.Declaration) + return ChangeStatus::UNCHANGED; + Function *F = getAnchorScope(); auto NumMallocCalls = MallocCalls.size(); diff --git a/llvm/test/Transforms/OpenMP/heap-to-shared-missing-declarations.ll b/llvm/test/Transforms/OpenMP/heap-to-shared-missing-declarations.ll new file mode 100644 index 00000000000000..13a45c2c11dad9 --- /dev/null +++ b/llvm/test/Transforms/OpenMP/heap-to-shared-missing-declarations.ll @@ -0,0 +1,91 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals +; REQUIRES: amdgpu-registered-target +; RUN: opt -mtriple=amdgcn-amd-amdhsa -S -passes=openmp-opt < %s | FileCheck %s + +define internal void @outlined0() { +; CHECK: Function Attrs: nounwind +; CHECK-LABEL: define {{[^@]+}}@outlined0 +; CHECK-SAME: () #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: bb: +; CHECK-NEXT: call void @func() #[[ATTR0]] +; CHECK-NEXT: [[I:%.*]] = call i32 @__kmpc_get_hardware_num_threads_in_block() #[[ATTR0]] +; CHECK-NEXT: ret void +; +bb: + call void @func() + %i = call i32 @__kmpc_get_hardware_num_threads_in_block() + ret void +} + +define internal void @func() { +; CHECK: Function Attrs: nounwind +; CHECK-LABEL: define {{[^@]+}}@func +; CHECK-SAME: () #[[ATTR0]] { +; CHECK-NEXT: bb: +; CHECK-NEXT: [[I:%.*]] = load ptr, ptr null, align 4294967296 +; CHECK-NEXT: store i64 0, ptr [[I]], align 8 +; CHECK-NEXT: ret void +; +bb: + %i = load ptr, ptr addrspacecast (ptr addrspace(5) null to ptr), align 4294967296 + store i64 0, ptr %i, align 8 + ret void +} + +define internal void @outlined1() { +; CHECK: Function Attrs: nounwind +; CHECK-LABEL: define {{[^@]+}}@outlined1 +; CHECK-SAME: () #[[ATTR0]] { +; CHECK-NEXT: bb: +; CHECK-NEXT: [[I:%.*]] = icmp sle i32 1, 0 +; CHECK-NEXT: br i1 [[I]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: common.ret: +; CHECK-NEXT: ret void +; CHECK: bb1: +; CHECK-NEXT: call void @func() #[[ATTR0]] +; CHECK-NEXT: br label [[COMMON_RET:%.*]] +; CHECK: bb2: +; CHECK-NEXT: call void @__kmpc_free_shared(ptr null, i64 0) #[[ATTR0]] +; CHECK-NEXT: br label [[COMMON_RET]] +; +bb: + %i = icmp sle i32 1, 0 + br i1 %i, label %bb1, label %bb2 + +common.ret: ; preds = %bb2, %bb1 + ret void + +bb1: ; preds = %bb + call void @func() + br label %common.ret + +bb2: ; preds = %bb + call void @__kmpc_free_shared(ptr null, i64 0) + br label %common.ret +} + +define void @user() { +; CHECK-LABEL: define {{[^@]+}}@user() { +; CHECK-NEXT: call void @outlined0() #[[ATTR0]] +; CHECK-NEXT: call void @outlined1() #[[ATTR0]] +; CHECK-NEXT: ret void +; + call void @outlined0() + call void @outlined1() + ret void +} + +declare i32 @__kmpc_get_hardware_num_threads_in_block() +declare void @__kmpc_free_shared(ptr, i64) + +!llvm.module.flags = !{!0, !1} + +!0 = !{i32 7, !"openmp", i32 50} +!1 = !{i32 7, !"openmp-device", i32 50} +;. +; CHECK: attributes #[[ATTR0]] = { nounwind } +; CHECK: attributes #[[ATTR1:[0-9]+]] = { nosync nounwind } +;. +; CHECK: [[META0:![0-9]+]] = !{i32 7, !"openmp", i32 50} +; CHECK: [[META1:![0-9]+]] = !{i32 7, !"openmp-device", i32 50} +;.