1// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s 2 3// CHECK-LABEL: define void @test_stand_alone_directives() 4llvm.func @test_stand_alone_directives() { 5 // CHECK: [[OMP_THREAD:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @{{[0-9]+}}) 6 // CHECK-NEXT: call void @__kmpc_barrier(%struct.ident_t* @{{[0-9]+}}, i32 [[OMP_THREAD]]) 7 omp.barrier 8 9 // CHECK: [[OMP_THREAD1:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @{{[0-9]+}}) 10 // CHECK-NEXT: [[RET_VAL:%.*]] = call i32 @__kmpc_omp_taskwait(%struct.ident_t* @{{[0-9]+}}, i32 [[OMP_THREAD1]]) 11 omp.taskwait 12 13 // CHECK: [[OMP_THREAD2:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @{{[0-9]+}}) 14 // CHECK-NEXT: [[RET_VAL:%.*]] = call i32 @__kmpc_omp_taskyield(%struct.ident_t* @{{[0-9]+}}, i32 [[OMP_THREAD2]], i32 0) 15 omp.taskyield 16 17 // CHECK-NEXT: ret void 18 llvm.return 19} 20 21// CHECK-LABEL: define void @test_flush_construct(i32 %0) 22llvm.func @test_flush_construct(%arg0: !llvm.i32) { 23 // CHECK: call void @__kmpc_flush(%struct.ident_t* @{{[0-9]+}} 24 omp.flush 25 26 // CHECK: call void @__kmpc_flush(%struct.ident_t* @{{[0-9]+}} 27 omp.flush (%arg0 : !llvm.i32) 28 29 // CHECK: call void @__kmpc_flush(%struct.ident_t* @{{[0-9]+}} 30 omp.flush (%arg0, %arg0 : !llvm.i32, !llvm.i32) 31 32 %0 = llvm.mlir.constant(1 : i64) : !llvm.i64 33 // CHECK: alloca {{.*}} align 4 34 %1 = llvm.alloca %0 x !llvm.i32 {in_type = i32, name = "a"} : (!llvm.i64) -> !llvm.ptr<i32> 35 // CHECK: call void @__kmpc_flush(%struct.ident_t* @{{[0-9]+}} 36 omp.flush 37 // CHECK: load i32, i32* 38 %2 = llvm.load %1 : !llvm.ptr<i32> 39 40 // CHECK-NEXT: ret void 41 llvm.return 42} 43 44// CHECK-LABEL: define void @test_omp_parallel_1() 45llvm.func @test_omp_parallel_1() -> () { 46 // CHECK: call void{{.*}}@__kmpc_fork_call{{.*}}@[[OMP_OUTLINED_FN_1:.*]] to {{.*}} 47 omp.parallel { 48 omp.barrier 49 omp.terminator 50 } 51 52 llvm.return 53} 54 55// CHECK: define internal void @[[OMP_OUTLINED_FN_1]] 56 // CHECK: call void @__kmpc_barrier 57 58llvm.func @body(!llvm.i64) 59 60// CHECK-LABEL: define void @test_omp_parallel_2() 61llvm.func @test_omp_parallel_2() -> () { 62 // CHECK: call void{{.*}}@__kmpc_fork_call{{.*}}@[[OMP_OUTLINED_FN_2:.*]] to {{.*}} 63 omp.parallel { 64 ^bb0: 65 %0 = llvm.mlir.constant(1 : index) : !llvm.i64 66 %1 = llvm.mlir.constant(42 : index) : !llvm.i64 67 llvm.call @body(%0) : (!llvm.i64) -> () 68 llvm.call @body(%1) : (!llvm.i64) -> () 69 llvm.br ^bb1 70 71 ^bb1: 72 %2 = llvm.add %0, %1 : !llvm.i64 73 llvm.call @body(%2) : (!llvm.i64) -> () 74 omp.terminator 75 } 76 llvm.return 77} 78 79// CHECK: define internal void @[[OMP_OUTLINED_FN_2]] 80 // CHECK-LABEL: omp.par.region: 81 // CHECK: br label %omp.par.region1 82 // CHECK-LABEL: omp.par.region1: 83 // CHECK: call void @body(i64 1) 84 // CHECK: call void @body(i64 42) 85 // CHECK: br label %omp.par.region2 86 // CHECK-LABEL: omp.par.region2: 87 // CHECK: call void @body(i64 43) 88 // CHECK: br label %omp.par.pre_finalize 89 90// CHECK: define void @test_omp_parallel_num_threads_1(i32 %[[NUM_THREADS_VAR_1:.*]]) 91llvm.func @test_omp_parallel_num_threads_1(%arg0: !llvm.i32) -> () { 92 // CHECK: %[[GTN_NUM_THREADS_VAR_1:.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GTN_SI_VAR_1:.*]]) 93 // CHECK: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GTN_SI_VAR_1]], i32 %[[GTN_NUM_THREADS_VAR_1]], i32 %[[NUM_THREADS_VAR_1]]) 94 // CHECK: call void{{.*}}@__kmpc_fork_call{{.*}}@[[OMP_OUTLINED_FN_NUM_THREADS_1:.*]] to {{.*}} 95 omp.parallel num_threads(%arg0: !llvm.i32) { 96 omp.barrier 97 omp.terminator 98 } 99 100 llvm.return 101} 102 103// CHECK: define internal void @[[OMP_OUTLINED_FN_NUM_THREADS_1]] 104 // CHECK: call void @__kmpc_barrier 105 106// CHECK: define void @test_omp_parallel_num_threads_2() 107llvm.func @test_omp_parallel_num_threads_2() -> () { 108 %0 = llvm.mlir.constant(4 : index) : !llvm.i32 109 // CHECK: %[[GTN_NUM_THREADS_VAR_2:.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GTN_SI_VAR_2:.*]]) 110 // CHECK: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GTN_SI_VAR_2]], i32 %[[GTN_NUM_THREADS_VAR_2]], i32 4) 111 // CHECK: call void{{.*}}@__kmpc_fork_call{{.*}}@[[OMP_OUTLINED_FN_NUM_THREADS_2:.*]] to {{.*}} 112 omp.parallel num_threads(%0: !llvm.i32) { 113 omp.barrier 114 omp.terminator 115 } 116 117 llvm.return 118} 119 120// CHECK: define internal void @[[OMP_OUTLINED_FN_NUM_THREADS_2]] 121 // CHECK: call void @__kmpc_barrier 122 123// CHECK: define void @test_omp_parallel_num_threads_3() 124llvm.func @test_omp_parallel_num_threads_3() -> () { 125 %0 = llvm.mlir.constant(4 : index) : !llvm.i32 126 // CHECK: %[[GTN_NUM_THREADS_VAR_3_1:.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GTN_SI_VAR_3_1:.*]]) 127 // CHECK: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GTN_SI_VAR_3_1]], i32 %[[GTN_NUM_THREADS_VAR_3_1]], i32 4) 128 // CHECK: call void{{.*}}@__kmpc_fork_call{{.*}}@[[OMP_OUTLINED_FN_NUM_THREADS_3_1:.*]] to {{.*}} 129 omp.parallel num_threads(%0: !llvm.i32) { 130 omp.barrier 131 omp.terminator 132 } 133 %1 = llvm.mlir.constant(8 : index) : !llvm.i32 134 // CHECK: %[[GTN_NUM_THREADS_VAR_3_2:.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GTN_SI_VAR_3_2:.*]]) 135 // CHECK: call void @__kmpc_push_num_threads(%struct.ident_t* @[[GTN_SI_VAR_3_2]], i32 %[[GTN_NUM_THREADS_VAR_3_2]], i32 8) 136 // CHECK: call void{{.*}}@__kmpc_fork_call{{.*}}@[[OMP_OUTLINED_FN_NUM_THREADS_3_2:.*]] to {{.*}} 137 omp.parallel num_threads(%1: !llvm.i32) { 138 omp.barrier 139 omp.terminator 140 } 141 142 llvm.return 143} 144 145// CHECK: define internal void @[[OMP_OUTLINED_FN_NUM_THREADS_3_2]] 146 // CHECK: call void @__kmpc_barrier 147 148// CHECK: define internal void @[[OMP_OUTLINED_FN_NUM_THREADS_3_1]] 149 // CHECK: call void @__kmpc_barrier 150 151// CHECK: define void @test_omp_parallel_if_1(i32 %[[IF_VAR_1:.*]]) 152llvm.func @test_omp_parallel_if_1(%arg0: !llvm.i32) -> () { 153 154// CHECK: %[[IF_COND_VAR_1:.*]] = icmp slt i32 %[[IF_VAR_1]], 0 155 %0 = llvm.mlir.constant(0 : index) : !llvm.i32 156 %1 = llvm.icmp "slt" %arg0, %0 : !llvm.i32 157 158// CHECK: %[[GTN_IF_1:.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[SI_VAR_IF_1:.*]]) 159// CHECK: br i1 %[[IF_COND_VAR_1]], label %[[IF_COND_TRUE_BLOCK_1:.*]], label %[[IF_COND_FALSE_BLOCK_1:.*]] 160// CHECK: [[IF_COND_TRUE_BLOCK_1]]: 161// CHECK: br label %[[OUTLINED_CALL_IF_BLOCK_1:.*]] 162// CHECK: [[OUTLINED_CALL_IF_BLOCK_1]]: 163// CHECK: call void {{.*}} @__kmpc_fork_call(%struct.ident_t* @[[SI_VAR_IF_1]], {{.*}} @[[OMP_OUTLINED_FN_IF_1:.*]] to void 164// CHECK: br label %[[OUTLINED_EXIT_IF_1:.*]] 165// CHECK: [[OUTLINED_EXIT_IF_1]]: 166// CHECK: br label %[[OUTLINED_EXIT_IF_2:.*]] 167// CHECK: [[OUTLINED_EXIT_IF_2]]: 168// CHECK: br label %[[RETURN_BLOCK_IF_1:.*]] 169// CHECK: [[IF_COND_FALSE_BLOCK_1]]: 170// CHECK: call void @__kmpc_serialized_parallel(%struct.ident_t* @[[SI_VAR_IF_1]], i32 %[[GTN_IF_1]]) 171// CHECK: call void @[[OMP_OUTLINED_FN_IF_1]] 172// CHECK: call void @__kmpc_end_serialized_parallel(%struct.ident_t* @[[SI_VAR_IF_1]], i32 %[[GTN_IF_1]]) 173// CHECK: br label %[[RETURN_BLOCK_IF_1]] 174 omp.parallel if(%1 : !llvm.i1) { 175 omp.barrier 176 omp.terminator 177 } 178 179// CHECK: [[RETURN_BLOCK_IF_1]]: 180// CHECK: ret void 181 llvm.return 182} 183 184// CHECK: define internal void @[[OMP_OUTLINED_FN_IF_1]] 185 // CHECK: call void @__kmpc_barrier 186 187// CHECK-LABEL: define void @test_omp_parallel_3() 188llvm.func @test_omp_parallel_3() -> () { 189 // CHECK: [[OMP_THREAD_3_1:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @{{[0-9]+}}) 190 // CHECK: call void @__kmpc_push_proc_bind(%struct.ident_t* @{{[0-9]+}}, i32 [[OMP_THREAD_3_1]], i32 2) 191 // CHECK: call void{{.*}}@__kmpc_fork_call{{.*}}@[[OMP_OUTLINED_FN_3_1:.*]] to {{.*}} 192 omp.parallel proc_bind(master) { 193 omp.barrier 194 omp.terminator 195 } 196 // CHECK: [[OMP_THREAD_3_2:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @{{[0-9]+}}) 197 // CHECK: call void @__kmpc_push_proc_bind(%struct.ident_t* @{{[0-9]+}}, i32 [[OMP_THREAD_3_2]], i32 3) 198 // CHECK: call void{{.*}}@__kmpc_fork_call{{.*}}@[[OMP_OUTLINED_FN_3_2:.*]] to {{.*}} 199 omp.parallel proc_bind(close) { 200 omp.barrier 201 omp.terminator 202 } 203 // CHECK: [[OMP_THREAD_3_3:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @{{[0-9]+}}) 204 // CHECK: call void @__kmpc_push_proc_bind(%struct.ident_t* @{{[0-9]+}}, i32 [[OMP_THREAD_3_3]], i32 4) 205 // CHECK: call void{{.*}}@__kmpc_fork_call{{.*}}@[[OMP_OUTLINED_FN_3_3:.*]] to {{.*}} 206 omp.parallel proc_bind(spread) { 207 omp.barrier 208 omp.terminator 209 } 210 211 llvm.return 212} 213 214// CHECK: define internal void @[[OMP_OUTLINED_FN_3_3]] 215// CHECK: define internal void @[[OMP_OUTLINED_FN_3_2]] 216// CHECK: define internal void @[[OMP_OUTLINED_FN_3_1]] 217 218// CHECK-LABEL: define void @test_omp_parallel_4() 219llvm.func @test_omp_parallel_4() -> () { 220// CHECK: call void {{.*}}@__kmpc_fork_call{{.*}} @[[OMP_OUTLINED_FN_4_1:.*]] to 221// CHECK: define internal void @[[OMP_OUTLINED_FN_4_1]] 222// CHECK: call void @__kmpc_barrier 223// CHECK: call void {{.*}}@__kmpc_fork_call{{.*}} @[[OMP_OUTLINED_FN_4_1_1:.*]] to 224// CHECK: call void @__kmpc_barrier 225 omp.parallel { 226 omp.barrier 227 228// CHECK: define internal void @[[OMP_OUTLINED_FN_4_1_1]] 229// CHECK: call void @__kmpc_barrier 230 omp.parallel { 231 omp.barrier 232 omp.terminator 233 } 234 235 omp.barrier 236 omp.terminator 237 } 238 llvm.return 239} 240 241llvm.func @test_omp_parallel_5() -> () { 242// CHECK: call void {{.*}}@__kmpc_fork_call{{.*}} @[[OMP_OUTLINED_FN_5_1:.*]] to 243// CHECK: define internal void @[[OMP_OUTLINED_FN_5_1]] 244// CHECK: call void @__kmpc_barrier 245// CHECK: call void {{.*}}@__kmpc_fork_call{{.*}} @[[OMP_OUTLINED_FN_5_1_1:.*]] to 246// CHECK: call void @__kmpc_barrier 247 omp.parallel { 248 omp.barrier 249 250// CHECK: define internal void @[[OMP_OUTLINED_FN_5_1_1]] 251 omp.parallel { 252// CHECK: call void {{.*}}@__kmpc_fork_call{{.*}} @[[OMP_OUTLINED_FN_5_1_1_1:.*]] to 253// CHECK: define internal void @[[OMP_OUTLINED_FN_5_1_1_1]] 254// CHECK: call void @__kmpc_barrier 255 omp.parallel { 256 omp.barrier 257 omp.terminator 258 } 259 omp.terminator 260 } 261 262 omp.barrier 263 omp.terminator 264 } 265 llvm.return 266} 267 268// CHECK-LABEL: define void @test_omp_master() 269llvm.func @test_omp_master() -> () { 270// CHECK: call void {{.*}}@__kmpc_fork_call{{.*}} @{{.*}} to 271// CHECK: omp.par.region1: 272 omp.parallel { 273 omp.master { 274// CHECK: [[OMP_THREAD_3_4:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @{{[0-9]+}}) 275// CHECK: {{[0-9]+}} = call i32 @__kmpc_master(%struct.ident_t* @{{[0-9]+}}, i32 [[OMP_THREAD_3_4]]) 276// CHECK: omp.master.region 277// CHECK: call void @__kmpc_end_master(%struct.ident_t* @{{[0-9]+}}, i32 [[OMP_THREAD_3_4]]) 278// CHECK: br label %omp_region.end 279 omp.terminator 280 } 281 omp.terminator 282 } 283 omp.parallel { 284 omp.parallel { 285 omp.master { 286 omp.terminator 287 } 288 omp.terminator 289 } 290 omp.terminator 291 } 292 llvm.return 293} 294