[mlir][OpenMP] Add checks and tests for hint clause and fix empty hint
This patch handles empty hint value for critical and atomic constructs. This also adds checks and tests for hint clause on atomic constructs. Reviewed By: peixin, kiranchandramohan, NimishMishra Differential Revision: https://reviews.llvm.org/D123186
This commit is contained in:
		
							parent
							
								
									7895c87367
								
							
						
					
					
						commit
						88bb2521b0
					
				| 
						 | 
					@ -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 - | FileCheck %s --check-prefixes="OMPDialect"
 | 
				
			||||||
!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 - | 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"
 | 
					!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()
 | 
					subroutine omp_critical()
 | 
				
			||||||
  use omp_lib
 | 
					  use omp_lib
 | 
				
			||||||
  integer :: x, y
 | 
					  integer :: x, y
 | 
				
			||||||
!FIRDialect: omp.critical.declare @help hint(contended)
 | 
					!OMPDialect: omp.critical(@help1)
 | 
				
			||||||
!LLVMDialect: omp.critical.declare @help hint(contended)
 | 
					!LLVMIR: call void @__kmpc_critical_with_hint({{.*}}, {{.*}}, {{.*}} @{{.*}}help1.var, i32 2)
 | 
				
			||||||
!FIRDialect: omp.critical(@help)
 | 
					!$OMP CRITICAL(help1) HINT(omp_lock_hint_contended)
 | 
				
			||||||
!LLVMDialect: omp.critical(@help)
 | 
					 | 
				
			||||||
!LLVMIR: call void @__kmpc_critical_with_hint({{.*}}, {{.*}}, {{.*}} @{{.*}}help.var, i32 2)
 | 
					 | 
				
			||||||
!$OMP CRITICAL(help) HINT(omp_lock_hint_contended)
 | 
					 | 
				
			||||||
  x = x + y
 | 
					  x = x + y
 | 
				
			||||||
!FIRDialect: omp.terminator
 | 
					!OMPDialect: omp.terminator
 | 
				
			||||||
!LLVMDialect: omp.terminator
 | 
					!LLVMIR: call void @__kmpc_end_critical({{.*}}, {{.*}}, {{.*}} @{{.*}}help1.var)
 | 
				
			||||||
!LLVMIR: call void @__kmpc_end_critical({{.*}}, {{.*}}, {{.*}} @{{.*}}help.var)
 | 
					!$OMP END CRITICAL(help1)
 | 
				
			||||||
!$OMP END CRITICAL(help)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
! Test that the same name can be used again
 | 
					! Test that the same name can be used again
 | 
				
			||||||
! Also test with the zero hint expression
 | 
					! Also test with the zero hint expression
 | 
				
			||||||
!FIRDialect: omp.critical(@help)
 | 
					!OMPDialect: omp.critical(@help2)
 | 
				
			||||||
!LLVMDialect: omp.critical(@help)
 | 
					!LLVMIR: call void @__kmpc_critical_with_hint({{.*}}, {{.*}}, {{.*}} @{{.*}}help2.var, i32 0)
 | 
				
			||||||
!LLVMIR: call void @__kmpc_critical_with_hint({{.*}}, {{.*}}, {{.*}} @{{.*}}help.var, i32 2)
 | 
					!$OMP CRITICAL(help2) HINT(omp_lock_hint_none)
 | 
				
			||||||
!$OMP CRITICAL(help) HINT(omp_lock_hint_none)
 | 
					 | 
				
			||||||
  x = x - y
 | 
					  x = x - y
 | 
				
			||||||
!FIRDialect: omp.terminator
 | 
					!OMPDialect: omp.terminator
 | 
				
			||||||
!LLVMDialect: omp.terminator
 | 
					!LLVMIR: call void @__kmpc_end_critical({{.*}}, {{.*}}, {{.*}} @{{.*}}help2.var)
 | 
				
			||||||
!LLVMIR: call void @__kmpc_end_critical({{.*}}, {{.*}}, {{.*}} @{{.*}}help.var)
 | 
					!$OMP END CRITICAL(help2)
 | 
				
			||||||
!$OMP END CRITICAL(help)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
!FIRDialect: omp.critical
 | 
					!OMPDialect: omp.critical
 | 
				
			||||||
!LLVMDialect: omp.critical
 | 
					 | 
				
			||||||
