brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.7 KiB · 0358f71 Raw
206 lines · plain
1// Test code-gen for `omp.parallel` ops with delayed privatizers (i.e. using2// `omp.private` ops).3 4// RUN: mlir-translate -mlir-to-llvmir -split-input-file %s | FileCheck %s5 6llvm.func @parallel_op_firstprivate(%arg0: !llvm.ptr) {7  omp.parallel private(@x.privatizer %arg0 -> %arg2 : !llvm.ptr) {8    %0 = llvm.load %arg2 : !llvm.ptr -> f329    omp.terminator10  }11  llvm.return12}13 14omp.private {type = firstprivate} @x.privatizer : f32 copy {15^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr):16  %0 = llvm.load %arg0 : !llvm.ptr -> f3217  llvm.store %0, %arg1 : f32, !llvm.ptr18  omp.yield(%arg1 : !llvm.ptr)19}20 21// CHECK-LABEL: @parallel_op_firstprivate22// CHECK-SAME: (ptr %[[ORIG:.*]]) {23// CHECK: %[[OMP_PAR_ARG:.*]] = alloca { ptr }, align 824// CHECK: %[[ORIG_GEP:.*]] = getelementptr { ptr }, ptr %[[OMP_PAR_ARG]], i32 0, i32 025// CHECK: store ptr %[[ORIG]], ptr %[[ORIG_GEP]], align 826// CHECK: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @1, i32 1, ptr @parallel_op_firstprivate..omp_par, ptr %[[OMP_PAR_ARG]])27// CHECK: }28 29// CHECK-LABEL: void @parallel_op_firstprivate..omp_par30// CHECK-SAME: (ptr noalias %{{.*}}, ptr noalias %{{.*}}, ptr %[[ARG:.*]])31// CHECK: %[[ORIG_PTR_PTR:.*]] = getelementptr { ptr }, ptr %[[ARG]], i32 0, i32 032// CHECK: %[[ORIG_PTR:.*]] = load ptr, ptr %[[ORIG_PTR_PTR]], align 833 34// Check that the privatizer alloc region was inlined properly.35// CHECK: %[[PRIV_ALLOC:.*]] = alloca float, align 436 37// Check that the privatizer copy region was inlined properly.38 39// CHECK: %[[ORIG_VAL:.*]] = load float, ptr %[[ORIG_PTR]], align 440// CHECK: store float %[[ORIG_VAL]], ptr %[[PRIV_ALLOC]], align 441// CHECK-NEXT: br42 43// Check that the privatized value is used (rather than the original one).44// CHECK: load float, ptr %[[PRIV_ALLOC]], align 445// CHECK: }46 47// -----48 49llvm.func @parallel_op_firstprivate_multi_block(%arg0: !llvm.ptr) {50  omp.parallel private(@multi_block.privatizer %arg0 -> %arg2 : !llvm.ptr) {51    %0 = llvm.load %arg2 : !llvm.ptr -> f3252    omp.terminator53  }54  llvm.return55}56 57// CHECK-LABEL: define internal void @parallel_op_firstprivate_multi_block..omp_par58// CHECK: omp.par.entry:59// CHECK:  %[[ORIG_PTR_PTR:.*]] = getelementptr { ptr }, ptr %{{.*}}, i32 0, i32 060// CHECK:  %[[ORIG_PTR:.*]] = load ptr, ptr %[[ORIG_PTR_PTR]], align 861// CHECK:  %[[PRIV_ALLOC:.*]] = alloca float, align 462// CHECK-NEXT: br label %omp.region.after_alloca63 64// CHECK: omp.region.after_alloca:65// CHECK-NEXT:   br label %[[PAR_REG:.*]]66 67// Check that the body of the parallel region loads from the private clone.68// CHECK: [[PAR_REG]]:69// CHECK:   br label %[[PRIV_BB1:.*]]70 71// CHECK: [[PRIV_BB1]]:72// The 1st `alloc` block directly branches to the 2nd `alloc` block since the73// only insruction is `llvm.mlir.constant` which gets translated to compile-time74// constant in LLVM IR.75// CHECK-NEXT: br label %[[PRIV_BB2:.*]]76 77// CHECK: [[PRIV_BB2]]:78// CHECK-NEXT: br label %[[PRIV_BB3:.*]]79 80// CHECK: [[PRIV_BB3]]:81// CHECK-NEXT: br label %omp.region.cont82 83// CHECK: omp.region.cont:84// CHECK-NEXT: %[[PRIV_ALLOC2:.*]] = phi ptr [ %[[PRIV_ALLOC]], %[[PRIV_BB3]] ]85// CHECK-NEXT: br label %omp.private.copy86 87// CHECK: omp.private.copy:88// CHECK-NEXT: br label %omp.private.copy489 90// CHECK: omp.private.copy4:91// CHECK-NEXT: %[[ORIG_VAL:.*]] = load float, ptr %[[ORIG_PTR]], align 492// CHECK-NEXT: br label %[[PRIV_BB3:.*]]93 94// Check contents of the 2nd block in the `copy` region.95// CHECK: [[PRIV_BB3]]:96// CHECK-NEXT: %[[ORIG_VAL2:.*]] = phi float [ %[[ORIG_VAL]], %omp.private.copy4 ]97// CHECK-NEXT: %[[PRIV_ALLOC3:.*]] = phi ptr [ %[[PRIV_ALLOC2]], %omp.private.copy4 ]98// CHECK-NEXT: store float %[[ORIG_VAL2]], ptr %[[PRIV_ALLOC3]], align 499// CHECK-NEXT: br label %[[PRIV_CONT:.*]]100 101// Check that the privatizer's continuation block yileds the private clone's102// address.103// CHECK: [[PRIV_CONT]]:104// CHECK-NEXT:   %[[PRIV_ALLOC4:.*]] = phi ptr [ %[[PRIV_ALLOC3]], %[[PRIV_BB3]] ]105// CHECK:        %{{.*}} = load float, ptr %[[PRIV_ALLOC2]], align 4106 107omp.private {type = firstprivate} @multi_block.privatizer : f32 init {108^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr):109  llvm.br ^bb1110 111^bb1:112  omp.yield(%arg1 : !llvm.ptr)113 114} copy {115^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr):116  %0 = llvm.load %arg0 : !llvm.ptr -> f32117  llvm.br ^bb1(%0, %arg1 : f32, !llvm.ptr)118 119^bb1(%arg2: f32, %arg3: !llvm.ptr):120  llvm.store %arg2, %arg3 : f32, !llvm.ptr121  omp.yield(%arg3 : !llvm.ptr)122}123 124// -----125 126// Verifies fix for https://github.com/llvm/llvm-project/issues/102935.127//128// The issue happens since we previously failed to match MLIR values to their129// corresponding LLVM values in some cases (e.g. char strings with non-const130// length).131llvm.func @non_const_len_char_test(%n: !llvm.ptr {fir.bindc_name = "n"}) {132  %n_val = llvm.load %n : !llvm.ptr -> i64133  %orig_alloc = llvm.alloca %n_val x i8 {bindc_name = "str"} : (i64) -> !llvm.ptr134  %orig_val = llvm.mlir.undef : !llvm.struct<(ptr, i64)>135  %orig_val_init = llvm.insertvalue %orig_alloc, %orig_val[0] : !llvm.struct<(ptr, i64)>136  omp.parallel private(@non_const_len_char %orig_val_init -> %priv_arg : !llvm.struct<(ptr, i64)>) {137    %dummy = llvm.extractvalue %priv_arg[0] : !llvm.struct<(ptr, i64)>138    omp.terminator139  }140  llvm.return141}142 143omp.private {type = firstprivate} @non_const_len_char : !llvm.struct<(ptr, i64)> init {144^bb0(%orig_val: !llvm.struct<(ptr, i64)>, %arg1: !llvm.struct<(ptr, i64)>):145  %str_len = llvm.extractvalue %orig_val[1] : !llvm.struct<(ptr, i64)>146  %priv_alloc = llvm.alloca %str_len x i8 {bindc_name = "str", pinned} : (i64) -> !llvm.ptr147  %priv_val = llvm.mlir.undef : !llvm.struct<(ptr, i64)>148  %priv_val_init = llvm.insertvalue %priv_alloc, %priv_val[0] : !llvm.struct<(ptr, i64)>149  omp.yield(%priv_val_init : !llvm.struct<(ptr, i64)>)150} copy {151^bb0(%orig_val: !llvm.struct<(ptr, i64)>, %priv_val: !llvm.struct<(ptr, i64)>):152  llvm.call @foo() : () -> ()153  omp.yield(%priv_val : !llvm.struct<(ptr, i64)>)154}155 156llvm.func @foo()157 158// CHECK-LABEL: @non_const_len_char_test..omp_par({{.*}})159// CHECK-NEXT:    omp.par.entry:160// Verify that we found the privatizer by checking that we properly inlined the161// bodies of the alloc and copy regions.162// CHECK:         %[[STR_LEN:.*]] = extractvalue { ptr, i64 } %{{.*}}, 1163// CHECK:         %{{.*}} = alloca i8, i64 %[[STR_LEN]], align 1164// CHECK:         call void @foo()165 166// -----167 168// Verifies fix for https://github.com/llvm/llvm-project/issues/102939.169//170// The issues occurs because the CodeExtractor component only collect inputs171// (to the parallel regions) that are defined in the same function in which the172// parallel regions is present. Howerver, this is problematic because if we are173// privatizing a global value (e.g. a `target` variable which is emitted as a174// global), then we miss finding that input and we do not privatize the175// variable.176 177omp.private {type = firstprivate} @global_privatizer : f32 copy {178^bb0(%arg0: !llvm.ptr, %arg1: !llvm.ptr):179  %0 = llvm.load %arg0 : !llvm.ptr -> f32180  llvm.store %0, %arg1 : f32, !llvm.ptr181  omp.yield(%arg1 : !llvm.ptr)182}183 184llvm.func @global_accessor() {185  %global_addr = llvm.mlir.addressof @global : !llvm.ptr186  omp.parallel private(@global_privatizer %global_addr -> %arg0 : !llvm.ptr) {187    %1 = llvm.mlir.constant(3.140000e+00 : f32) : f32188    llvm.store %1, %arg0 : f32, !llvm.ptr189    omp.terminator190  }191  llvm.return192}193 194llvm.mlir.global internal @global() {addr_space = 0 : i32} : f32 {195  %0 = llvm.mlir.zero : f32196  llvm.return %0 : f32197}198 199// CHECK-LABEL: @global_accessor..omp_par({{.*}})200// CHECK-NEXT:  omp.par.entry:201// Verify that we found the privatizer by checking that we properly inlined the202// bodies of the alloc and copy regions.203// CHECK:         %[[PRIV_ALLOC:.*]] = alloca float, align 4204// CHECK:         %[[GLOB_VAL:.*]] = load float, ptr @global, align 4205// CHECK:         store float %[[GLOB_VAL]], ptr %[[PRIV_ALLOC]], align 4206