Skip to content

Commit 7a86041

Browse files
[Flang] Add lowering support for depobj in depend clause
From Documentation: depobj: The task dependences are derived from the depend clause specified in the depobj constructs that initialized dependences represented by the depend objects specified in the depend clause as if the depend clauses of the depobj constructs were specified in the current construct. Implementation details: - The variable is of type omp_depend_kind and is used as a locator_list. - Access the base address of obj and compute the clause size, based on the obj value and other clauses count. - Allocate struct.kmp_dep_info with the size computed before. - Now, populate all the depend clauses information into the alloca. the other clauses info is added first in the index, 0, 1, 2, ... and then all the depobj clauses info. - Then, the alloca and size is passed as argument to __kmpc_omp_task_with_deps runtime. - `Stacksave` and `Stackrestore` is used to restore the stack pointer to the state before the depobj operations. Basically removing all the alloca's used. TODO: Requires depobj construct support for checking runtime results. Also, test debobj modify and destroy clauses
1 parent a01e1d4 commit 7a86041

File tree

8 files changed

+158
-37
lines changed

8 files changed

+158
-37
lines changed

flang/lib/Lower/OpenMP/ClauseProcessor.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ static mlir::omp::ClauseTaskDependAttr
139139
genDependKindAttr(lower::AbstractConverter &converter,
140140
const omp::clause::DependenceType kind) {
141141
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
142-
mlir::Location currentLocation = converter.getCurrentLocation();
143142

144143
mlir::omp::ClauseTaskDepend pbKind;
145144
switch (kind) {
@@ -152,15 +151,15 @@ genDependKindAttr(lower::AbstractConverter &converter,
152151
case omp::clause::DependenceType::Inout:
153152
pbKind = mlir::omp::ClauseTaskDepend::taskdependinout;
154153
break;
154+
case omp::clause::DependenceType::Depobj:
155+
pbKind = mlir::omp::ClauseTaskDepend::taskdependdepobj;
156+
break;
155157
case omp::clause::DependenceType::Mutexinoutset:
156158
pbKind = mlir::omp::ClauseTaskDepend::taskdependmutexinoutset;
157159
break;
158160
case omp::clause::DependenceType::Inoutset:
159161
pbKind = mlir::omp::ClauseTaskDepend::taskdependinoutset;
160162
break;
161-
case omp::clause::DependenceType::Depobj:
162-
TODO(currentLocation, "DEPOBJ dependence-type");
163-
break;
164163
case omp::clause::DependenceType::Sink:
165164
case omp::clause::DependenceType::Source:
166165
llvm_unreachable("unhandled parser task dependence type");

flang/test/Lower/OpenMP/Todo/depend-clause-depobj.f90

Lines changed: 0 additions & 10 deletions
This file was deleted.

flang/test/Lower/OpenMP/task.f90

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,18 @@ subroutine task_depend_multi_task()
150150
x = x - 12
151151
!CHECK: omp.terminator
152152
!$omp end task
153-
!CHECK: omp.task depend(taskdependinoutset -> %{{.+}} : !fir.ref<i32>)
153+
!CHECK: omp.task depend(taskdependinoutset -> %{{.+}} : !fir.ref<i32>)
154154
!$omp task depend(inoutset : x)
155155
!CHECK: arith.subi
156156
x = x - 12
157157
!CHECK: omp.terminator
158158
!$omp end task
159+
!CHECK: omp.task depend(taskdependdepobj -> %{{.+}} : !fir.ref<i32>)
160+
!$omp task depend(depobj: obj)
161+
! CHECK: arith.addi
162+
x = x + 73
163+
! CHECK: omp.terminator
164+
!$omp end task
159165
end subroutine task_depend_multi_task
160166

161167
!===============================================================================

llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,10 +1241,12 @@ class OpenMPIRBuilder {
12411241
omp::RTLDependenceKindTy DepKind = omp::RTLDependenceKindTy::DepUnknown;
12421242
Type *DepValueType;
12431243
Value *DepVal;
1244+
bool isTypeDepObj;
12441245
explicit DependData() = default;
12451246
DependData(omp::RTLDependenceKindTy DepKind, Type *DepValueType,
1246-
Value *DepVal)
1247-
: DepKind(DepKind), DepValueType(DepValueType), DepVal(DepVal) {}
1247+
Value *DepVal, bool isTypeDepObj = false)
1248+
: DepKind(DepKind), DepValueType(DepValueType), DepVal(DepVal),
1249+
isTypeDepObj(isTypeDepObj) {}
12481250
};
12491251

12501252
/// Generator for `#omp task`

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2049,19 +2049,61 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createTask(
20492049
Builder.CreateStore(Priority, CmplrData);
20502050
}
20512051

2052-
Value *DepArray = nullptr;
2052+
Value *DepAlloca = nullptr;
2053+
Value *stackSave = nullptr;
2054+
Value *depSize = Builder.getInt32(Dependencies.size());
20532055
if (Dependencies.size()) {
20542056
InsertPointTy OldIP = Builder.saveIP();
20552057
Builder.SetInsertPoint(
20562058
&OldIP.getBlock()->getParent()->getEntryBlock().back());
20572059

20582060
Type *DepArrayTy = ArrayType::get(DependInfo, Dependencies.size());
2059-
DepArray = Builder.CreateAlloca(DepArrayTy, nullptr, ".dep.arr.addr");
2061+
2062+
// Used to keep a count of other dependence type apart from DEPOBJ
2063+
size_t otherDepTypeCount = 0;
2064+
SmallVector<Value *> objsVal;
2065+
// Load all the value of DEPOBJ object from omp_depend_t object
2066+
for (const DependData &dep : Dependencies) {
2067+
if (dep.isTypeDepObj) {
2068+
Value *loadDepVal = Builder.CreateLoad(VoidPtr, dep.DepVal);
2069+
Value *depValGEP =
2070+
Builder.CreateGEP(DependInfo, loadDepVal, Builder.getInt64(-1));
2071+
Value *obj =
2072+
Builder.CreateConstInBoundsGEP2_64(DependInfo, depValGEP, 0, 0);
2073+
Value *objVal = Builder.CreateLoad(Builder.getInt64Ty(), obj);
2074+
objsVal.push_back(objVal);
2075+
} else {
2076+
otherDepTypeCount++;
2077+
}
2078+
}
2079+
2080+
// Add all the values and use it as the size for DependInfo alloca
2081+
if (objsVal.size() > 0) {
2082+
depSize = objsVal[0];
2083+
for (size_t i = 1; i < objsVal.size(); i++)
2084+
depSize = Builder.CreateAdd(depSize, objsVal[i]);
2085+
if (otherDepTypeCount > 0)
2086+
depSize =
2087+
Builder.CreateAdd(depSize, Builder.getInt64(otherDepTypeCount));
2088+
}
2089+
2090+
if (!isa<ConstantInt>(depSize)) {
2091+
// stackSave to save the stack pointer
2092+
if (!stackSave)
2093+
stackSave = Builder.CreateStackSave();
2094+
DepAlloca = Builder.CreateAlloca(DependInfo, depSize, "dep.addr");
2095+
((AllocaInst *)DepAlloca)->setAlignment(Align(16));
2096+
depSize = Builder.CreateTrunc(depSize, Builder.getInt32Ty());
2097+
} else {
2098+
DepAlloca = Builder.CreateAlloca(DepArrayTy, nullptr, ".dep.arr.addr");
2099+
}
20602100

20612101
unsigned P = 0;
20622102
for (const DependData &Dep : Dependencies) {
2103+
if (Dep.isTypeDepObj)
2104+
continue;
20632105
Value *Base =
2064-
Builder.CreateConstInBoundsGEP2_64(DepArrayTy, DepArray, 0, P);
2106+
Builder.CreateGEP(DependInfo, DepAlloca, Builder.getInt64(P));
20652107
// Store the pointer to the variable
20662108
Value *Addr = Builder.CreateStructGEP(
20672109
DependInfo, Base,
@@ -2087,6 +2129,23 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createTask(
20872129
++P;
20882130
}
20892131

2132+
P = 0;
2133+
Value *depAllocaIdx = Builder.getInt64(otherDepTypeCount);
2134+
for (const DependData &dep : Dependencies) {
2135+
if (dep.isTypeDepObj) {
2136+
Value *depAllocaPtr =
2137+
Builder.CreateGEP(DependInfo, DepAlloca, depAllocaIdx);
2138+
Align alignment = Align(8);
2139+
Value *loadDepVal = Builder.CreateLoad(VoidPtr, dep.DepVal);
2140+
Value *memCpySize =
2141+
Builder.CreateMul(Builder.getInt64(24), objsVal[P]);
2142+
Builder.CreateMemCpy(depAllocaPtr, alignment, loadDepVal, alignment,
2143+
memCpySize);
2144+
depAllocaIdx = Builder.CreateAdd(depAllocaIdx, objsVal[P]);
2145+
++P;
2146+
}
2147+
}
2148+
20902149
Builder.restoreIP(OldIP);
20912150
}
20922151

@@ -2124,7 +2183,7 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createTask(
21242183
getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_omp_wait_deps);
21252184
Builder.CreateCall(
21262185
TaskWaitFn,
2127-
{Ident, ThreadID, Builder.getInt32(Dependencies.size()), DepArray,
2186+
{Ident, ThreadID, Builder.getInt32(Dependencies.size()), DepAlloca,
21282187
ConstantInt::get(Builder.getInt32Ty(), 0),
21292188
ConstantPointerNull::get(PointerType::getUnqual(M.getContext()))});
21302189
}
@@ -2146,12 +2205,13 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createTask(
21462205
if (Dependencies.size()) {
21472206
Function *TaskFn =
21482207
getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_omp_task_with_deps);
2149-
Builder.CreateCall(
2150-
TaskFn,
2151-
{Ident, ThreadID, TaskData, Builder.getInt32(Dependencies.size()),
2152-
DepArray, ConstantInt::get(Builder.getInt32Ty(), 0),
2153-
ConstantPointerNull::get(PointerType::getUnqual(M.getContext()))});
2154-
2208+
Builder.CreateCall(TaskFn, {Ident, ThreadID, TaskData, depSize, DepAlloca,
2209+
ConstantInt::get(Builder.getInt32Ty(), 0),
2210+
ConstantPointerNull::get(
2211+
PointerType::getUnqual(M.getContext()))});
2212+
// stackSave is used by depend(depobj: x) clause to save the stack pointer
2213+
if (stackSave)
2214+
Builder.CreateStackRestore(stackSave);
21552215
} else {
21562216
// Emit the @__kmpc_omp_task runtime call to spawn the task
21572217
Function *TaskFn = getOrCreateRuntimeFunctionPtr(OMPRTL___kmpc_omp_task);

mlir/include/mlir/Dialect/OpenMP/OpenMPEnums.td

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,14 @@ def ClauseTaskDependInOut : I32EnumAttrCase<"taskdependinout", 2>;
111111
def ClauseTaskDependMutexInOutSet
112112
: I32EnumAttrCase<"taskdependmutexinoutset", 3>;
113113
def ClauseTaskDependInOutSet : I32EnumAttrCase<"taskdependinoutset", 4>;
114+
def ClauseTaskDependDepObj : I32EnumAttrCase<"taskdependdepobj", 5>;
114115

115116
def ClauseTaskDepend
116-
: OpenMP_I32EnumAttr<
117-
"ClauseTaskDepend", "depend clause in a target or task construct",
118-
[ClauseTaskDependIn, ClauseTaskDependOut, ClauseTaskDependInOut,
119-
ClauseTaskDependMutexInOutSet, ClauseTaskDependInOutSet]>;
117+
: OpenMP_I32EnumAttr<"ClauseTaskDepend",
118+
"depend clause in a target or task construct",
119+
[ClauseTaskDependIn, ClauseTaskDependOut,
120+
ClauseTaskDependInOut, ClauseTaskDependMutexInOutSet,
121+
ClauseTaskDependInOutSet, ClauseTaskDependDepObj]>;
120122

121123
def ClauseTaskDependAttr : OpenMP_EnumAttr<ClauseTaskDepend,
122124
"clause_task_depend"> {

mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1715,6 +1715,7 @@ buildDependData(std::optional<ArrayAttr> dependKinds, OperandRange dependVars,
17151715
return;
17161716
for (auto dep : llvm::zip(dependVars, dependKinds->getValue())) {
17171717
llvm::omp::RTLDependenceKindTy type;
1718+
bool isTypeDepObj = false;
17181719
switch (
17191720
cast<mlir::omp::ClauseTaskDependAttr>(std::get<1>(dep)).getValue()) {
17201721
case mlir::omp::ClauseTaskDepend::taskdependin:
@@ -1733,9 +1734,13 @@ buildDependData(std::optional<ArrayAttr> dependKinds, OperandRange dependVars,
17331734
case mlir::omp::ClauseTaskDepend::taskdependinoutset:
17341735
type = llvm::omp::RTLDependenceKindTy::DepInOutSet;
17351736
break;
1737+
case mlir::omp::ClauseTaskDepend::taskdependdepobj:
1738+
isTypeDepObj = true;
1739+
break;
17361740
};
17371741
llvm::Value *depVal = moduleTranslation.lookupValue(std::get<0>(dep));
1738-
llvm::OpenMPIRBuilder::DependData dd(type, depVal->getType(), depVal);
1742+
llvm::OpenMPIRBuilder::DependData dd(type, depVal->getType(), depVal,
1743+
isTypeDepObj);
17391744
dds.emplace_back(dd);
17401745
}
17411746
}

mlir/test/Target/LLVMIR/openmp-llvm.mlir

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2653,7 +2653,7 @@ llvm.func @omp_task_attrs() -> () attributes {
26532653
// CHECK-LABEL: define void @omp_task_with_deps
26542654
// CHECK-SAME: (ptr %[[zaddr:.+]])
26552655
// CHECK: %[[dep_arr_addr:.+]] = alloca [1 x %struct.kmp_dep_info], align 8
2656-
// CHECK: %[[dep_arr_addr_0:.+]] = getelementptr inbounds [1 x %struct.kmp_dep_info], ptr %[[dep_arr_addr]], i64 0, i64 0
2656+
// CHECK: %[[dep_arr_addr_0:.+]] = getelementptr %struct.kmp_dep_info, ptr %[[dep_arr_addr]], i64 0
26572657
// CHECK: %[[dep_arr_addr_0_val:.+]] = getelementptr inbounds nuw %struct.kmp_dep_info, ptr %[[dep_arr_addr_0]], i32 0, i32 0
26582658
// CHECK: %[[dep_arr_addr_0_val_int:.+]] = ptrtoint ptr %0 to i64
26592659
// CHECK: store i64 %[[dep_arr_addr_0_val_int]], ptr %[[dep_arr_addr_0_val]], align 4
@@ -2664,28 +2664,28 @@ llvm.func @omp_task_attrs() -> () attributes {
26642664
// -----
26652665
// dependence_type: Out
26662666
// CHECK: %[[DEP_ARR_ADDR1:.+]] = alloca [1 x %struct.kmp_dep_info], align 8
2667-
// CHECK: %[[DEP_ARR_ADDR_1:.+]] = getelementptr inbounds [1 x %struct.kmp_dep_info], ptr %[[DEP_ARR_ADDR1]], i64 0, i64 0
2667+
// CHECK: %[[DEP_ARR_ADDR_1:.+]] = getelementptr %struct.kmp_dep_info, ptr %[[DEP_ARR_ADDR1]], i64 0
26682668
// [...]
26692669
// CHECK: %[[DEP_TYPE_1:.+]] = getelementptr inbounds nuw %struct.kmp_dep_info, ptr %[[DEP_ARR_ADDR_1]], i32 0, i32 2
26702670
// CHECK: store i8 3, ptr %[[DEP_TYPE_1]], align 1
26712671
// -----
26722672
// dependence_type: Inout
26732673
// CHECK: %[[DEP_ARR_ADDR2:.+]] = alloca [1 x %struct.kmp_dep_info], align 8
2674-
// CHECK: %[[DEP_ARR_ADDR_2:.+]] = getelementptr inbounds [1 x %struct.kmp_dep_info], ptr %[[DEP_ARR_ADDR2]], i64 0, i64 0
2674+
// CHECK: %[[DEP_ARR_ADDR_2:.+]] = getelementptr %struct.kmp_dep_info, ptr %[[DEP_ARR_ADDR2]], i64 0
26752675
// [...]
26762676
// CHECK: %[[DEP_TYPE_2:.+]] = getelementptr inbounds nuw %struct.kmp_dep_info, ptr %[[DEP_ARR_ADDR_2]], i32 0, i32 2
26772677
// CHECK: store i8 3, ptr %[[DEP_TYPE_2]], align 1
26782678
// -----
26792679
// dependence_type: Mutexinoutset
26802680
// CHECK: %[[DEP_ARR_ADDR3:.+]] = alloca [1 x %struct.kmp_dep_info], align 8
2681-
// CHECK: %[[DEP_ARR_ADDR_3:.+]] = getelementptr inbounds [1 x %struct.kmp_dep_info], ptr %[[DEP_ARR_ADDR3]], i64 0, i64 0
2681+
// CHECK: %[[DEP_ARR_ADDR_3:.+]] = getelementptr %struct.kmp_dep_info, ptr %[[DEP_ARR_ADDR3]], i64 0
26822682
// [...]
26832683
// CHECK: %[[DEP_TYPE_3:.+]] = getelementptr inbounds nuw %struct.kmp_dep_info, ptr %[[DEP_ARR_ADDR_3]], i32 0, i32 2
26842684
// CHECK: store i8 4, ptr %[[DEP_TYPE_3]], align 1
26852685
// -----
26862686
// dependence_type: Inoutset
26872687
// CHECK: %[[DEP_ARR_ADDR4:.+]] = alloca [1 x %struct.kmp_dep_info], align 8
2688-
// CHECK: %[[DEP_ARR_ADDR_4:.+]] = getelementptr inbounds [1 x %struct.kmp_dep_info], ptr %[[DEP_ARR_ADDR4]], i64 0, i64 0
2688+
// CHECK: %[[DEP_ARR_ADDR_4:.+]] = getelementptr %struct.kmp_dep_info, ptr %[[DEP_ARR_ADDR4]], i64 0
26892689
// [...]
26902690
// CHECK: %[[DEP_TYPE_4:.+]] = getelementptr inbounds nuw %struct.kmp_dep_info, ptr %[[DEP_ARR_ADDR_4]], i32 0, i32 2
26912691
// CHECK: store i8 8, ptr %[[DEP_TYPE_4]], align 1
@@ -2734,6 +2734,63 @@ llvm.func @omp_task_with_deps(%zaddr: !llvm.ptr) {
27342734

27352735
// -----
27362736

2737+
// CHECK-LABEL: define void @omp_task_with_deps_02(ptr %0, ptr %1) {
2738+
2739+
// CHECK: %[[obj:.+]] = alloca i64, i64 1, align 8
2740+
// CHECK: %[[obj_load_01:.+]] = load ptr, ptr %[[obj]], align 8
2741+
// CHECK: %[[gep_01:.+]] = getelementptr %struct.kmp_dep_info, ptr %[[obj_load_01]], i64 -1
2742+
// CHECK: %[[gep_02:.+]] = getelementptr inbounds %struct.kmp_dep_info, ptr %[[gep_01]], i64 0, i64 0
2743+
// CHECK: %[[obj_addr:.+]] = load i64, ptr %[[gep_02]], align 4
2744+
2745+
// CHECK: %[[size:.+]] = add i64 %[[obj_addr]], 2
2746+
2747+
// CHECK: %[[stack_ptr:.+]] = call ptr @llvm.stacksave.p0()
2748+
// CHECK: %[[dep_addr:.+]] = alloca %struct.kmp_dep_info, i64 %[[size]], align 16
2749+
// CHECK: %[[dep_size:.+]] = trunc i64 %[[size]] to i32
2750+
2751+
// CHECK: %[[gep_03:.+]] = getelementptr %struct.kmp_dep_info, ptr %[[dep_addr]], i64 0
2752+
// CHECK: %[[gep_04:.+]] = getelementptr inbounds nuw %struct.kmp_dep_info, ptr %[[gep_03]], i32 0, i32 0
2753+
// CHECK: %[[arg_01_int:.+]] = ptrtoint ptr %0 to i64
2754+
// CHECK: store i64 %[[arg_01_int]], ptr %[[gep_04]], align 4
2755+
// CHECK: %[[gep_05:.+]] = getelementptr inbounds nuw %struct.kmp_dep_info, ptr %[[gep_03]], i32 0, i32 1
2756+
// CHECK: store i64 8, ptr %[[gep_05]], align 4
2757+
// CHECK: %[[gep_06:.+]] = getelementptr inbounds nuw %struct.kmp_dep_info, ptr %[[gep_03]], i32 0, i32 2
2758+
// CHECK: store i8 1, ptr %[[gep_06]], align 1
2759+
2760+
// CHECK: %[[gep_07:.+]] = getelementptr %struct.kmp_dep_info, ptr %[[dep_addr]], i64 1
2761+
// CHECK: %[[gep_08:.+]] = getelementptr inbounds nuw %struct.kmp_dep_info, ptr %[[gep_07]], i32 0, i32 0
2762+
// CHECK: %[[arg_02_int:.+]] = ptrtoint ptr %1 to i64
2763+
// CHECK: store i64 %[[arg_02_int]], ptr %[[gep_08]], align 4
2764+
// CHECK: %[[gep_09:.+]] = getelementptr inbounds nuw %struct.kmp_dep_info, ptr %[[gep_07]], i32 0, i32 1
2765+
// CHECK: store i64 8, ptr %[[gep_09]], align 4
2766+
// CHECK: %[[gep_10:.+]] = getelementptr inbounds nuw %struct.kmp_dep_info, ptr %[[gep_07]], i32 0, i32 2
2767+
// CHECK: store i8 3, ptr %[[gep_10]], align 1
2768+
2769+
// CHECK: %[[gep_11:.+]] = getelementptr %struct.kmp_dep_info, ptr %[[dep_addr]], i64 2
2770+
// CHECK: %[[obj_load_02:.+]] = load ptr, ptr %[[obj]], align 8
2771+
// CHECK: %[[obj_size:.+]] = mul i64 24, %[[obj_addr]]
2772+
// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %[[gep_11]], ptr align 8 %[[obj_load_02]], i64 %[[obj_size]], i1 false)
2773+
// CHECK: %[[dep_size_idx:.+]] = add i64 2, %[[obj_addr]]
2774+
2775+
// CHECK: %[[task:.+]] = call i32 @__kmpc_omp_task_with_deps({{.*}}, i32 %[[dep_size]], ptr %[[dep_addr]], i32 0, ptr null)
2776+
// CHECK: call void @llvm.stackrestore.p0(ptr %[[stack_ptr]])
2777+
// CHECK: }
2778+
2779+
2780+
llvm.func @omp_task_with_deps_02(%arg0: !llvm.ptr, %arg1: !llvm.ptr) {
2781+
%c_1 = llvm.mlir.constant(1 : i64) : i64
2782+
%1 = llvm.alloca %c_1 x i64 : (i64) -> !llvm.ptr
2783+
omp.task depend(taskdependin -> %arg0 : !llvm.ptr, taskdependdepobj -> %1 : !llvm.ptr, taskdependout -> %arg1 : !llvm.ptr) {
2784+
%4 = llvm.load %arg0 : !llvm.ptr -> i64
2785+
%5 = llvm.add %4, %c_1 : i64
2786+
llvm.store %5, %arg1 : i64, !llvm.ptr
2787+
omp.terminator
2788+
}
2789+
llvm.return
2790+
}
2791+
2792+
// -----
2793+
27372794
// CHECK-LABEL: define void @omp_task
27382795
// CHECK-SAME: (i32 %[[x:.+]], i32 %[[y:.+]], ptr %[[zaddr:.+]])
27392796
module attributes {llvm.target_triple = "x86_64-unknown-linux-gnu"} {

0 commit comments

Comments
 (0)