llvm-project/clang/test/OpenMP/amdgcn_weak_alias.cpp
Jason-VanBeusekom 4394aa685c
[OpenMP][clang][HIP][CUDA] fix weak alias emit on device compilation (#164326)
This PR adds checks for when emitting weak aliases in: `void
CodeGenModule::EmitGlobal(GlobalDecl GD)`, before for device compilation
for OpenMP, HIP and Cuda, clang would look for the aliasee even if it
was never marked for device compilation.

For OpenMP the following case now works:

> Failed before when compiling with device, ie: `clang -fopenmp
-fopenmp-targets=amdgcn-amd-amdhsa`
>   ```
>   int __Two(void) { return 2; }
>   int Two(void) __attribute__ ((weak, alias("__Two")));
>   ```

For HIP / Cuda:

> 
> ```
> int __HostFunc(void) { return 42; }
> int HostFunc(void) __attribute__ ((weak, alias("__HostFunc")));
> ```

For HIP:

>Failed before on HIP, Cuda fails due to: `NVPTX aliasee must not be
'.weak'` error
> ``` 
> __device__ int __One(void) { return 2; }
> __device__ int One(void) __attribute__ ((weak, alias("__One")));
> ```

Included are Codegen LIT tests for the above cases, and also cases for
weak alias cases that currently work in clang.

Fixes https://github.com/llvm/llvm-project/issues/117369
2025-11-27 09:05:24 -05:00

116 lines
5.4 KiB
C++

// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --version 6
// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fopenmp-targets=amdgcn-amd-amdhsa -emit-llvm-bc %s -o %t-ppc-host.bc
// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fopenmp-targets=amdgcn-amd-amdhsa -emit-llvm %s -o - | FileCheck %s --check-prefix=HOST
// RUN: %clang_cc1 -fopenmp -x c++ -triple amdgcn-amd-amdhsa -fopenmp-targets=amdgcn-amd-amdhsa -emit-llvm %s -fopenmp-is-target-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix=DEVICE
//.
// HOST: @_Z3Onev = weak alias i32 (), ptr @_Z5__Onev
// HOST: @_Z3Onef = weak alias float (float), ptr @_Z5__Onef
// HOST: @_Z4One_v = alias i32 (), ptr @_Z5__Onev
// HOST: @_Z4One_f = alias float (float), ptr @_Z5__Onef
// HOST: @_Z3Twov = weak alias i32 (), ptr @_Z5__Twov
// HOST: @_Z3Twof = weak alias float (float), ptr @_Z5__Twof
// HOST: @_Z4Two_v = alias i32 (), ptr @_Z5__Twov
// HOST: @_Z4Two_f = alias float (float), ptr @_Z5__Twof
// HOST: @_Z5Threev = weak alias i32 (), ptr @_Z7__Threev
// HOST: @_Z6Three_v = alias i32 (), ptr @_Z7__Threev
// HOST: @_Z4Fourv = weak alias i32 (), ptr @_Z6__Fourv
// HOST: @_Z5Four_v = alias i32 (), ptr @_Z6__Fourv
//.
// DEVICE: @_Z3Twov = weak hidden alias i32 (), ptr @_Z5__Twov
// DEVICE: @_Z3Twof = weak hidden alias float (float), ptr @_Z5__Twof
// DEVICE: @_Z4Two_v = hidden alias i32 (), ptr @_Z5__Twov
// DEVICE: @_Z4Two_f = hidden alias float (float), ptr @_Z5__Twof
// DEVICE: @_Z5Threev = weak hidden alias i32 (), ptr @_Z7__Threev
// DEVICE: @_Z6Three_v = hidden alias i32 (), ptr @_Z7__Threev
//.
// HOST-LABEL: define dso_local noundef i32 @_Z5__Onev(
// HOST-SAME: ) #[[ATTR0:[0-9]+]] {
// HOST-NEXT: [[ENTRY:.*:]]
// HOST-NEXT: ret i32 1
//
int __One(void) { return 1; }
// HOST-LABEL: define dso_local noundef float @_Z5__Onef(
// HOST-SAME: float noundef [[F:%.*]]) #[[ATTR0]] {
// HOST-NEXT: [[ENTRY:.*:]]
// HOST-NEXT: [[F_ADDR:%.*]] = alloca float, align 4
// HOST-NEXT: store float [[F]], ptr [[F_ADDR]], align 4
// HOST-NEXT: [[TMP0:%.*]] = load float, ptr [[F_ADDR]], align 4
// HOST-NEXT: [[MUL:%.*]] = fmul float 1.000000e+00, [[TMP0]]
// HOST-NEXT: ret float [[MUL]]
//
float __One(float f) { return 1.0f * f; }
int One(void) __attribute__((weak, alias("_Z5__Onev")));
float One(float f) __attribute__((weak, alias("_Z5__Onef")));
int One_(void) __attribute__((alias("_Z5__Onev")));
float One_(float f) __attribute__((alias("_Z5__Onef")));
#pragma omp declare target
// HOST-LABEL: define dso_local noundef i32 @_Z5__Twov(
// HOST-SAME: ) #[[ATTR0]] {
// HOST-NEXT: [[ENTRY:.*:]]
// HOST-NEXT: ret i32 2
//
// DEVICE-LABEL: define hidden noundef i32 @_Z5__Twov(
// DEVICE-SAME: ) #[[ATTR0:[0-9]+]] {
// DEVICE-NEXT: [[ENTRY:.*:]]
// DEVICE-NEXT: [[RETVAL:%.*]] = alloca i32, align 4, addrspace(5)
// DEVICE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr
// DEVICE-NEXT: ret i32 2
//
int __Two(void) { return 2; }
// HOST-LABEL: define dso_local noundef float @_Z5__Twof(
// HOST-SAME: float noundef [[F:%.*]]) #[[ATTR0]] {
// HOST-NEXT: [[ENTRY:.*:]]
// HOST-NEXT: [[F_ADDR:%.*]] = alloca float, align 4
// HOST-NEXT: store float [[F]], ptr [[F_ADDR]], align 4
// HOST-NEXT: [[TMP0:%.*]] = load float, ptr [[F_ADDR]], align 4
// HOST-NEXT: [[MUL:%.*]] = fmul float 2.000000e+00, [[TMP0]]
// HOST-NEXT: ret float [[MUL]]
//
// DEVICE-LABEL: define hidden noundef float @_Z5__Twof(
// DEVICE-SAME: float noundef [[F:%.*]]) #[[ATTR0]] {
// DEVICE-NEXT: [[ENTRY:.*:]]
// DEVICE-NEXT: [[RETVAL:%.*]] = alloca float, align 4, addrspace(5)
// DEVICE-NEXT: [[F_ADDR:%.*]] = alloca float, align 4, addrspace(5)
// DEVICE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr
// DEVICE-NEXT: [[F_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[F_ADDR]] to ptr
// DEVICE-NEXT: store float [[F]], ptr [[F_ADDR_ASCAST]], align 4
// DEVICE-NEXT: [[TMP0:%.*]] = load float, ptr [[F_ADDR_ASCAST]], align 4
// DEVICE-NEXT: [[MUL:%.*]] = fmul float 2.000000e+00, [[TMP0]]
// DEVICE-NEXT: ret float [[MUL]]
//
float __Two(float f) { return 2.0f * f; }
int Two(void) __attribute__((weak, alias("_Z5__Twov")));
float Two(float f) __attribute__((weak, alias("_Z5__Twof")));
int Two_(void) __attribute__((alias("_Z5__Twov")));
float Two_(float f) __attribute__((alias("_Z5__Twof")));
#pragma omp end declare target
#pragma omp declare target
// HOST-LABEL: define linkonce_odr noundef i32 @_Z7__Threev(
// HOST-SAME: ) #[[ATTR0]] comdat {
// HOST-NEXT: [[ENTRY:.*:]]
// HOST-NEXT: ret i32 3
//
// DEVICE-LABEL: define linkonce_odr hidden noundef i32 @_Z7__Threev(
// DEVICE-SAME: ) #[[ATTR0]] comdat {
// DEVICE-NEXT: [[ENTRY:.*:]]
// DEVICE-NEXT: [[RETVAL:%.*]] = alloca i32, align 4, addrspace(5)
// DEVICE-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr
// DEVICE-NEXT: ret i32 3
//
constexpr int __Three(void) { return 3; }
int Three(void) __attribute__((weak, alias("_Z7__Threev")));
int Three_(void) __attribute__((alias("_Z7__Threev")));
#pragma omp end declare target
// HOST-LABEL: define linkonce_odr noundef i32 @_Z6__Fourv(
// HOST-SAME: ) #[[ATTR0]] comdat {
// HOST-NEXT: [[ENTRY:.*:]]
// HOST-NEXT: ret i32 4
//
constexpr int __Four(void) { return 4; }
int Four(void) __attribute__((weak, alias("_Z6__Fourv")));
int Four_(void) __attribute__((alias("_Z6__Fourv")));