brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.4 KiB · 94ace20 Raw
228 lines · cpp
1// Test target codegen - host bc file has to be created first.2// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc3// RUN: %clang_cc1 -debug-info-kind=limited -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-target-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-644// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc5// RUN: %clang_cc1 -debug-info-kind=limited -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-target-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-326// expected-no-diagnostics7#ifndef HEADER8#define HEADER9 10template <typename tx, typename ty>11struct TT {12  tx X;13  ty Y;14};15 16// TCHECK-DAG:  [[TTII:%.+]] = type { i32, i32 }17// TCHECK-DAG:  [[TT:%.+]] = type { i64, i8 }18// TCHECK-DAG:  [[S1:%.+]] = type { double }19 20int foo(int n, double *ptr) {21  int a = 0;22  short aa = 0;23  float b[10];24  double c[5][10];25  TT<long long, char> d;26  const TT<int, int> e = {n, n};27 28#pragma omp target firstprivate(a, e) map(tofrom \29                                          : b)30  {31    b[a] = a;32    b[a] += e.X;33  }34 35  // TCHECK:  define {{.*}}void @__omp_offloading_{{.+}}(ptr {{[^,]+}}, ptr addrspace(1) noalias noundef [[B_IN:%.+]], i{{[0-9]+}} noundef [[A_IN:%.+]], ptr noalias noundef [[E_IN:%.+]])36  // TCHECK:  [[DYN_PTR_ADDR:%.+]] = alloca ptr37  // TCHECK:  [[A_ADDR:%.+]] = alloca i{{[0-9]+}},38  // TCHECK-NOT: alloca [[TTII]],39  // TCHECK: alloca i{{[0-9]+}},40  // TCHECK:  store i{{[0-9]+}} [[A_IN]], ptr [[A_ADDR]],41  // TCHECK:  ret void42 43#pragma omp target firstprivate(aa, b, c, d)44  {45    aa += 1;46    b[2] = 1.0;47    c[1][2] = 1.0;48    d.X = 1;49    d.Y = 1;50  }51 52  // make sure that firstprivate variables are generated in all cases and that we use those instances for operations inside the53  // target region54  // TCHECK:  define {{.*}}void @__omp_offloading_{{.+}}(ptr {{[^,]+}}, i{{[0-9]+}}{{.*}} [[A2_IN:%.+]], ptr{{.*}} [[B_IN:%.+]], ptr{{.*}} [[C_IN:%.+]], ptr{{.*}} [[D_IN:%.+]])55  // TCHECK:  [[DYN_PTR_ADDR:%.+]] = alloca ptr56  // TCHECK:  [[A2_ADDR:%.+]] = alloca i{{[0-9]+}},57  // TCHECK:  [[B_ADDR:%.+]] = alloca ptr,58  // TCHECK:  [[C_ADDR:%.+]] = alloca ptr,59  // TCHECK:  [[D_ADDR:%.+]] = alloca ptr,60  // TCHECK-NOT: alloca i{{[0-9]+}},61  // TCHECK:  [[B_PRIV:%.+]] = alloca [10 x float],62  // TCHECK:  [[C_PRIV:%.+]] = alloca [5 x [10 x double]],63  // TCHECK:  [[D_PRIV:%.+]] = alloca [[TT]],64  // TCHECK:  store i{{[0-9]+}} [[A2_IN]], ptr [[A2_ADDR]],65  // TCHECK:  store ptr [[B_IN]], ptr [[B_ADDR]],66  // TCHECK:  store ptr [[C_IN]], ptr [[C_ADDR]],67  // TCHECK:  store ptr [[D_IN]], ptr [[D_ADDR]],68  // TCHECK:  [[B_ADDR_REF:%.+]] = load ptr, ptr [[B_ADDR]],69  // TCHECK:  [[B_ADDR_REF:%.+]] = load ptr, ptr %70  // TCHECK:  [[C_ADDR_REF:%.+]] = load ptr, ptr [[C_ADDR]],71  // TCHECK:  [[C_ADDR_REF:%.+]] = load ptr, ptr %72  // TCHECK:  [[D_ADDR_REF:%.+]] = load ptr, ptr [[D_ADDR]],73  // TCHECK:  [[D_ADDR_REF:%.+]] = load ptr, ptr %74 75  // firstprivate(aa): a_priv = a_in76 77  //  firstprivate(b): memcpy(b_priv,b_in)78  // TCHECK:  call void @llvm.memcpy.{{.+}}(ptr align {{[0-9]+}} [[B_PRIV]], ptr align {{[0-9]+}} [[B_ADDR_REF]], {{.+}})79 80  // firstprivate(c)81  // TCHECK:  call void @llvm.memcpy.{{.+}}(ptr align {{[0-9]+}} [[C_PRIV]], ptr align {{[0-9]+}} [[C_ADDR_REF]],{{.+}})82 83  // firstprivate(d)84  // TCHECK:  call void @llvm.memcpy.{{.+}}(ptr align {{[0-9]+}} [[D_PRIV]], ptr align {{[0-9]+}} [[D_ADDR_REF]],{{.+}})85 86  // TCHECK: load i16, ptr [[A2_ADDR]],87 88#pragma omp target firstprivate(ptr)89  {90    ptr[0]++;91  }92 93  // TCHECK:  define weak_odr protected ptx_kernel void @__omp_offloading_{{.+}}(ptr {{[^,]+}}, ptr noundef [[PTR_IN:%.+]])94  // TCHECK:  [[DYN_PTR_ADDR:%.+]] = alloca ptr,95  // TCHECK:  [[PTR_ADDR:%.+]] = alloca ptr,96  // TCHECK-NOT: alloca ptr,97  // TCHECK:  store ptr [[PTR_IN]], ptr [[PTR_ADDR]],98  // TCHECK:  [[PTR_IN_REF:%.+]] = load ptr, ptr [[PTR_ADDR]],99  // TCHECK-NOT:  store ptr [[PTR_IN_REF]], ptr {{%.+}},100 101  return a;102}103 104template <typename tx>105tx ftemplate(int n) {106  tx a = 0;107  tx b[10];108 109#pragma omp target firstprivate(a, b)110  {111    a += 1;112    b[2] += 1;113  }114 115  return a;116}117 118static int fstatic(int n) {119  int a = 0;120  char aaa = 0;121  int b[10];122 123#pragma omp target firstprivate(a, aaa, b)124  {125    a += 1;126    aaa += 1;127    b[2] += 1;128  }129 130  return a;131}132 133template <typename tx>134void fconst(const tx t) {135#pragma omp target firstprivate(t)136  { }137}138 139// TCHECK: define {{.*}}void @__omp_offloading_{{.+}}(ptr {{[^,]+}}, i{{[0-9]+}}{{.*}} [[A_IN:%.+]], i{{[0-9]+}}{{.*}} [[A3_IN:%.+]], ptr {{.+}} [[B_IN:%.+]])140// TCHECK:  [[DYN_PTR_ADDR:%.+]] = alloca ptr141// TCHECK:  [[A_ADDR:%.+]] = alloca i{{[0-9]+}},142// TCHECK:  [[A3_ADDR:%.+]] = alloca i{{[0-9]+}},143// TCHECK:  [[B_ADDR:%.+]] = alloca ptr,144// TCHECK-NOT:  alloca i{{[0-9]+}},145// TCHECK:  [[B_PRIV:%.+]] = alloca [10 x i{{[0-9]+}}],146// TCHECK:  store i{{[0-9]+}} [[A_IN]], ptr [[A_ADDR]],147// TCHECK:  store i{{[0-9]+}} [[A3_IN]], ptr [[A3_ADDR]],148// TCHECK:  store ptr [[B_IN]], ptr [[B_ADDR]],149// TCHECK:  [[B_ADDR_REF:%.+]] = load ptr, ptr [[B_ADDR]],150// TCHECK:  [[B_ADDR_REF:%.+]] = load ptr, ptr %151 152// firstprivate(a): a_priv = a_in153 154// firstprivate(aaa)155 156// TCHECK-NOT:  store i{{[0-9]+}} %{{.+}}, ptr157 158// firstprivate(b)159// TCHECK:  call void @llvm.memcpy.{{.+}}(ptr align {{[0-9]+}} [[B_PRIV]], ptr align {{[0-9]+}} [[B_ADDR_REF]],{{.+}})160// TCHECK:  ret void161 162struct S1 {163  double a;164 165  int r1(int n) {166    int b = n + 1;167 168#pragma omp target firstprivate(b)169    {170      this->a = (double)b + 1.5;171    }172 173    return (int)b;174  }175 176  // TCHECK: define internal void @__omp_offloading_{{.+}}(ptr {{[^,]+}}, ptr noundef [[TH:%.+]], i{{[0-9]+}} noundef [[B_IN:%.+]])177  // TCHECK:  [[DYN_PTR_ADDR:%.+]] = alloca ptr178  // TCHECK:  [[TH_ADDR:%.+]] = alloca ptr,179  // TCHECK:  [[B_ADDR:%.+]] = alloca i{{[0-9]+}},180  // TCHECK-NOT: alloca i{{[0-9]+}},181 182  // TCHECK:  store ptr [[TH]], ptr [[TH_ADDR]],183  // TCHECK:  store i{{[0-9]+}} [[B_IN]], ptr [[B_ADDR]],184  // TCHECK:  [[TH_ADDR_REF:%.+]] = load ptr, ptr [[TH_ADDR]],185 186  // firstprivate(b)187  // TCHECK-NOT:  store i{{[0-9]+}} %{{.+}}, ptr188 189  // TCHECK: ret void190};191 192int bar(int n, double *ptr) {193  int a = 0;194  a += foo(n, ptr);195  S1 S;196  a += S.r1(n);197  a += fstatic(n);198  a += ftemplate<int>(n);199 200  fconst(TT<int, int>{0, 0});201  fconst(TT<char, char>{0, 0});202 203  return a;204}205 206// template207 208// TCHECK: define internal void @__omp_offloading_{{.+}}(ptr {{[^,]+}}, i{{[0-9]+}} noundef [[A_IN:%.+]], ptr{{.+}} noundef [[B_IN:%.+]])209// TCHECK:  [[DYN_PTR_ADDR:%.+]] = alloca ptr210// TCHECK:  [[A_ADDR:%.+]] = alloca i{{[0-9]+}},211// TCHECK:  [[B_ADDR:%.+]] = alloca ptr,212// TCHECK-NOT: alloca i{{[0-9]+}},213// TCHECK:  [[B_PRIV:%.+]] = alloca [10 x i{{[0-9]+}}],214// TCHECK:  store i{{[0-9]+}} [[A_IN]], ptr [[A_ADDR]],215// TCHECK:  store ptr [[B_IN]], ptr [[B_ADDR]],216// TCHECK:  [[B_ADDR_REF:%.+]] = load ptr, ptr [[B_ADDR]],217// TCHECK:  [[B_ADDR_REF:%.+]] = load ptr, ptr %218 219// firstprivate(a)220// TCHECK-NOT:  store i{{[0-9]+}} %{{.+}}, ptr221 222// firstprivate(b)223// TCHECK:  call void @llvm.memcpy.{{.+}}(ptr align {{[0-9]+}} [[B_PRIV]], ptr align {{[0-9]+}} [[B_ADDR_REF]],{{.+}})224 225// TCHECK: ret void226 227#endif228