!LLVMIR: call void @__kmpc_critical({{.*}}, {{.*}}, {{.*}} @{{.*}}_.var)
 | 
					!LLVMIR: call void @__kmpc_critical({{.*}}, {{.*}}, {{.*}} @{{.*}}_.var)
 | 
				
			||||||
!$OMP CRITICAL
 | 
					!$OMP CRITICAL
 | 
				
			||||||
  y = x + y
 | 
					  y = x + y
 | 
				
			||||||
!FIRDialect: omp.terminator
 | 
					!OMPDialect: omp.terminator
 | 
				
			||||||
!LLVMDialect: omp.terminator
 | 
					 | 
				
			||||||
!LLVMIR: call void @__kmpc_end_critical({{.*}}, {{.*}}, {{.*}} @{{.*}}_.var)
 | 
					!LLVMIR: call void @__kmpc_end_critical({{.*}}, {{.*}}, {{.*}} @{{.*}}_.var)
 | 
				
			||||||
!$OMP END CRITICAL
 | 
					!$OMP END CRITICAL
 | 
				
			||||||
end subroutine omp_critical
 | 
					end subroutine omp_critical
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -946,6 +946,7 @@ def AtomicCaptureOp : OpenMP_Op<"atomic.capture",
 | 
				
			||||||
    $region attr-dict
 | 
					    $region attr-dict
 | 
				
			||||||
  }];
 | 
					  }];
 | 
				
			||||||
  let hasRegionVerifier = 1;
 | 
					  let hasRegionVerifier = 1;
 | 
				
			||||||
 | 
					  let hasVerifier = 1;
 | 
				
			||||||
  let extraClassDeclaration = [{
 | 
					  let extraClassDeclaration = [{
 | 
				
			||||||
    /// Returns the first operation in atomic capture region
 | 
					    /// Returns the first operation in atomic capture region
 | 
				
			||||||
    Operation* getFirstOp();
 | 
					    Operation* getFirstOp();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -382,6 +382,10 @@ static ParseResult parseSynchronizationHint(OpAsmParser &parser,
 | 
				
			||||||
                                            IntegerAttr &hintAttr) {
 | 
					                                            IntegerAttr &hintAttr) {
 | 
				
			||||||
  StringRef hintKeyword;
 | 
					  StringRef hintKeyword;
 | 
				
			||||||
  int64_t hint = 0;
 | 
					  int64_t hint = 0;
 | 
				
			||||||
 | 
					  if (succeeded(parser.parseOptionalKeyword("none"))) {
 | 
				
			||||||
 | 
					    hintAttr = IntegerAttr::get(parser.getBuilder().getI64Type(), 0);
 | 
				
			||||||
 | 
					    return success();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  do {
 | 
					  do {
 | 
				
			||||||
    if (failed(parser.parseKeyword(&hintKeyword)))
 | 
					    if (failed(parser.parseKeyword(&hintKeyword)))
 | 
				
			||||||
      return failure();
 | 
					      return failure();
 | 
				
			||||||
| 
						 | 
					@ -406,8 +410,10 @@ static void printSynchronizationHint(OpAsmPrinter &p, Operation *op,
 | 
				
			||||||
                                     IntegerAttr hintAttr) {
 | 
					                                     IntegerAttr hintAttr) {
 | 
				
			||||||
  int64_t hint = hintAttr.getInt();
 | 
					  int64_t hint = hintAttr.getInt();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (hint == 0)
 | 
					  if (hint == 0) {
 | 
				
			||||||
 | 
					    p << "none";
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Helper function to get n-th bit from the right end of `value`
 | 
					  // Helper function to get n-th bit from the right end of `value`
 | 
				
			||||||
  auto bitn = [](int value, int n) -> bool { return value & (1 << n); };
 | 
					  auto bitn = [](int value, int n) -> bool { return value & (1 << n); };
 | 
				
			||||||
| 
						 | 
					@ -864,7 +870,7 @@ LogicalResult AtomicUpdateOp::verify() {
 | 
				
			||||||
                     "element type is the same as that of the region argument");
 | 
					                     "element type is the same as that of the region argument");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return success();
 | 
					  return verifySynchronizationHint(*this, hint_val());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LogicalResult AtomicUpdateOp::verifyRegions() {
 | 
					LogicalResult AtomicUpdateOp::verifyRegions() {
 | 
				
			||||||
| 
						 | 
					@ -915,6 +921,10 @@ AtomicUpdateOp AtomicCaptureOp::getAtomicUpdateOp() {
 | 
				
			||||||
  return dyn_cast<AtomicUpdateOp>(getSecondOp());
 | 
					  return dyn_cast<AtomicUpdateOp>(getSecondOp());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LogicalResult AtomicCaptureOp::verify() {
 | 
				
			||||||
 | 
					  return verifySynchronizationHint(*this, hint_val());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LogicalResult AtomicCaptureOp::verifyRegions() {
 | 
					LogicalResult AtomicCaptureOp::verifyRegions() {
 | 
				
			||||||
  Block::OpListType &ops = region().front().getOperations();
 | 
					  Block::OpListType &ops = region().front().getOperations();
 | 
				
			||||||
  if (ops.size() != 3)
 | 
					  if (ops.size() != 3)
 | 
				
			||||||
| 
						 | 
					@ -949,6 +959,10 @@ LogicalResult AtomicCaptureOp::verifyRegions() {
 | 
				
			||||||
    return firstReadStmt.emitError()
 | 
					    return firstReadStmt.emitError()
 | 
				
			||||||
           << "captured variable in omp.atomic.read must be updated in "
 | 
					           << "captured variable in omp.atomic.read must be updated in "
 | 
				
			||||||
              "second operation";
 | 
					              "second operation";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (getFirstOp()->getAttr("hint_val") || getSecondOp()->getAttr("hint_val"))
 | 
				
			||||||
 | 
					    return emitOpError(
 | 
				
			||||||
 | 
					        "operations inside capture region must not have hint clause");
 | 
				
			||||||
  return success();
 | 
					  return success();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -708,6 +708,42 @@ func @omp_atomic_update9(%x: memref<i32>, %expr: i32) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// -----
 | 
					// -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func @omp_atomic_update(%x: memref<i32>, %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<i32> {
 | 
				
			||||||
 | 
					  ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					    %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					    omp.yield (%newval : i32)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func @omp_atomic_update(%x: memref<i32>, %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<i32> {
 | 
				
			||||||
 | 
					  ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					    %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					    omp.yield (%newval : i32)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func @omp_atomic_update(%x: memref<i32>, %expr: i32) {
 | 
				
			||||||
 | 
					  // expected-error @below {{invalid_hint is not a valid hint}}
 | 
				
			||||||
 | 
					  omp.atomic.update hint(invalid_hint) %x : memref<i32> {
 | 
				
			||||||
 | 
					  ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					    %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					    omp.yield (%newval : i32)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
 | 
					func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
 | 
				
			||||||
  // expected-error @below {{expected three operations in omp.atomic.capture region}}
 | 
					  // expected-error @below {{expected three operations in omp.atomic.capture region}}
 | 
				
			||||||
  omp.atomic.capture {
 | 
					  omp.atomic.capture {
 | 
				
			||||||
| 
						 | 
					@ -848,6 +884,66 @@ func @omp_atomic_capture(%x: memref<i32>, %y: memref<i32>, %v: memref<i32>, %exp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// -----
 | 
					// -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %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<i32> {
 | 
				
			||||||
 | 
					    ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					      %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					      omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    omp.atomic.read %v = %x : memref<i32>
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %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<i32> {
 | 
				
			||||||
 | 
					    ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					      %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					      omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    omp.atomic.read %v = %x : memref<i32>
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
 | 
				
			||||||
 | 
					  // expected-error @below {{invalid_hint is not a valid hint}}
 | 
				
			||||||
 | 
					  omp.atomic.capture hint(invalid_hint) {
 | 
				
			||||||
 | 
					    omp.atomic.update %x : memref<i32> {
 | 
				
			||||||
 | 
					    ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					      %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					      omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    omp.atomic.read %v = %x : memref<i32>
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
 | 
				
			||||||
 | 
					  // expected-error @below {{operations inside capture region must not have hint clause}}
 | 
				
			||||||
 | 
					  omp.atomic.capture {
 | 
				
			||||||
 | 
					    omp.atomic.update hint(uncontended) %x : memref<i32> {
 | 
				
			||||||
 | 
					    ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					      %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					      omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    omp.atomic.read %v = %x : memref<i32>
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func @omp_sections(%data_var : memref<i32>) -> () {
 | 
					func @omp_sections(%data_var : memref<i32>) -> () {
 | 
				
			||||||
  // expected-error @below {{expected equal sizes for allocate and allocator variables}}
 | 
					  // expected-error @below {{expected equal sizes for allocate and allocator variables}}
 | 
				
			||||||
  "omp.sections" (%data_var) ({
 | 
					  "omp.sections" (%data_var) ({
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -583,6 +583,10 @@ omp.critical.declare @mutex6 hint(contended, nonspeculative)
 | 
				
			||||||
omp.critical.declare @mutex7 hint(uncontended, speculative)
 | 
					omp.critical.declare @mutex7 hint(uncontended, speculative)
 | 
				
			||||||
// CHECK: omp.critical.declare @mutex8 hint(contended, speculative)
 | 
					// CHECK: omp.critical.declare @mutex8 hint(contended, speculative)
 | 
				
			||||||
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
 | 
					// CHECK-LABEL: omp_critical
 | 
				
			||||||
| 
						 | 
					@ -657,6 +661,8 @@ func @omp_atomic_read(%v: memref<i32>, %x: memref<i32>) {
 | 
				
			||||||
  omp.atomic.read %v = %x hint(nonspeculative, contended) : memref<i32>
 | 
					  omp.atomic.read %v = %x hint(nonspeculative, contended) : memref<i32>
 | 
				
			||||||
  // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(seq_cst) hint(contended, speculative) : memref<i32>
 | 
					  // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(seq_cst) hint(contended, speculative) : memref<i32>
 | 
				
			||||||
  omp.atomic.read %v = %x hint(speculative, contended) memory_order(seq_cst) : memref<i32>
 | 
					  omp.atomic.read %v = %x hint(speculative, contended) memory_order(seq_cst) : memref<i32>
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.read %[[v]] = %[[x]] memory_order(seq_cst) hint(none) : memref<i32>
 | 
				
			||||||
 | 
					  omp.atomic.read %v = %x hint(none) memory_order(seq_cst) : memref<i32>
 | 
				
			||||||
  return
 | 
					  return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -673,6 +679,8 @@ func @omp_atomic_write(%addr : memref<i32>, %val : i32) {
 | 
				
			||||||
  omp.atomic.write %addr = %val memory_order(relaxed) : memref<i32>, i32
 | 
					  omp.atomic.write %addr = %val memory_order(relaxed) : memref<i32>, i32
 | 
				
			||||||
  // CHECK: omp.atomic.write %[[ADDR]] = %[[VAL]] hint(uncontended, speculative) : memref<i32>, i32
 | 
					  // CHECK: omp.atomic.write %[[ADDR]] = %[[VAL]] hint(uncontended, speculative) : memref<i32>, i32
 | 
				
			||||||
  omp.atomic.write %addr = %val hint(speculative, uncontended) : memref<i32>, i32
 | 
					  omp.atomic.write %addr = %val hint(speculative, uncontended) : memref<i32>, i32
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.write %[[ADDR]] = %[[VAL]] hint(none) : memref<i32>, i32
 | 
				
			||||||
 | 
					  omp.atomic.write %addr = %val hint(none) : memref<i32>, i32
 | 
				
			||||||
  return
 | 
					  return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -728,6 +736,97 @@ func @omp_atomic_update(%x : memref<i32>, %expr : i32, %xBool : memref<i1>, %exp
 | 
				
			||||||
    %newval = llvm.icmp "eq" %xval, %exprBool : i1
 | 
					    %newval = llvm.icmp "eq" %xval, %exprBool : i1
 | 
				
			||||||
    omp.yield(%newval : i1)
 | 
					    omp.yield(%newval : i1)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.update hint(none) %[[X]] : memref<i32>
 | 
				
			||||||
 | 
					  // 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<i32> {
 | 
				
			||||||
 | 
					  ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					    %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					    omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.update hint(uncontended) %[[X]] : memref<i32>
 | 
				
			||||||
 | 
					  // 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<i32> {
 | 
				
			||||||
 | 
					  ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					    %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					    omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.update hint(contended) %[[X]] : memref<i32>
 | 
				
			||||||
 | 
					  // 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<i32> {
 | 
				
			||||||
 | 
					  ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					    %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					    omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.update hint(nonspeculative) %[[X]] : memref<i32>
 | 
				
			||||||
 | 
					  // 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<i32> {
 | 
				
			||||||
 | 
					  ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					    %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					    omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.update hint(speculative) %[[X]] : memref<i32>
 | 
				
			||||||
 | 
					  // 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<i32> {
 | 
				
			||||||
 | 
					  ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					    %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					    omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.update hint(uncontended, nonspeculative) %[[X]] : memref<i32>
 | 
				
			||||||
 | 
					  // 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<i32> {
 | 
				
			||||||
 | 
					  ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					    %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					    omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.update hint(contended, nonspeculative) %[[X]] : memref<i32>
 | 
				
			||||||
 | 
					  // 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<i32> {
 | 
				
			||||||
 | 
					  ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					    %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					    omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.update hint(uncontended, speculative) %[[X]] : memref<i32>
 | 
				
			||||||
 | 
					  // 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<i32> {
 | 
				
			||||||
 | 
					  ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					    %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					    omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.update hint(contended, speculative) %[[X]] : memref<i32>
 | 
				
			||||||
 | 
					  // 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<i32> {
 | 
				
			||||||
 | 
					  ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					    %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					    omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return
 | 
					  return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -774,6 +873,159 @@ func @omp_atomic_capture(%v: memref<i32>, %x: memref<i32>, %expr: i32) {
 | 
				
			||||||
    omp.atomic.read %v = %x : memref<i32>
 | 
					    omp.atomic.read %v = %x : memref<i32>
 | 
				
			||||||
    omp.atomic.write %x = %expr : memref<i32>, i32
 | 
					    omp.atomic.write %x = %expr : memref<i32>, i32
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.capture hint(none) {
 | 
				
			||||||
 | 
					  // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>
 | 
				
			||||||
 | 
					  // 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<i32>
 | 
				
			||||||
 | 
					  // CHECK-NEXT: }
 | 
				
			||||||
 | 
					  omp.atomic.capture hint(none) {
 | 
				
			||||||
 | 
					    omp.atomic.update %x : memref<i32> {
 | 
				
			||||||
 | 
					    ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					      %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					      omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    omp.atomic.read %v = %x : memref<i32>
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.capture hint(uncontended) {
 | 
				
			||||||
 | 
					  // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>
 | 
				
			||||||
 | 
					  // 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<i32>
 | 
				
			||||||
 | 
					  // CHECK-NEXT: }
 | 
				
			||||||
 | 
					  omp.atomic.capture hint(uncontended) {
 | 
				
			||||||
 | 
					    omp.atomic.update %x : memref<i32> {
 | 
				
			||||||
 | 
					    ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					      %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					      omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    omp.atomic.read %v = %x : memref<i32>
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.capture hint(contended) {
 | 
				
			||||||
 | 
					  // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>
 | 
				
			||||||
 | 
					  // 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<i32>
 | 
				
			||||||
 | 
					  // CHECK-NEXT: }
 | 
				
			||||||
 | 
					  omp.atomic.capture hint(contended) {
 | 
				
			||||||
 | 
					    omp.atomic.update %x : memref<i32> {
 | 
				
			||||||
 | 
					    ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					      %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					      omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    omp.atomic.read %v = %x : memref<i32>
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.capture hint(nonspeculative) {
 | 
				
			||||||
 | 
					  // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>
 | 
				
			||||||
 | 
					  // 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<i32>
 | 
				
			||||||
 | 
					  // CHECK-NEXT: }
 | 
				
			||||||
 | 
					  omp.atomic.capture hint(nonspeculative) {
 | 
				
			||||||
 | 
					    omp.atomic.update %x : memref<i32> {
 | 
				
			||||||
 | 
					    ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					      %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					      omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    omp.atomic.read %v = %x : memref<i32>
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.capture hint(speculative) {
 | 
				
			||||||
 | 
					  // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>
 | 
				
			||||||
 | 
					  // 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<i32>
 | 
				
			||||||
 | 
					  // CHECK-NEXT: }
 | 
				
			||||||
 | 
					  omp.atomic.capture hint(speculative) {
 | 
				
			||||||
 | 
					    omp.atomic.update %x : memref<i32> {
 | 
				
			||||||
 | 
					    ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					      %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					      omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    omp.atomic.read %v = %x : memref<i32>
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.capture hint(uncontended, nonspeculative) {
 | 
				
			||||||
 | 
					  // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>
 | 
				
			||||||
 | 
					  // 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<i32>
 | 
				
			||||||
 | 
					  // CHECK-NEXT: }
 | 
				
			||||||
 | 
					  omp.atomic.capture hint(uncontended, nonspeculative) {
 | 
				
			||||||
 | 
					    omp.atomic.update %x : memref<i32> {
 | 
				
			||||||
 | 
					    ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					      %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					      omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    omp.atomic.read %v = %x : memref<i32>
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.capture hint(contended, nonspeculative) {
 | 
				
			||||||
 | 
					  // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>
 | 
				
			||||||
 | 
					  // 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<i32>
 | 
				
			||||||
 | 
					  // CHECK-NEXT: }
 | 
				
			||||||
 | 
					  omp.atomic.capture hint(contended, nonspeculative) {
 | 
				
			||||||
 | 
					    omp.atomic.update %x : memref<i32> {
 | 
				
			||||||
 | 
					    ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					      %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					      omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    omp.atomic.read %v = %x : memref<i32>
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.capture hint(uncontended, speculative) {
 | 
				
			||||||
 | 
					  // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>
 | 
				
			||||||
 | 
					  // 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<i32>
 | 
				
			||||||
 | 
					  // CHECK-NEXT: }
 | 
				
			||||||
 | 
					  omp.atomic.capture hint(uncontended, speculative) {
 | 
				
			||||||
 | 
					    omp.atomic.update %x : memref<i32> {
 | 
				
			||||||
 | 
					    ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					      %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					      omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    omp.atomic.read %v = %x : memref<i32>
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // CHECK: omp.atomic.capture hint(contended, speculative) {
 | 
				
			||||||
 | 
					  // CHECK-NEXT: omp.atomic.update %[[x]] : memref<i32>
 | 
				
			||||||
 | 
					  // 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<i32>
 | 
				
			||||||
 | 
					  // CHECK-NEXT: }
 | 
				
			||||||
 | 
					  omp.atomic.capture hint(contended, speculative) {
 | 
				
			||||||
 | 
					    omp.atomic.update %x : memref<i32> {
 | 
				
			||||||
 | 
					    ^bb0(%xval: i32):
 | 
				
			||||||
 | 
					      %newval = llvm.add %xval, %expr : i32
 | 
				
			||||||
 | 
					      omp.yield(%newval : i32)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    omp.atomic.read %v = %x : memref<i32>
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  return
 | 
					  return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -891,7 +891,15 @@ llvm.func @test_omp_wsloop_dynamic_monotonic_ordered(%lb : i64, %ub : i64, %step
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// -----
 | 
					// -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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
 | 
					// CHECK-LABEL: @omp_critical
 | 
				
			||||||
llvm.func @omp_critical(%x : !llvm.ptr<i32>, %xval : i32) -> () {
 | 
					llvm.func @omp_critical(%x : !llvm.ptr<i32>, %xval : i32) -> () {
 | 
				
			||||||
| 
						 | 
					@ -905,15 +913,95 @@ llvm.func @omp_critical(%x : !llvm.ptr<i32>, %xval : i32) -> () {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  // CHECK: call void @__kmpc_end_critical({{.*}}critical_user_.var{{.*}})
 | 
					  // 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: br label %omp.critical.region
 | 
				
			||||||
  // CHECK: omp.critical.region
 | 
					  // CHECK: omp.critical.region
 | 
				
			||||||
  omp.critical(@mutex) {
 | 
					  omp.critical(@mutex_none) {
 | 
				
			||||||
  // CHECK: store
 | 
					  // CHECK: store
 | 
				
			||||||
    llvm.store %xval, %x : !llvm.ptr<i32>
 | 
					    llvm.store %xval, %x : !llvm.ptr<i32>
 | 
				
			||||||
    omp.terminator
 | 
					    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<i32>
 | 
				
			||||||
 | 
					    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<i32>
 | 
				
			||||||
 | 
					    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<i32>
 | 
				
			||||||
 | 
					    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<i32>
 | 
				
			||||||
 | 
					    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<i32>
 | 
				
			||||||
 | 
					    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<i32>
 | 
				
			||||||
 | 
					    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<i32>
 | 
				
			||||||
 | 
					    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<i32>
 | 
				
			||||||
 | 
					    omp.terminator
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // CHECK: call void @__kmpc_end_critical({{.*}}critical_user_mutex_speculative_contended.var{{.*}})
 | 
				
			||||||
  llvm.return
 | 
					  llvm.return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue