brintos

brintos / llvm-project-archived public Read only

0
0
Text · 19.7 KiB · 08473f2 Raw
672 lines · plain
1// RUN: mlir-translate -mlir-to-llvmir -split-input-file %s | FileCheck %s2 3// Only check the overall shape of the code and the presence of relevant4// runtime calls. Actual IR checking is done at the OpenMPIRBuilder level.5 6omp.declare_reduction @add_f32 : f327init {8^bb0(%arg: f32):9  %0 = llvm.mlir.constant(0.0 : f32) : f3210  omp.yield (%0 : f32)11}12combiner {13^bb1(%arg0: f32, %arg1: f32):14  %1 = llvm.fadd %arg0, %arg1 : f3215  omp.yield (%1 : f32)16}17atomic {18^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):19  %2 = llvm.load %arg3 : !llvm.ptr -> f3220  llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f3221  omp.yield22}23 24// CHECK-LABEL: @simple_reduction25llvm.func @simple_reduction(%lb : i64, %ub : i64, %step : i64) {26  %c1 = llvm.mlir.constant(1 : i32) : i3227  %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr28  omp.parallel {29    omp.wsloop reduction(@add_f32 %0 -> %prv : !llvm.ptr) {30      omp.loop_nest (%iv) : i64 = (%lb) to (%ub) step (%step) {31        %1 = llvm.mlir.constant(2.0 : f32) : f3232        %2 = llvm.load %prv : !llvm.ptr -> f3233        %3 = llvm.fadd %1, %2 : f3234        llvm.store %3, %prv : f32, !llvm.ptr35        omp.yield36      }37    }38    omp.terminator39  }40  llvm.return41}42 43// Call to the outlined function.44// CHECK: call void {{.*}} @__kmpc_fork_call45// CHECK-SAME: @[[OUTLINED:[A-Za-z_.][A-Za-z0-9_.]*]]46 47// Outlined function.48// CHECK: define internal void @[[OUTLINED]]49 50// Private reduction variable and its initialization.51// CHECK: %[[PRIVATE:.+]] = alloca float52// CHECK: store float 0.000000e+00, ptr %[[PRIVATE]]53 54// Call to the reduction function.55// CHECK: call i32 @__kmpc_reduce56// CHECK-SAME: @[[REDFUNC:[A-Za-z_.][A-Za-z0-9_.]*]]57 58// Atomic reduction.59// CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]]60// CHECK: atomicrmw fadd ptr %{{.*}}, float %[[PARTIAL]]61 62// Non-atomic reduction:63// CHECK: fadd float64// CHECK: call void @__kmpc_end_reduce65// CHECK: br label %[[FINALIZE:.+]]66 67// CHECK: [[FINALIZE]]:68// CHECK: call void @__kmpc_barrier69 70// Update of the private variable using the reduction region71// (the body block currently comes after all the other blocks).72// CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]]73// CHECK: %[[UPDATED:.+]] = fadd float 2.000000e+00, %[[PARTIAL]]74// CHECK: store float %[[UPDATED]], ptr %[[PRIVATE]]75 76// Reduction function.77// CHECK: define internal void @[[REDFUNC]]78// CHECK: fadd float79 80// -----81 82omp.declare_reduction @add_f32 : f3283init {84^bb0(%arg: f32):85  %0 = llvm.mlir.constant(0.0 : f32) : f3286  omp.yield (%0 : f32)87}88combiner {89^bb1(%arg0: f32, %arg1: f32):90  %1 = llvm.fadd %arg0, %arg1 : f3291  omp.yield (%1 : f32)92}93atomic {94^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):95  %2 = llvm.load %arg3 : !llvm.ptr -> f3296  llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f3297  omp.yield98}99 100// When the same reduction declaration is used several times, its regions101// are translated several times, which shouldn't lead to value/block102// remapping assertions.103// CHECK-LABEL: @reuse_declaration104llvm.func @reuse_declaration(%lb : i64, %ub : i64, %step : i64) {105  %c1 = llvm.mlir.constant(1 : i32) : i32106  %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr107  %2 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr108  omp.parallel {109    omp.wsloop reduction(@add_f32 %0 -> %prv0, @add_f32 %2 -> %prv1 : !llvm.ptr, !llvm.ptr) {110      omp.loop_nest (%iv) : i64 = (%lb) to (%ub) step (%step) {111        %1 = llvm.mlir.constant(2.0 : f32) : f32112        %3 = llvm.load %prv0 : !llvm.ptr -> f32113        %4 = llvm.fadd %3, %1 : f32114        llvm.store %4, %prv0 : f32, !llvm.ptr115        %5 = llvm.load %prv1 : !llvm.ptr -> f32116        %6 = llvm.fadd %5, %1 : f32117        llvm.store %6, %prv1 : f32, !llvm.ptr118        omp.yield119      }120    }121    omp.terminator122  }123  llvm.return124}125 126// Call to the outlined function.127// CHECK: call void {{.*}} @__kmpc_fork_call128// CHECK-SAME: @[[OUTLINED:[A-Za-z_.][A-Za-z0-9_.]*]]129 130// Outlined function.131// CHECK: define internal void @[[OUTLINED]]132 133// Private reduction variable and its initialization.134// CHECK: %[[PRIVATE1:.+]] = alloca float135// CHECK: %[[PRIVATE2:.+]] = alloca float136// CHECK: store float 0.000000e+00, ptr %[[PRIVATE1]]137// CHECK: store float 0.000000e+00, ptr %[[PRIVATE2]]138 139// Call to the reduction function.140// CHECK: call i32 @__kmpc_reduce141// CHECK-SAME: @[[REDFUNC:[A-Za-z_.][A-Za-z0-9_.]*]]142 143// Atomic reduction.144// CHECK: %[[PARTIAL1:.+]] = load float, ptr %[[PRIVATE1]]145// CHECK: atomicrmw fadd ptr %{{.*}}, float %[[PARTIAL1]]146// CHECK: %[[PARTIAL2:.+]] = load float, ptr %[[PRIVATE2]]147// CHECK: atomicrmw fadd ptr %{{.*}}, float %[[PARTIAL2]]148 149// Non-atomic reduction:150// CHECK: fadd float151// CHECK: fadd float152// CHECK: call void @__kmpc_end_reduce153// CHECK: br label %[[FINALIZE:.+]]154 155// CHECK: [[FINALIZE]]:156// CHECK: call void @__kmpc_barrier157 158// Update of the private variable using the reduction region159// (the body block currently comes after all the other blocks).160// CHECK: %[[PARTIAL1:.+]] = load float, ptr %[[PRIVATE1]]161// CHECK: %[[UPDATED1:.+]] = fadd float %[[PARTIAL1]], 2.000000e+00162// CHECK: store float %[[UPDATED1]], ptr %[[PRIVATE1]]163// CHECK: %[[PARTIAL2:.+]] = load float, ptr %[[PRIVATE2]]164// CHECK: %[[UPDATED2:.+]] = fadd float %[[PARTIAL2]], 2.000000e+00165// CHECK: store float %[[UPDATED2]], ptr %[[PRIVATE2]]166 167// Reduction function.168// CHECK: define internal void @[[REDFUNC]]169// CHECK: fadd float170// CHECK: fadd float171 172 173// -----174 175omp.declare_reduction @add_f32 : f32176init {177^bb0(%arg: f32):178  %0 = llvm.mlir.constant(0.0 : f32) : f32179  omp.yield (%0 : f32)180}181combiner {182^bb1(%arg0: f32, %arg1: f32):183  %1 = llvm.fadd %arg0, %arg1 : f32184  omp.yield (%1 : f32)185}186atomic {187^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):188  %2 = llvm.load %arg3 : !llvm.ptr -> f32189  llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32190  omp.yield191}192 193// It's okay not to reference the reduction variable in the body.194// CHECK-LABEL: @missing_omp_reduction195llvm.func @missing_omp_reduction(%lb : i64, %ub : i64, %step : i64) {196  %c1 = llvm.mlir.constant(1 : i32) : i32197  %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr198  %2 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr199  omp.parallel {200    omp.wsloop reduction(@add_f32 %0 -> %prv0, @add_f32 %2 -> %prv1 : !llvm.ptr, !llvm.ptr) {201      omp.loop_nest (%iv) : i64 = (%lb) to (%ub) step (%step) {202        %1 = llvm.mlir.constant(2.0 : f32) : f32203        %3 = llvm.load %prv0 : !llvm.ptr -> f32204        %4 = llvm.fadd %3, %1 : f32205        llvm.store %4, %prv0 : f32, !llvm.ptr206        omp.yield207      }208    }209    omp.terminator210  }211  llvm.return212}213 214// Call to the outlined function.215// CHECK: call void {{.*}} @__kmpc_fork_call216// CHECK-SAME: @[[OUTLINED:[A-Za-z_.][A-Za-z0-9_.]*]]217 218// Outlined function.219// CHECK: define internal void @[[OUTLINED]]220 221// Private reduction variable and its initialization.222// CHECK: %[[PRIVATE1:.+]] = alloca float223// CHECK: %[[PRIVATE2:.+]] = alloca float224// CHECK: store float 0.000000e+00, ptr %[[PRIVATE1]]225// CHECK: store float 0.000000e+00, ptr %[[PRIVATE2]]226 227// Call to the reduction function.228// CHECK: call i32 @__kmpc_reduce229// CHECK-SAME: @[[REDFUNC:[A-Za-z_.][A-Za-z0-9_.]*]]230 231// Atomic reduction.232// CHECK: %[[PARTIAL1:.+]] = load float, ptr %[[PRIVATE1]]233// CHECK: atomicrmw fadd ptr %{{.*}}, float %[[PARTIAL1]]234// CHECK: %[[PARTIAL2:.+]] = load float, ptr %[[PRIVATE2]]235// CHECK: atomicrmw fadd ptr %{{.*}}, float %[[PARTIAL2]]236 237// Non-atomic reduction:238// CHECK: fadd float239// CHECK: fadd float240// CHECK: call void @__kmpc_end_reduce241// CHECK: br label %[[FINALIZE:.+]]242 243// CHECK: [[FINALIZE]]:244// CHECK: call void @__kmpc_barrier245 246// Update of the private variable using the reduction region247// (the body block currently comes after all the other blocks).248// CHECK: %[[PARTIAL1:.+]] = load float, ptr %[[PRIVATE1]]249// CHECK: %[[UPDATED1:.+]] = fadd float %[[PARTIAL1]], 2.000000e+00250// CHECK: store float %[[UPDATED1]], ptr %[[PRIVATE1]]251// CHECK-NOT: %{{.*}} = load float, ptr %[[PRIVATE2]]252// CHECK-NOT: %{{.*}} = fadd float %[[PARTIAL2]], 2.000000e+00253 254// Reduction function.255// CHECK: define internal void @[[REDFUNC]]256// CHECK: fadd float257// CHECK: fadd float258 259// -----260 261omp.declare_reduction @add_f32 : f32262init {263^bb0(%arg: f32):264  %0 = llvm.mlir.constant(0.0 : f32) : f32265  omp.yield (%0 : f32)266}267combiner {268^bb1(%arg0: f32, %arg1: f32):269  %1 = llvm.fadd %arg0, %arg1 : f32270  omp.yield (%1 : f32)271}272atomic {273^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):274  %2 = llvm.load %arg3 : !llvm.ptr -> f32275  llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32276  omp.yield277}278 279// It's okay to refer to the same reduction variable more than once in the280// body.281// CHECK-LABEL: @double_reference282llvm.func @double_reference(%lb : i64, %ub : i64, %step : i64) {283  %c1 = llvm.mlir.constant(1 : i32) : i32284  %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr285  omp.parallel {286    omp.wsloop reduction(@add_f32 %0 -> %prv : !llvm.ptr) {287      omp.loop_nest (%iv) : i64 = (%lb) to (%ub) step (%step) {288        %1 = llvm.mlir.constant(2.0 : f32) : f32289        %2 = llvm.load %prv : !llvm.ptr -> f32290        %3 = llvm.fadd %2, %1 : f32291        llvm.store %3, %prv : f32, !llvm.ptr292        %4 = llvm.load %prv : !llvm.ptr -> f32293        %5 = llvm.fadd %4, %1 : f32294        llvm.store %5, %prv : f32, !llvm.ptr295        omp.yield296      }297    }298    omp.terminator299  }300  llvm.return301}302 303// Call to the outlined function.304// CHECK: call void {{.*}} @__kmpc_fork_call305// CHECK-SAME: @[[OUTLINED:[A-Za-z_.][A-Za-z0-9_.]*]]306 307// Outlined function.308// CHECK: define internal void @[[OUTLINED]]309 310// Private reduction variable and its initialization.311// CHECK: %[[PRIVATE:.+]] = alloca float312// CHECK: store float 0.000000e+00, ptr %[[PRIVATE]]313 314// Call to the reduction function.315// CHECK: call i32 @__kmpc_reduce316// CHECK-SAME: @[[REDFUNC:[A-Za-z_.][A-Za-z0-9_.]*]]317 318// Atomic reduction.319// CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]]320// CHECK: atomicrmw fadd ptr %{{.*}}, float %[[PARTIAL]]321 322// Non-atomic reduction:323// CHECK: fadd float324// CHECK: call void @__kmpc_end_reduce325// CHECK: br label %[[FINALIZE:.+]]326 327// CHECK: [[FINALIZE]]:328// CHECK: call void @__kmpc_barrier329 330// Update of the private variable using the reduction region331// (the body block currently comes after all the other blocks).332// CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]]333// CHECK: %[[UPDATED:.+]] = fadd float %[[PARTIAL]], 2.000000e+00334// CHECK: store float %[[UPDATED]], ptr %[[PRIVATE]]335// CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]]336// CHECK: %[[UPDATED:.+]] = fadd float %[[PARTIAL]], 2.000000e+00337// CHECK: store float %[[UPDATED]], ptr %[[PRIVATE]]338 339// Reduction function.340// CHECK: define internal void @[[REDFUNC]]341// CHECK: fadd float342 343// -----344 345omp.declare_reduction @add_f32 : f32346init {347^bb0(%arg: f32):348  %0 = llvm.mlir.constant(0.0 : f32) : f32349  omp.yield (%0 : f32)350}351combiner {352^bb1(%arg0: f32, %arg1: f32):353  %1 = llvm.fadd %arg0, %arg1 : f32354  omp.yield (%1 : f32)355}356atomic {357^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):358  %2 = llvm.load %arg3 : !llvm.ptr -> f32359  llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32360  omp.yield361}362 363omp.declare_reduction @mul_f32 : f32364init {365^bb0(%arg: f32):366  %0 = llvm.mlir.constant(1.0 : f32) : f32367  omp.yield (%0 : f32)368}369combiner {370^bb1(%arg0: f32, %arg1: f32):371  %1 = llvm.fmul %arg0, %arg1 : f32372  omp.yield (%1 : f32)373}374 375// CHECK-LABEL: @no_atomic376llvm.func @no_atomic(%lb : i64, %ub : i64, %step : i64) {377  %c1 = llvm.mlir.constant(1 : i32) : i32378  %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr379  %2 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr380  omp.parallel {381    omp.wsloop reduction(@add_f32 %0 -> %prv0, @mul_f32 %2 -> %prv1 : !llvm.ptr, !llvm.ptr) {382      omp.loop_nest (%iv) : i64 = (%lb) to (%ub) step (%step) {383        %1 = llvm.mlir.constant(2.0 : f32) : f32384        %3 = llvm.load %prv0 : !llvm.ptr -> f32385        %4 = llvm.fadd %3, %1 : f32386        llvm.store %4, %prv0 : f32, !llvm.ptr387        %5 = llvm.load %prv1 : !llvm.ptr -> f32388        %6 = llvm.fmul %5, %1 : f32389        llvm.store %6, %prv1 : f32, !llvm.ptr390        omp.yield391      }392    }393    omp.terminator394  }395  llvm.return396}397 398// Call to the outlined function.399// CHECK: call void {{.*}} @__kmpc_fork_call400// CHECK-SAME: @[[OUTLINED:[A-Za-z_.][A-Za-z0-9_.]*]]401 402// Outlined function.403// CHECK: define internal void @[[OUTLINED]]404 405// Private reduction variable and its initialization.406// CHECK: %[[PRIVATE1:.+]] = alloca float407// CHECK: %[[PRIVATE2:.+]] = alloca float408// CHECK: store float 0.000000e+00, ptr %[[PRIVATE1]]409// CHECK: store float 1.000000e+00, ptr %[[PRIVATE2]]410 411// Call to the reduction function.412// CHECK: call i32 @__kmpc_reduce413// CHECK-SAME: @[[REDFUNC:[A-Za-z_.][A-Za-z0-9_.]*]]414 415// Atomic reduction not provided.416// CHECK: unreachable417 418// Non-atomic reduction:419// CHECK: fadd float420// CHECK: fmul float421// CHECK: call void @__kmpc_end_reduce422// CHECK: br label %[[FINALIZE:.+]]423 424// CHECK: [[FINALIZE]]:425// CHECK: call void @__kmpc_barrier426 427// Update of the private variable using the reduction region428// (the body block currently comes after all the other blocks).429// CHECK: %[[PARTIAL1:.+]] = load float, ptr %[[PRIVATE1]]430// CHECK: %[[UPDATED1:.+]] = fadd float %[[PARTIAL1]], 2.000000e+00431// CHECK: store float %[[UPDATED1]], ptr %[[PRIVATE1]]432// CHECK: %[[PARTIAL2:.+]] = load float, ptr %[[PRIVATE2]]433// CHECK: %[[UPDATED2:.+]] = fmul float %[[PARTIAL2]], 2.000000e+00434// CHECK: store float %[[UPDATED2]], ptr %[[PRIVATE2]]435 436// Reduction function.437// CHECK: define internal void @[[REDFUNC]]438// CHECK: fadd float439// CHECK: fmul float440 441// -----442 443omp.declare_reduction @add_f32 : f32444init {445^bb0(%arg: f32):446  %0 = llvm.mlir.constant(0.0 : f32) : f32447  omp.yield (%0 : f32)448}449combiner {450^bb1(%arg0: f32, %arg1: f32):451  %1 = llvm.fadd %arg0, %arg1 : f32452  omp.yield (%1 : f32)453}454atomic {455^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):456  %2 = llvm.load %arg3 : !llvm.ptr -> f32457  llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32458  omp.yield459}460 461// CHECK-LABEL: @simple_reduction_parallel462llvm.func @simple_reduction_parallel() {463  %c1 = llvm.mlir.constant(1 : i32) : i32464  %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr465  omp.parallel reduction(@add_f32 %0 -> %prv : !llvm.ptr) {466    %1 = llvm.mlir.constant(2.0 : f32) : f32467    %2 = llvm.load %prv : !llvm.ptr -> f32468    %3 = llvm.fadd %2, %1 : f32469    llvm.store %3, %prv : f32, !llvm.ptr470    omp.terminator471  }472  llvm.return473}474 475// Call to the outlined function.476// CHECK: call void {{.*}} @__kmpc_fork_call477// CHECK-SAME: @[[OUTLINED:[A-Za-z_.][A-Za-z0-9_.]*]]478 479// Outlined function.480// CHECK: define internal void @[[OUTLINED]]481 482// Private reduction variable and its initialization.483// CHECK: %[[PRIVATE:.+]] = alloca float484// CHECK: store float 0.000000e+00, ptr %[[PRIVATE]]485 486// Update of the private variable487// CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]]488// CHECK: %[[UPDATED:.+]] = fadd float %[[PARTIAL]], 2.000000e+00489// CHECK: store float %[[UPDATED]], ptr %[[PRIVATE]]490 491// Call to the reduction function.492// CHECK: call i32 @__kmpc_reduce493// CHECK-SAME: @[[REDFUNC:[A-Za-z_.][A-Za-z0-9_.]*]]494 495// Atomic reduction.496// CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]]497// CHECK: atomicrmw fadd ptr %{{.*}}, float %[[PARTIAL]]498 499// Non-atomic reduction:500// CHECK: fadd float501// CHECK: call void @__kmpc_end_reduce502// CHECK: br label %[[FINALIZE:.+]]503 504// CHECK: [[FINALIZE]]:505 506// Reduction function.507// CHECK: define internal void @[[REDFUNC]]508// CHECK: fadd float509 510// -----511 512omp.declare_reduction @add_i32 : i32513init {514^bb0(%arg: i32):515  %0 = llvm.mlir.constant(0 : i32) : i32516  omp.yield (%0 : i32)517}518combiner {519^bb1(%arg0: i32, %arg1: i32):520  %1 = llvm.add %arg0, %arg1 : i32521  omp.yield (%1 : i32)522}523atomic {524^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):525  %2 = llvm.load %arg3 : !llvm.ptr -> i32526  llvm.atomicrmw add %arg2, %2 monotonic : !llvm.ptr, i32527  omp.yield528}529 530// CHECK-LABEL: @parallel_nested_workshare_reduction531llvm.func @parallel_nested_workshare_reduction(%ub : i64) {532  %c1 = llvm.mlir.constant(1 : i32) : i32533  %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr534 535  %lb = llvm.mlir.constant(1 : i64) : i64536  %step = llvm.mlir.constant(1 : i64) : i64537  538  omp.parallel {539    omp.wsloop reduction(@add_i32 %0 -> %prv : !llvm.ptr) {540      omp.loop_nest (%iv) : i64 = (%lb) to (%ub) step (%step) {541        %ival = llvm.trunc %iv : i64 to i32542        %lprv = llvm.load %prv : !llvm.ptr -> i32543        %add = llvm.add %lprv, %ival : i32544        llvm.store %add, %prv : i32, !llvm.ptr545        omp.yield546      }547    }548    omp.terminator549  }550 551  llvm.return552}553 554// Call to the outlined function.555// CHECK: call void {{.*}} @__kmpc_fork_call556// CHECK-SAME: @[[OUTLINED:[A-Za-z_.][A-Za-z0-9_.]*]]557 558// Outlined function.559// CHECK: define internal void @[[OUTLINED]]560 561// Private reduction variable and its initialization.562// CHECK: %[[PRIVATE:[0-9]+]] = alloca i32563// CHECK: store i32 0, ptr %[[PRIVATE]]564 565// Loop exit:566// CHECK: call void @__kmpc_barrier567 568// Call to the reduction function.569// CHECK: call i32 @__kmpc_reduce570// CHECK-SAME: @[[REDFUNC:[A-Za-z_.][A-Za-z0-9_.]*]]571 572// Atomic reduction:573// CHECK: %[[PARTIAL:.+]] = load i32, ptr %[[PRIVATE]]574// CHECK: atomicrmw add ptr %{{.*}}, i32 %[[PARTIAL]]575 576// Non-atomic reduction:577// CHECK: add i32578// CHECK: call void @__kmpc_end_reduce579 580// Update of the private variable using the reduction region581// (the body block currently comes after all the other blocks).582// CHECK: %[[PARTIAL:.+]] = load i32, ptr %[[PRIVATE]]583// CHECK: %[[UPDATED:.+]] = add i32 %[[PARTIAL]], {{.*}}584// CHECK: store i32 %[[UPDATED]], ptr %[[PRIVATE]]585 586// Reduction function.587// CHECK: define internal void @[[REDFUNC]]588// CHECK: add i32589 590// -----591 592omp.declare_reduction @add_f32 : f32593init {594^bb0(%arg: f32):595  %0 = llvm.mlir.constant(0.0 : f32) : f32596  omp.yield (%0 : f32)597}598combiner {599^bb1(%arg0: f32, %arg1: f32):600  %1 = llvm.fadd %arg0, %arg1 : f32601  omp.yield (%1 : f32)602}603atomic {604^bb2(%arg2: !llvm.ptr, %arg3: !llvm.ptr):605  %2 = llvm.load %arg3 : !llvm.ptr -> f32606  llvm.atomicrmw fadd %arg2, %2 monotonic : !llvm.ptr, f32607  omp.yield608}609 610// CHECK-LABEL: @wsloop_simd_reduction611llvm.func @wsloop_simd_reduction(%lb : i64, %ub : i64, %step : i64) {612  %c1 = llvm.mlir.constant(1 : i32) : i32613  %0 = llvm.alloca %c1 x i32 : (i32) -> !llvm.ptr614  omp.parallel {615    omp.wsloop reduction(@add_f32 %0 -> %prv1 : !llvm.ptr) {616      omp.simd reduction(@add_f32 %prv1 -> %prv2 : !llvm.ptr) {617        omp.loop_nest (%iv) : i64 = (%lb) to (%ub) step (%step) {618          %1 = llvm.mlir.constant(2.0 : f32) : f32619          %2 = llvm.load %prv2 : !llvm.ptr -> f32620          %3 = llvm.fadd %1, %2 : f32621          llvm.store %3, %prv2 : f32, !llvm.ptr622          omp.yield623        }624      } {omp.composite}625    } {omp.composite}626    omp.terminator627  }628  llvm.return629}630 631// Same checks as for wsloop reduction, because currently omp.simd is ignored in632// a composite 'do/for simd' construct.633// Call to the outlined function.634// CHECK: call void {{.*}} @__kmpc_fork_call635// CHECK-SAME: @[[OUTLINED:[A-Za-z_.][A-Za-z0-9_.]*]]636 637// Outlined function.638// CHECK: define internal void @[[OUTLINED]]639 640// reduction variable in wsloop641// CHECK: %[[PRIVATE:.+]] = alloca float642// reduction variable in simd643// CHECK: %[[PRIVATE2:.+]] = alloca float644// CHECK: store float 0.000000e+00, ptr %[[PRIVATE]]645// CHECK: store float 0.000000e+00, ptr %[[PRIVATE2]]646 647// Call to the reduction function.648// CHECK: call i32 @__kmpc_reduce649// CHECK-SAME: @[[REDFUNC:[A-Za-z_.][A-Za-z0-9_.]*]]650 651// Atomic reduction.652// CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE]]653// CHECK: atomicrmw fadd ptr %{{.*}}, float %[[PARTIAL]]654 655// Non-atomic reduction:656// CHECK: fadd float657// CHECK: call void @__kmpc_end_reduce658// CHECK: br label %[[FINALIZE:.+]]659 660// CHECK: [[FINALIZE]]:661// CHECK: call void @__kmpc_barrier662 663// Update of the private variable using the reduction region664// (the body block currently comes after all the other blocks).665// CHECK: %[[PARTIAL:.+]] = load float, ptr %[[PRIVATE2]]666// CHECK: %[[UPDATED:.+]] = fadd float 2.000000e+00, %[[PARTIAL]]667// CHECK: store float %[[UPDATED]], ptr %[[PRIVATE2]]668 669// Reduction function.670// CHECK: define internal void @[[REDFUNC]]671// CHECK: fadd float672