|
| 1 | +! This test checks lowering of OpenMP parallel Directive with arbitrary code |
| 2 | +! inside it. |
| 3 | + |
| 4 | +! RUN: bbc -fopenmp -emit-fir %s -o - | \ |
| 5 | +! RUN: FileCheck %s --check-prefix=FIRDialect |
| 6 | +! RUN: bbc -fopenmp -emit-llvm %s -o - | \ |
| 7 | +! RUN: FileCheck %s --check-prefix=LLVMIRDialect |
| 8 | +! RUN: bbc -fopenmp -emit-fir %s -o - | \ |
| 9 | +! RUN: tco | FileCheck %s --check-prefix=LLVMIR |
| 10 | + |
| 11 | +program parallel |
| 12 | + |
| 13 | + integer :: a,b,c |
| 14 | + integer :: num_threads |
| 15 | + |
| 16 | + a = 1 |
| 17 | + b = 2 |
| 18 | +!FIRDialect: %[[VAR_A:.*]] = fir.alloca i32 {name = "a"} |
| 19 | +!FIRDialect: %[[VAR_B:.*]] = fir.alloca i32 {name = "b"} |
| 20 | +!FIRDialect: %[[VAR_C:.*]] = fir.alloca i32 {name = "c"} |
| 21 | +!FIRDialect: %[[VAR_NUM_THREADS:.*]] = fir.alloca i32 {name = "num_threads"} |
| 22 | + |
| 23 | +!LLVMIRDialect: %[[VAR_A:.*]] = llvm.alloca %{{.*}} x !llvm.i32 {in_type = i32, name = "a"} |
| 24 | +!LLVMIRDialect: %[[VAR_B:.*]] = llvm.alloca %{{.*}} x !llvm.i32 {in_type = i32, name = "b"} |
| 25 | +!LLVMIRDialect: %[[VAR_C:.*]] = llvm.alloca %{{.*}} x !llvm.i32 {in_type = i32, name = "c"} |
| 26 | +!LLVMIRDialect: %[[VAR_NUM_THREADS:.*]] = llvm.alloca %{{.*}} x !llvm.i32 {in_type = i32, name = "num_threads"} |
| 27 | + |
| 28 | +!LLVMIR: %[[OMP_GLOBAL_THREAD_NUM:.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @{{.*}}) |
| 29 | +!LLVMIR: call void @__kmpc_push_num_threads(%struct.ident_t* @{{.*}}, i32 %[[OMP_GLOBAL_THREAD_NUM]], i32 %{{.*}}) |
| 30 | + |
| 31 | +!$OMP PARALLEL NUM_THREADS(num_threads) |
| 32 | +!FIRDialect: omp.parallel num_threads(%{{.*}} : i32) { |
| 33 | +!FIRDialect-DAG: %[[OMP_VAR_A:.*]] = fir.load %[[VAR_A]] |
| 34 | +!FIRDialect-DAG: %[[OMP_VAR_B:.*]] = fir.load %[[VAR_B]] |
| 35 | +!FIRDialect: %[[OMP_VAR_C:.*]] = addi %[[OMP_VAR_A]], %[[OMP_VAR_B]] |
| 36 | +!FIRDialect: fir.store %[[OMP_VAR_C]] to %[[VAR_C]] |
| 37 | +!FIRDialect: %[[CONSTANT:.*]] = constant 4 : i32 |
| 38 | +!FIRDialect: %[[COND_C:.*]] = fir.load %[[VAR_C]] : !fir.ref<i32> |
| 39 | +!FIRDialect: %[[COND_RES:.*]] = cmpi "sgt", %[[COND_C]], %[[CONSTANT]] : i32 |
| 40 | +!FIRDialect: fir.if %[[COND_RES]] { |
| 41 | +!FIRDialect: fir.call @_FortranAioBeginExternalListOutput |
| 42 | +!FIRDialect: fir.call @_FortranAioOutputAscii |
| 43 | +!FIRDialect: fir.call @_FortranAioEndIoStatement |
| 44 | +!FIRDialect: } else { |
| 45 | +!FIRDialect-NEXT: } |
| 46 | +!FIRDialect: fir.call @_FortranAioBeginExternalListOutput |
| 47 | +!FIRDialect: fir.load %[[VAR_C]] |
| 48 | +!FIRDialect: fir.call @_FortranAioOutputInteger64 |
| 49 | +!FIRDialect: fir.call @_FortranAioEndIoStatement |
| 50 | +!FIRDialect: omp.terminator |
| 51 | +!FIRDialect-NEXT: } |
| 52 | + |
| 53 | +!LLVMIRDialect-LABEL: omp.parallel num_threads(%{{.*}} : !llvm.i32) { |
| 54 | +!LLVMIRDialect-DAG: %[[OMP_VAR_A:.*]] = llvm.load %[[VAR_A:.*]] |
| 55 | +!LLVMIRDialect-DAG: %[[OMP_VAR_B:.*]] = llvm.load %[[VAR_B:.*]] |
| 56 | +!LLVMIRDialect: %[[OMP_VAR_C:.*]] = llvm.add %[[OMP_VAR_B]], %[[OMP_VAR_A]] |
| 57 | +!LLVMIRDialect: llvm.store %[[OMP_VAR_C]], %[[VAR_C]] |
| 58 | +!LLVMIRDialect: %[[COND_C:.*]] = llvm.load %[[VAR_C]] : !llvm.ptr<i32> |
| 59 | +!LLVMIRDialect: %[[COND_RES:.*]] = llvm.icmp "sgt" %[[COND_C]], %{{.*}} : !llvm.i32 |
| 60 | +!LLVMIRDialect: llvm.cond_br %[[COND_RES]], ^bb1, ^bb2 |
| 61 | +!LLVMIRDialect: ^bb1: // pred: ^bb0 |
| 62 | +!LLVMIRDialect: llvm.call @_FortranAioBeginExternalListOutput |
| 63 | +!LLVMIRDialect: llvm.call @_FortranAioOutputAscii |
| 64 | +!LLVMIRDialect: llvm.call @_FortranAioEndIoStatement |
| 65 | +!LLVMIRDialect: llvm.br ^bb2 |
| 66 | +!LLVMIRDialect: ^bb2: // 2 preds: ^bb0, ^bb1 |
| 67 | +!LLVMIRDialect: llvm.call @_FortranAioBeginExternalListOutput |
| 68 | +!LLVMIRDialect: llvm.load %[[VAR_C]] : !llvm.ptr<i32> |
| 69 | +!LLVMIRDialect: llvm.call @_FortranAioOutputInteger64 |
| 70 | +!LLVMIRDialect: llvm.call @_FortranAioEndIoStatement |
| 71 | +!LLVMIRDialect: omp.terminator |
| 72 | +!LLVMIRDialect-NEXT: } |
| 73 | + |
| 74 | +!LLVMIR: call {{.*}} @__kmpc_fork_call(%struct.ident_t* @{{.*}} @_QQmain..omp_par |
| 75 | + |
| 76 | +!LLVMIR-LABEL: define internal void @_QQmain..omp_par |
| 77 | +!LLVMIR: br label %[[REGION_1:.*]] |
| 78 | +!LLVMIR: [[REGION_1]]: |
| 79 | +!LLVMIR: br label %[[REGION_1_1:.*]] |
| 80 | +!LLVMIR: [[REGION_1_1]]: |
| 81 | +!LLVMIR: %[[COND_RES:.*]] = icmp sgt i32 %{{.*}}, 4 |
| 82 | +!LLVMIR: br i1 %[[COND_RES]], label %{{.*}}, label %{{.*}} |
| 83 | +!LLVMIR: call i8* @_FortranAioBeginExternalListOutput |
| 84 | +!LLVMIR: call i1 @_FortranAioOutputInteger64 |
| 85 | +!LLVMIR: call i32 @_FortranAioEndIoStatement |
| 86 | + c = a + b |
| 87 | + |
| 88 | + if (c .gt. 4) then |
| 89 | + print*, "Inside If Statement" |
| 90 | + endif |
| 91 | + |
| 92 | + print*, c |
| 93 | + |
| 94 | +!$OMP END PARALLEL |
| 95 | + |
| 96 | +!$OMP PARALLEL |
| 97 | + print*, "Second Region" |
| 98 | +!FIRDialect: omp.parallel { |
| 99 | +!FIRDialect: fir.call @_FortranAioBeginExternalListOutput |
| 100 | +!FIRDialect: fir.call @_FortranAioOutputAscii |
| 101 | +!FIRDialect: fir.call @_FortranAioEndIoStatement |
| 102 | +!FIRDialect: omp.terminator |
| 103 | +!FIRDialect-NEXT: } |
| 104 | + |
| 105 | +!LLVMIRDialect: omp.parallel { |
| 106 | +!LLVMIRDialect: llvm.call @_FortranAioBeginExternalListOutput |
| 107 | +!LLVMIRDialect: llvm.call @_FortranAioOutputAscii |
| 108 | +!LLVMIRDialect: llvm.call @_FortranAioEndIoStatement |
| 109 | +!LLVMIRDialect: omp.terminator |
| 110 | +!LLVMIRDialect: } |
| 111 | + |
| 112 | +!LLVMIR-DAG-LABEL: call {{.*}} @__kmpc_fork_call(%struct.ident_t* @{{.*}} @_QQmain..omp_par.1 |
| 113 | +!LLVMIR-DAG-LABEL: define internal void @_QQmain..omp_par.1 |
| 114 | +!LLVMIR: call i8* @_FortranAioBeginExternalListOutput |
| 115 | +!LLVMIR: call i32 @_FortranAioEndIoStatement |
| 116 | +!$OMP END PARALLEL |
| 117 | + |
| 118 | +end program |
0 commit comments