Don't allocate a task context structure if none of the private variables needed it. This was already skipped when there were no private variables at all.
113 lines
6.9 KiB
MLIR
113 lines
6.9 KiB
MLIR
// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
|
|
|
|
// Regression check for a taskloop with private variables but none of the
|
|
// private variables go into the context struct.
|
|
|
|
omp.private {type = private} @_QFtestEi_private_i32 : i32
|
|
omp.private {type = private} @_QFtestEt2_private_i32 : i32
|
|
omp.private {type = private} @_QFtestEt1_private_i32 : i32
|
|
llvm.func @_QPtest() {
|
|
%0 = llvm.mlir.constant(1 : i32) : i32
|
|
%1 = llvm.mlir.constant(20 : i32) : i32
|
|
%2 = llvm.mlir.constant(1 : i64) : i64
|
|
%3 = llvm.alloca %2 x i32 {bindc_name = "t2"} : (i64) -> !llvm.ptr
|
|
%4 = llvm.alloca %2 x i32 {bindc_name = "t1"} : (i64) -> !llvm.ptr
|
|
%5 = llvm.alloca %2 x i32 {bindc_name = "i"} : (i64) -> !llvm.ptr
|
|
omp.taskloop private(@_QFtestEt1_private_i32 %4 -> %arg0, @_QFtestEt2_private_i32 %3 -> %arg1, @_QFtestEi_private_i32 %5 -> %arg2 : !llvm.ptr, !llvm.ptr, !llvm.ptr) {
|
|
omp.loop_nest (%arg3) : i32 = (%0) to (%1) inclusive step (%0) {
|
|
llvm.store %arg3, %arg2 : i32, !llvm.ptr
|
|
omp.yield
|
|
}
|
|
}
|
|
llvm.return
|
|
}
|
|
// CHECK-LABEL: define void @_QPtest() {
|
|
// No task context structure:
|
|
// CHECK: %[[STRUCTARG:.*]] = alloca { i64, i64, i64 }, align 8
|
|
// CHECK: %[[VAL_0:.*]] = alloca i32, i64 1, align 4
|
|
// CHECK: %[[VAL_1:.*]] = alloca i32, i64 1, align 4
|
|
// CHECK: %[[VAL_2:.*]] = alloca i32, i64 1, align 4
|
|
// CHECK: br label %[[VAL_3:.*]]
|
|
// CHECK: entry: ; preds = %[[VAL_4:.*]]
|
|
// CHECK: br label %[[VAL_5:.*]]
|
|
// CHECK: omp.private.init: ; preds = %[[VAL_3]]
|
|
// CHECK: br label %[[VAL_7:.*]]
|
|
// CHECK: omp.private.copy: ; preds = %[[VAL_5]]
|
|
// CHECK: br label %[[VAL_8:.*]]
|
|
// CHECK: omp.taskloop.start: ; preds = %[[VAL_7]]
|
|
// CHECK: br label %[[VAL_9:.*]]
|
|
// CHECK: codeRepl: ; preds = %[[VAL_8]]
|
|
// CHECK: %[[VAL_10:.*]] = getelementptr { i64, i64, i64 }, ptr %[[STRUCTARG]], i32 0, i32 0
|
|
// CHECK: store i64 1, ptr %[[VAL_10]], align 4
|
|
// CHECK: %[[VAL_11:.*]] = getelementptr { i64, i64, i64 }, ptr %[[STRUCTARG]], i32 0, i32 1
|
|
// CHECK: store i64 20, ptr %[[VAL_11]], align 4
|
|
// CHECK: %[[VAL_12:.*]] = getelementptr { i64, i64, i64 }, ptr %[[STRUCTARG]], i32 0, i32 2
|
|
// CHECK: store i64 1, ptr %[[VAL_12]], align 4
|
|
// CHECK: %[[VAL_14:.*]] = call i32 @__kmpc_global_thread_num(ptr @1)
|
|
// CHECK: call void @__kmpc_taskgroup(ptr @1, i32 %[[VAL_14]])
|
|
// CHECK: %[[VAL_15:.*]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 %[[VAL_14]], i32 1, i64 40, i64 24, ptr @_QPtest..omp_par)
|
|
// CHECK: %[[VAL_16:.*]] = load ptr, ptr %[[VAL_15]], align 8
|
|
// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %[[VAL_16]], ptr align 1 %[[STRUCTARG]], i64 24, i1 false)
|
|
// CHECK: %[[VAL_17:.*]] = getelementptr { i64, i64, i64 }, ptr %[[VAL_16]], i32 0, i32 0
|
|
// CHECK: %[[VAL_18:.*]] = getelementptr { i64, i64, i64 }, ptr %[[VAL_16]], i32 0, i32 1
|
|
// CHECK: %[[VAL_19:.*]] = getelementptr { i64, i64, i64 }, ptr %[[VAL_16]], i32 0, i32 2
|
|
// CHECK: %[[VAL_20:.*]] = load i64, ptr %[[VAL_19]], align 4
|
|
// CHECK: call void @__kmpc_taskloop(ptr @1, i32 %[[VAL_14]], ptr %[[VAL_15]], i32 1, ptr %[[VAL_17]], ptr %[[VAL_18]], i64 %[[VAL_20]], i32 1, i32 0, i64 0, ptr null)
|
|
// CHECK: call void @__kmpc_end_taskgroup(ptr @1, i32 %[[VAL_14]])
|
|
// CHECK: br label %[[VAL_21:.*]]
|
|
// CHECK: taskloop.exit: ; preds = %[[VAL_9]]
|
|
// CHECK: ret void
|
|
|
|
// CHECK-LABEL: define internal void @_QPtest..omp_par
|
|
// CHECK: taskloop.alloca:
|
|
// CHECK: %[[VAL_22:.*]] = load ptr, ptr %[[VAL_23:.*]], align 8
|
|
// CHECK: %[[VAL_24:.*]] = getelementptr { i64, i64, i64 }, ptr %[[VAL_22]], i32 0, i32 0
|
|
// CHECK: %[[VAL_25:.*]] = load i64, ptr %[[VAL_24]], align 4
|
|
// CHECK: %[[VAL_26:.*]] = getelementptr { i64, i64, i64 }, ptr %[[VAL_22]], i32 0, i32 1
|
|
// CHECK: %[[VAL_27:.*]] = load i64, ptr %[[VAL_26]], align 4
|
|
// CHECK: %[[VAL_28:.*]] = getelementptr { i64, i64, i64 }, ptr %[[VAL_22]], i32 0, i32 2
|
|
// CHECK: %[[VAL_29:.*]] = load i64, ptr %[[VAL_28]], align 4
|
|
// CHECK: %[[VAL_32:.*]] = alloca i32, align 4
|
|
// CHECK: %[[VAL_33:.*]] = alloca i32, align 4
|
|
// CHECK: %[[VAL_34:.*]] = alloca i32, align 4
|
|
// CHECK: br label %[[VAL_35:.*]]
|
|
// CHECK: taskloop.body: ; preds = %[[VAL_36:.*]]
|
|
// CHECK: br label %[[VAL_37:.*]]
|
|
// CHECK: omp.taskloop.region: ; preds = %[[VAL_35]]
|
|
// CHECK: br label %[[VAL_38:.*]]
|
|
// CHECK: omp_loop.preheader: ; preds = %[[VAL_37]]
|
|
// CHECK: %[[VAL_39:.*]] = sub i64 %[[VAL_27]], %[[VAL_25]]
|
|
// CHECK: %[[VAL_40:.*]] = sdiv i64 %[[VAL_39]], 1
|
|
// CHECK: %[[VAL_41:.*]] = add i64 %[[VAL_40]], 1
|
|
// CHECK: %[[VAL_42:.*]] = trunc i64 %[[VAL_41]] to i32
|
|
// CHECK: %[[VAL_43:.*]] = trunc i64 %[[VAL_25]] to i32
|
|
// CHECK: br label %[[VAL_44:.*]]
|
|
// CHECK: omp_loop.header: ; preds = %[[VAL_45:.*]], %[[VAL_38]]
|
|
// CHECK: %[[VAL_46:.*]] = phi i32 [ 0, %[[VAL_38]] ], [ %[[VAL_47:.*]], %[[VAL_45]] ]
|
|
// CHECK: br label %[[VAL_48:.*]]
|
|
// CHECK: omp_loop.cond: ; preds = %[[VAL_44]]
|
|
// CHECK: %[[VAL_49:.*]] = icmp ult i32 %[[VAL_46]], %[[VAL_42]]
|
|
// CHECK: br i1 %[[VAL_49]], label %[[VAL_50:.*]], label %[[VAL_51:.*]]
|
|
// CHECK: omp_loop.exit: ; preds = %[[VAL_48]]
|
|
// CHECK: br label %[[VAL_52:.*]]
|
|
// CHECK: omp_loop.after: ; preds = %[[VAL_51]]
|
|
// CHECK: br label %[[VAL_53:.*]]
|
|
// CHECK: omp.region.cont: ; preds = %[[VAL_52]]
|
|
// CHECK: br label %[[VAL_54:.*]]
|
|
// CHECK: omp_loop.body: ; preds = %[[VAL_48]]
|
|
// CHECK: %[[VAL_55:.*]] = mul i32 %[[VAL_46]], 1
|
|
// CHECK: %[[VAL_56:.*]] = add i32 %[[VAL_55]], %[[VAL_43]]
|
|
// CHECK: br label %[[VAL_57:.*]]
|
|
// CHECK: omp.loop_nest.region: ; preds = %[[VAL_50]]
|
|
// CHECK: store i32 %[[VAL_56]], ptr %[[VAL_34]], align 4
|
|
// CHECK: br label %[[VAL_58:.*]]
|
|
// CHECK: omp.region.cont3: ; preds = %[[VAL_57]]
|
|
// CHECK: br label %[[VAL_45]]
|
|
// CHECK: omp_loop.inc: ; preds = %[[VAL_58]]
|
|
// CHECK: %[[VAL_47]] = add nuw i32 %[[VAL_46]], 1
|
|
// CHECK: br label %[[VAL_44]]
|
|
// CHECK: taskloop.exit.exitStub: ; preds = %[[VAL_53]]
|
|
// CHECK: ret void
|
|
|
|
// CHECK-NOT: define internal void @omp_taskloop_dup
|