diff --git a/flang/test/Lower/OpenMP/critical.f90 b/flang/test/Lower/OpenMP/critical.f90 --- a/flang/test/Lower/OpenMP/critical.f90 +++ b/flang/test/Lower/OpenMP/critical.f90 @@ -1,41 +1,36 @@ -!RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s --check-prefix="FIRDialect" -!RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefix="LLVMDialect" +!RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s --check-prefixes="OMPDialect" +!RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefix="OMPDialect" !RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | fir-opt --fir-to-llvm-ir | tco | FileCheck %s --check-prefix="LLVMIR" +!OMPDialect: omp.critical.declare @help2 hint(none) +!OMPDialect: omp.critical.declare @help1 hint(contended) + subroutine omp_critical() use omp_lib integer :: x, y -!FIRDialect: omp.critical.declare @help hint(contended) -!LLVMDialect: omp.critical.declare @help hint(contended) -!FIRDialect: omp.critical(@help) -!LLVMDialect: omp.critical(@help) -!LLVMIR: call void @__kmpc_critical_with_hint({{.*}}, {{.*}}, {{.*}} @{{.*}}help.var, i32 2) -!$OMP CRITICAL(help) HINT(omp_lock_hint_contended) +!OMPDialect: omp.critical(@help1) +!LLVMIR: call void @__kmpc_critical_with_hint({{.*}}, {{.*}}, {{.*}} @{{.*}}help1.var, i32 2) +!$OMP CRITICAL(help1) HINT(omp_lock_hint_contended) x = x + y -!FIRDialect: omp.terminator -!LLVMDialect: omp.terminator -!LLVMIR: call void @__kmpc_end_critical({{.*}}, {{.*}}, {{.*}} @{{.*}}help.var) -!$OMP END CRITICAL(help) +!OMPDialect: omp.terminator +!LLVMIR: call void @__kmpc_end_critical({{.*}}, {{.*}}, {{.*}} @{{.*}}help1.var) +!$OMP END CRITICAL(help1) ! Test that the same name can be used again ! Also test with the zero hint expression -!FIRDialect: omp.critical(@help) -!LLVMDialect: omp.critical(@help) -!LLVMIR: call void @__kmpc_critical_with_hint({{.*}}, {{.*}}, {{.*}} @{{.*}}help.var, i32 2) -!$OMP CRITICAL(help) HINT(omp_lock_hint_none) +!OMPDialect: omp.critical(@help2) +!LLVMIR: call void @__kmpc_critical_with_hint({{.*}}, {{.*}}, {{.*}} @{{.*}}help2.var, i32 0) +!$OMP CRITICAL(help2) HINT(omp_lock_hint_none) x = x - y -!FIRDialect: omp.terminator -!LLVMDialect: omp.terminator -!LLVMIR: call void @__kmpc_end_critical({{.*}}, {{.*}}, {{.*}} @{{.*}}help.var) -!$OMP END CRITICAL(help) +!OMPDialect: omp.terminator +!LLVMIR: call void @__kmpc_end_critical({{.*}}, {{.*}}, {{.*}} @{{.*}}help2.var) +!$OMP END CRITICAL(help2) -!FIRDialect: omp.critical -!LLVMDialect: omp.critical +!OMPDialect: omp.critical !LLVMIR: call void @__kmpc_critical({{.*}}, {{.*}}, {{.*}} @{{.*}}_.var) !$OMP CRITICAL y = x + y -!FIRDialect: omp.terminator -!LLVMDialect: omp.terminator +!OMPDialect: omp.terminator !LLVMIR: call void @__kmpc_end_critical({{.*}}, {{.*}}, {{.*}} @{{.*}}_.var) !$OMP END CRITICAL end subroutine omp_critical diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td --- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td +++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td @@ -946,6 +946,7 @@ $region attr-dict }]; let hasRegionVerifier = 1; + let hasVerifier = 1; let extraClassDeclaration = [{ /// Returns the first operation in atomic capture region Operation* getFirstOp(); diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp --- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp +++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp @@ -382,6 +382,10 @@ IntegerAttr &hintAttr) { StringRef hintKeyword; int64_t hint = 0; + if (succeeded(parser.parseOptionalKeyword("none"))) { + hintAttr = IntegerAttr::get(parser.getBuilder().getI64Type(), 0); + return success(); + } do { if (failed(parser.parseKeyword(&hintKeyword))) return failure(); @@ -406,8 +410,10 @@ IntegerAttr hintAttr) { int64_t hint = hintAttr.getInt(); - if (hint == 0) + if (hint == 0) { + p << "none"; return; + } // Helper function to get n-th bit from the right end of `value` auto bitn = [](int value, int n) -> bool { return value & (1 << n); }; @@ -864,7 +870,7 @@ "element type is the same as that of the region argument"); } - return success(); + return verifySynchronizationHint(*this, hint_val()); } LogicalResult AtomicUpdateOp::verifyRegions() { @@ -915,6 +921,10 @@ return dyn_cast(getSecondOp()); } +LogicalResult AtomicCaptureOp::verify() { + return verifySynchronizationHint(*this, hint_val()); +} + LogicalResult AtomicCaptureOp::verifyRegions() { Block::OpListType &ops = region().front().getOperations(); if (ops.size() != 3) @@ -949,6 +959,10 @@ return firstReadStmt.emitError() << "captured variable in omp.atomic.read must be updated in " "second operation"; + + if (getFirstOp()->getAttr("hint_val") || getSecondOp()->getAttr("hint_val")) + return emitOpError( + "operations inside capture region must not have hint clause"); return success(); } diff --git a/mlir/test/Dialect/OpenMP/invalid.mlir b/mlir/test/Dialect/OpenMP/invalid.mlir --- a/mlir/test/Dialect/OpenMP/invalid.mlir +++ b/mlir/test/Dialect/OpenMP/invalid.mlir @@ -708,6 +708,42 @@ // ----- +func @omp_atomic_update(%x: memref, %expr: i32) { + // expected-error @below {{the hints omp_sync_hint_uncontended and omp_sync_hint_contended cannot be combined}} + omp.atomic.update hint(uncontended, contended) %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield (%newval : i32) + } + return +} + +// ----- + +func @omp_atomic_update(%x: memref, %expr: i32) { + // expected-error @below {{the hints omp_sync_hint_nonspeculative and omp_sync_hint_speculative cannot be combined}} + omp.atomic.update hint(nonspeculative, speculative) %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield (%newval : i32) + } + return +} + +// ----- + +func @omp_atomic_update(%x: memref, %expr: i32) { + // expected-error @below {{invalid_hint is not a valid hint}} + omp.atomic.update hint(invalid_hint) %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield (%newval : i32) + } + return +} + +// ----- + func @omp_atomic_capture(%x: memref, %v: memref, %expr: i32) { // expected-error @below {{expected three operations in omp.atomic.capture region}} omp.atomic.capture { @@ -848,6 +884,66 @@ // ----- +func @omp_atomic_capture(%x: memref, %v: memref, %expr: i32) { + // expected-error @below {{the hints omp_sync_hint_uncontended and omp_sync_hint_contended cannot be combined}} + omp.atomic.capture hint(contended, uncontended) { + omp.atomic.update %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + omp.atomic.read %v = %x : memref + } + return +} + +// ----- + +func @omp_atomic_capture(%x: memref, %v: memref, %expr: i32) { + // expected-error @below {{the hints omp_sync_hint_nonspeculative and omp_sync_hint_speculative cannot be combined}} + omp.atomic.capture hint(nonspeculative, speculative) { + omp.atomic.update %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + omp.atomic.read %v = %x : memref + } + return +} + +// ----- + +func @omp_atomic_capture(%x: memref, %v: memref, %expr: i32) { + // expected-error @below {{invalid_hint is not a valid hint}} + omp.atomic.capture hint(invalid_hint) { + omp.atomic.update %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + omp.atomic.read %v = %x : memref + } + return +} + +// ----- + +func @omp_atomic_capture(%x: memref, %v: memref, %expr: i32) { + // expected-error @below {{operations inside capture region must not have hint clause}} + omp.atomic.capture { + omp.atomic.update hint(uncontended) %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + omp.atomic.read %v = %x : memref + } + return +} + +// ----- + func @omp_sections(%data_var : memref) -> () { // expected-error @below {{expected equal sizes for allocate and allocator variables}} "omp.sections" (%data_var) ({ diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir --- a/mlir/test/Dialect/OpenMP/ops.mlir +++ b/mlir/test/Dialect/OpenMP/ops.mlir @@ -583,6 +583,10 @@ omp.critical.declare @mutex7 hint(uncontended, speculative) // CHECK: omp.critical.declare @mutex8 hint(contended, speculative) omp.critical.declare @mutex8 hint(contended, speculative) +// CHECK: omp.critical.declare @mutex9 hint(none) +omp.critical.declare @mutex9 hint(none) +// CHECK: omp.critical.declare @mutex10 +omp.critical.declare @mutex10 // CHECK-LABEL: omp_critical @@ -657,6 +661,8 @@ omp.atomic.read %v = %x hint(nonspeculative, contended) : memref // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(seq_cst) hint(contended, speculative) : memref omp.atomic.read %v = %x hint(speculative, contended) memory_order(seq_cst) : memref + // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(seq_cst) hint(none) : memref + omp.atomic.read %v = %x hint(none) memory_order(seq_cst) : memref return } @@ -673,6 +679,8 @@ omp.atomic.write %addr = %val memory_order(relaxed) : memref, i32 // CHECK: omp.atomic.write %[[ADDR]] = %[[VAL]] hint(uncontended, speculative) : memref, i32 omp.atomic.write %addr = %val hint(speculative, uncontended) : memref, i32 + // CHECK: omp.atomic.write %[[ADDR]] = %[[VAL]] hint(none) : memref, i32 + omp.atomic.write %addr = %val hint(none) : memref, i32 return } @@ -728,6 +736,97 @@ %newval = llvm.icmp "eq" %xval, %exprBool : i1 omp.yield(%newval : i1) } + + // CHECK: omp.atomic.update hint(none) %[[X]] : memref + // CHECK-NEXT: (%[[XVAL:.*]]: i32): + // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i32 + // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32) + omp.atomic.update hint(none) %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + + // CHECK: omp.atomic.update hint(uncontended) %[[X]] : memref + // CHECK-NEXT: (%[[XVAL:.*]]: i32): + // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i32 + // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32) + omp.atomic.update hint(uncontended) %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + + // CHECK: omp.atomic.update hint(contended) %[[X]] : memref + // CHECK-NEXT: (%[[XVAL:.*]]: i32): + // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i32 + // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32) + omp.atomic.update hint(contended) %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + + // CHECK: omp.atomic.update hint(nonspeculative) %[[X]] : memref + // CHECK-NEXT: (%[[XVAL:.*]]: i32): + // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i32 + // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32) + omp.atomic.update hint(nonspeculative) %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + + // CHECK: omp.atomic.update hint(speculative) %[[X]] : memref + // CHECK-NEXT: (%[[XVAL:.*]]: i32): + // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i32 + // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32) + omp.atomic.update hint(speculative) %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + + // CHECK: omp.atomic.update hint(uncontended, nonspeculative) %[[X]] : memref + // CHECK-NEXT: (%[[XVAL:.*]]: i32): + // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i32 + // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32) + omp.atomic.update hint(uncontended, nonspeculative) %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + + // CHECK: omp.atomic.update hint(contended, nonspeculative) %[[X]] : memref + // CHECK-NEXT: (%[[XVAL:.*]]: i32): + // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i32 + // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32) + omp.atomic.update hint(contended, nonspeculative) %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + + // CHECK: omp.atomic.update hint(uncontended, speculative) %[[X]] : memref + // CHECK-NEXT: (%[[XVAL:.*]]: i32): + // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i32 + // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32) + omp.atomic.update hint(uncontended, speculative) %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + + // CHECK: omp.atomic.update hint(contended, speculative) %[[X]] : memref + // CHECK-NEXT: (%[[XVAL:.*]]: i32): + // CHECK-NEXT: %[[NEWVAL:.*]] = llvm.add %[[XVAL]], %[[EXPR]] : i32 + // CHECK-NEXT: omp.yield(%[[NEWVAL]] : i32) + omp.atomic.update hint(contended, speculative) %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + return } @@ -774,6 +873,159 @@ omp.atomic.read %v = %x : memref omp.atomic.write %x = %expr : memref, i32 } + + // CHECK: omp.atomic.capture hint(none) { + // CHECK-NEXT: omp.atomic.update %[[x]] : memref + // CHECK-NEXT: (%[[xval:.*]]: i32): + // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 + // CHECK-NEXT: omp.yield(%[[newval]] : i32) + // CHECK-NEXT: } + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: } + omp.atomic.capture hint(none) { + omp.atomic.update %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + omp.atomic.read %v = %x : memref + } + + // CHECK: omp.atomic.capture hint(uncontended) { + // CHECK-NEXT: omp.atomic.update %[[x]] : memref + // CHECK-NEXT: (%[[xval:.*]]: i32): + // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 + // CHECK-NEXT: omp.yield(%[[newval]] : i32) + // CHECK-NEXT: } + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: } + omp.atomic.capture hint(uncontended) { + omp.atomic.update %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + omp.atomic.read %v = %x : memref + } + + // CHECK: omp.atomic.capture hint(contended) { + // CHECK-NEXT: omp.atomic.update %[[x]] : memref + // CHECK-NEXT: (%[[xval:.*]]: i32): + // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 + // CHECK-NEXT: omp.yield(%[[newval]] : i32) + // CHECK-NEXT: } + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: } + omp.atomic.capture hint(contended) { + omp.atomic.update %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + omp.atomic.read %v = %x : memref + } + + // CHECK: omp.atomic.capture hint(nonspeculative) { + // CHECK-NEXT: omp.atomic.update %[[x]] : memref + // CHECK-NEXT: (%[[xval:.*]]: i32): + // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 + // CHECK-NEXT: omp.yield(%[[newval]] : i32) + // CHECK-NEXT: } + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: } + omp.atomic.capture hint(nonspeculative) { + omp.atomic.update %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + omp.atomic.read %v = %x : memref + } + + // CHECK: omp.atomic.capture hint(speculative) { + // CHECK-NEXT: omp.atomic.update %[[x]] : memref + // CHECK-NEXT: (%[[xval:.*]]: i32): + // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 + // CHECK-NEXT: omp.yield(%[[newval]] : i32) + // CHECK-NEXT: } + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: } + omp.atomic.capture hint(speculative) { + omp.atomic.update %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + omp.atomic.read %v = %x : memref + } + + // CHECK: omp.atomic.capture hint(uncontended, nonspeculative) { + // CHECK-NEXT: omp.atomic.update %[[x]] : memref + // CHECK-NEXT: (%[[xval:.*]]: i32): + // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 + // CHECK-NEXT: omp.yield(%[[newval]] : i32) + // CHECK-NEXT: } + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: } + omp.atomic.capture hint(uncontended, nonspeculative) { + omp.atomic.update %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + omp.atomic.read %v = %x : memref + } + + // CHECK: omp.atomic.capture hint(contended, nonspeculative) { + // CHECK-NEXT: omp.atomic.update %[[x]] : memref + // CHECK-NEXT: (%[[xval:.*]]: i32): + // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 + // CHECK-NEXT: omp.yield(%[[newval]] : i32) + // CHECK-NEXT: } + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: } + omp.atomic.capture hint(contended, nonspeculative) { + omp.atomic.update %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + omp.atomic.read %v = %x : memref + } + + // CHECK: omp.atomic.capture hint(uncontended, speculative) { + // CHECK-NEXT: omp.atomic.update %[[x]] : memref + // CHECK-NEXT: (%[[xval:.*]]: i32): + // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 + // CHECK-NEXT: omp.yield(%[[newval]] : i32) + // CHECK-NEXT: } + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: } + omp.atomic.capture hint(uncontended, speculative) { + omp.atomic.update %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + omp.atomic.read %v = %x : memref + } + + // CHECK: omp.atomic.capture hint(contended, speculative) { + // CHECK-NEXT: omp.atomic.update %[[x]] : memref + // CHECK-NEXT: (%[[xval:.*]]: i32): + // CHECK-NEXT: %[[newval:.*]] = llvm.add %[[xval]], %[[expr]] : i32 + // CHECK-NEXT: omp.yield(%[[newval]] : i32) + // CHECK-NEXT: } + // CHECK-NEXT: omp.atomic.read %[[v]] = %[[x]] : memref + // CHECK-NEXT: } + omp.atomic.capture hint(contended, speculative) { + omp.atomic.update %x : memref { + ^bb0(%xval: i32): + %newval = llvm.add %xval, %expr : i32 + omp.yield(%newval : i32) + } + omp.atomic.read %v = %x : memref + } return } diff --git a/mlir/test/Target/LLVMIR/openmp-llvm.mlir b/mlir/test/Target/LLVMIR/openmp-llvm.mlir --- a/mlir/test/Target/LLVMIR/openmp-llvm.mlir +++ b/mlir/test/Target/LLVMIR/openmp-llvm.mlir @@ -891,7 +891,15 @@ // ----- -omp.critical.declare @mutex hint(contended) +omp.critical.declare @mutex_none hint(none) // 0 +omp.critical.declare @mutex_uncontended hint(uncontended) // 1 +omp.critical.declare @mutex_contended hint(contended) // 2 +omp.critical.declare @mutex_nonspeculative hint(nonspeculative) // 4 +omp.critical.declare @mutex_nonspeculative_uncontended hint(nonspeculative, uncontended) // 5 +omp.critical.declare @mutex_nonspeculative_contended hint(nonspeculative, contended) // 6 +omp.critical.declare @mutex_speculative hint(speculative) // 8 +omp.critical.declare @mutex_speculative_uncontended hint(speculative, uncontended) // 9 +omp.critical.declare @mutex_speculative_contended hint(speculative, contended) // 10 // CHECK-LABEL: @omp_critical llvm.func @omp_critical(%x : !llvm.ptr, %xval : i32) -> () { @@ -905,15 +913,95 @@ } // CHECK: call void @__kmpc_end_critical({{.*}}critical_user_.var{{.*}}) - // CHECK: call void @__kmpc_critical_with_hint({{.*}}critical_user_mutex.var{{.*}}, i32 2) + // CHECK: call void @__kmpc_critical_with_hint({{.*}}critical_user_mutex_none.var{{.*}}, i32 0) // CHECK: br label %omp.critical.region // CHECK: omp.critical.region - omp.critical(@mutex) { + omp.critical(@mutex_none) { // CHECK: store llvm.store %xval, %x : !llvm.ptr omp.terminator } - // CHECK: call void @__kmpc_end_critical({{.*}}critical_user_mutex.var{{.*}}) + // CHECK: call void @__kmpc_end_critical({{.*}}critical_user_mutex_none.var{{.*}}) + + // CHECK: call void @__kmpc_critical_with_hint({{.*}}critical_user_mutex_uncontended.var{{.*}}, i32 1) + // CHECK: br label %omp.critical.region + // CHECK: omp.critical.region + omp.critical(@mutex_uncontended) { + // CHECK: store + llvm.store %xval, %x : !llvm.ptr + omp.terminator + } + // CHECK: call void @__kmpc_end_critical({{.*}}critical_user_mutex_uncontended.var{{.*}}) + + // CHECK: call void @__kmpc_critical_with_hint({{.*}}critical_user_mutex_contended.var{{.*}}, i32 2) + // CHECK: br label %omp.critical.region + // CHECK: omp.critical.region + omp.critical(@mutex_contended) { + // CHECK: store + llvm.store %xval, %x : !llvm.ptr + omp.terminator + } + // CHECK: call void @__kmpc_end_critical({{.*}}critical_user_mutex_contended.var{{.*}}) + + // CHECK: call void @__kmpc_critical_with_hint({{.*}}critical_user_mutex_nonspeculative.var{{.*}}, i32 4) + // CHECK: br label %omp.critical.region + // CHECK: omp.critical.region + omp.critical(@mutex_nonspeculative) { + // CHECK: store + llvm.store %xval, %x : !llvm.ptr + omp.terminator + } + // CHECK: call void @__kmpc_end_critical({{.*}}critical_user_mutex_nonspeculative.var{{.*}}) + + // CHECK: call void @__kmpc_critical_with_hint({{.*}}critical_user_mutex_nonspeculative_uncontended.var{{.*}}, i32 5) + // CHECK: br label %omp.critical.region + // CHECK: omp.critical.region + omp.critical(@mutex_nonspeculative_uncontended) { + // CHECK: store + llvm.store %xval, %x : !llvm.ptr + omp.terminator + } + // CHECK: call void @__kmpc_end_critical({{.*}}critical_user_mutex_nonspeculative_uncontended.var{{.*}}) + + // CHECK: call void @__kmpc_critical_with_hint({{.*}}critical_user_mutex_nonspeculative_contended.var{{.*}}, i32 6) + // CHECK: br label %omp.critical.region + // CHECK: omp.critical.region + omp.critical(@mutex_nonspeculative_contended) { + // CHECK: store + llvm.store %xval, %x : !llvm.ptr + omp.terminator + } + // CHECK: call void @__kmpc_end_critical({{.*}}critical_user_mutex_nonspeculative_contended.var{{.*}}) + + // CHECK: call void @__kmpc_critical_with_hint({{.*}}critical_user_mutex_speculative.var{{.*}}, i32 8) + // CHECK: br label %omp.critical.region + // CHECK: omp.critical.region + omp.critical(@mutex_speculative) { + // CHECK: store + llvm.store %xval, %x : !llvm.ptr + omp.terminator + } + // CHECK: call void @__kmpc_end_critical({{.*}}critical_user_mutex_speculative.var{{.*}}) + + // CHECK: call void @__kmpc_critical_with_hint({{.*}}critical_user_mutex_speculative_uncontended.var{{.*}}, i32 9) + // CHECK: br label %omp.critical.region + // CHECK: omp.critical.region + omp.critical(@mutex_speculative_uncontended) { + // CHECK: store + llvm.store %xval, %x : !llvm.ptr + omp.terminator + } + // CHECK: call void @__kmpc_end_critical({{.*}}critical_user_mutex_speculative_uncontended.var{{.*}}) + + // CHECK: call void @__kmpc_critical_with_hint({{.*}}critical_user_mutex_speculative_contended.var{{.*}}, i32 10) + // CHECK: br label %omp.critical.region + // CHECK: omp.critical.region + omp.critical(@mutex_speculative_contended) { + // CHECK: store + llvm.store %xval, %x : !llvm.ptr + omp.terminator + } + // CHECK: call void @__kmpc_end_critical({{.*}}critical_user_mutex_speculative_contended.var{{.*}}) llvm.return }