https://github.com/shraiysh updated https://github.com/llvm/llvm-project/pull/68042
>From c7c9e907d897ae667331761d8097ccb7852c5d93 Mon Sep 17 00:00:00 2001 From: Shraiysh Vaishay <shraiysh.vais...@amd.com> Date: Mon, 2 Oct 2023 16:43:13 -0500 Subject: [PATCH 1/3] [mlir][OpenMP] Added translation for `omp.teams` to LLVM IR This patch adds translation from `omp.teams` operation to LLVM IR using OpenMPIRBuilder. The clauses are not handled in this patch. --- .../OpenMP/OpenMPToLLVMIRTranslation.cpp | 21 +++ mlir/test/Target/LLVMIR/openmp-teams.mlir | 136 ++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 mlir/test/Target/LLVMIR/openmp-teams.mlir diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp index 8f7f1963b3e5a4f..b9643be40e13c01 100644 --- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp @@ -661,6 +661,24 @@ convertOmpSingle(omp::SingleOp &singleOp, llvm::IRBuilderBase &builder, return bodyGenStatus; } +// Convert an OpenMP Teams construct to LLVM IR using OpenMPIRBuilder +static LogicalResult convertOmpTeams(omp::TeamsOp op, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation) { + using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy; + LogicalResult bodyGenStatus = success(); + if(op.getNumTeamsLower() || op.getNumTeamsUpper() || op.getIfExpr() || op.getThreadLimit() || !op.getAllocatorsVars().empty() || op.getReductions()) { + return op.emitError("unhandled clauses for translation to LLVM IR"); + } + auto bodyCB = [&](InsertPointTy allocaIP, InsertPointTy codegenIP){ + LLVM::ModuleTranslation::SaveStack<OpenMPAllocaStackFrame> frame(moduleTranslation, allocaIP); + builder.restoreIP(codegenIP); + convertOmpOpRegions(op.getRegion(), "omp.teams.region", builder, moduleTranslation, bodyGenStatus); + }; + + llvm::OpenMPIRBuilder::LocationDescription ompLoc(builder); + builder.restoreIP(moduleTranslation.getOpenMPBuilder()->createTeams(ompLoc, bodyCB)); + return bodyGenStatus; +} + /// Converts an OpenMP task construct into LLVM IR using OpenMPIRBuilder. static LogicalResult convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder, @@ -2406,6 +2424,9 @@ LogicalResult OpenMPDialectLLVMIRTranslationInterface::convertOperation( .Case([&](omp::SingleOp op) { return convertOmpSingle(op, builder, moduleTranslation); }) + .Case([&](omp::TeamsOp op) { + return convertOmpTeams(op, builder, moduleTranslation); + }) .Case([&](omp::TaskOp op) { return convertOmpTaskOp(op, builder, moduleTranslation); }) diff --git a/mlir/test/Target/LLVMIR/openmp-teams.mlir b/mlir/test/Target/LLVMIR/openmp-teams.mlir new file mode 100644 index 000000000000000..c9005fca94a7c20 --- /dev/null +++ b/mlir/test/Target/LLVMIR/openmp-teams.mlir @@ -0,0 +1,136 @@ +// RUN: mlir-translate -mlir-to-llvmir -split-input-file %s | FileCheck %s + +llvm.func @foo() + +// CHECK-LABEL: @omp_teams_simple +// CHECK: call void {{.*}} @__kmpc_fork_teams(ptr @{{.+}}, i32 0, ptr [[wrapperfn:.+]]) +// CHECK: ret void +llvm.func @omp_teams_simple() { + omp.teams { + llvm.call @foo() : () -> () + omp.terminator + } + llvm.return +} + +// CHECK: define internal void @[[outlinedfn:.+]]() +// CHECK: call void @foo() +// CHECK: ret void +// CHECK: define void [[wrapperfn]](ptr %[[global_tid:.+]], ptr %[[bound_tid:.+]]) +// CHECK: call void @[[outlinedfn]] +// CHECK: ret void + +// ----- + +llvm.func @foo(i32) -> () + +// CHECK-LABEL: @omp_teams_shared_simple +// CHECK-SAME: (i32 [[arg0:%.+]]) +// CHECK: [[structArg:%.+]] = alloca { i32 } +// CHECK: br +// CHECK: [[gep:%.+]] = getelementptr { i32 }, ptr [[structArg]], i32 0, i32 0 +// CHECK: store i32 [[arg0]], ptr [[gep]] +// CHECK: call void {{.+}} @__kmpc_fork_teams(ptr @{{.+}}, i32 1, ptr [[wrapperfn:.+]], ptr [[structArg]]) +// CHECK: ret void +llvm.func @omp_teams_shared_simple(%arg0: i32) { + omp.teams { + llvm.call @foo(%arg0) : (i32) -> () + omp.terminator + } + llvm.return +} + +// CHECK: define internal void [[outlinedfn:@.+]](ptr [[structArg:%.+]]) +// CHECK: [[gep:%.+]] = getelementptr { i32 }, ptr [[structArg]], i32 0, i32 0 +// CHECK: [[loadgep:%.+]] = load i32, ptr [[gep]] +// CHECK: call void @foo(i32 [[loadgep]]) +// CHECK: ret void +// CHECK: define void [[wrapperfn]](ptr [[global_tid:.+]], ptr [[bound_tid:.+]], ptr [[structArg:.+]]) +// CHECK: call void [[outlinedfn]](ptr [[structArg]]) +// CHECK: ret void + +// ----- + +llvm.func @my_alloca_fn() -> !llvm.ptr<i32> +llvm.func @foo(i32, f32, !llvm.ptr<i32>, f128, !llvm.ptr<i32>, i32) -> () +llvm.func @bar() + +// CHECK-LABEL: @omp_teams_branching_shared +// CHECK-SAME: (i1 [[condition:%.+]], i32 [[arg0:%.+]], float [[arg1:%.+]], ptr [[arg2:%.+]], fp128 [[arg3:%.+]]) + +// Checking that the allocation for struct argument happens in the alloca block. +// CHECK: [[structArg:%.+]] = alloca { i1, i32, float, ptr, fp128, ptr, i32 } +// CHECK: [[allocated:%.+]] = call ptr @my_alloca_fn() +// CHECK: [[loaded:%.+]] = load i32, ptr [[allocated]] +// CHECK: br label + +// Checking that the shared values are stored properly in the struct arg. +// CHECK: [[conditionPtr:%.+]] = getelementptr {{.+}}, ptr [[structArg]] +// CHECK: store i1 [[condition]], ptr [[conditionPtr]] +// CHECK: [[arg0ptr:%.+]] = getelementptr {{.+}}, ptr [[structArg]], i32 0, i32 1 +// CHECK: store i32 [[arg0]], ptr [[arg0ptr]] +// CHECK: [[arg1ptr:%.+]] = getelementptr {{.+}}, ptr [[structArg]], i32 0, i32 2 +// CHECK: store float [[arg1]], ptr [[arg1ptr]] +// CHECK: [[arg2ptr:%.+]] = getelementptr {{.+}}, ptr [[structArg]], i32 0, i32 3 +// CHECK: store ptr [[arg2]], ptr [[arg2ptr]] +// CHECK: [[arg3ptr:%.+]] = getelementptr {{.+}}, ptr [[structArg]], i32 0, i32 4 +// CHECK: store fp128 [[arg3]], ptr [[arg3ptr]] +// CHECK: [[allocatedPtr:%.+]] = getelementptr {{.+}}, ptr [[structArg]], i32 0, i32 5 +// CHECK: store ptr [[allocated]], ptr [[allocatedPtr]] +// CHECK: [[loadedPtr:%.+]] = getelementptr {{.+}}, ptr [[structArg]], i32 0, i32 6 +// CHECK: store i32 [[loaded]], ptr [[loadedPtr]] + +// Runtime call. +// CHECK: call void {{.+}} @__kmpc_fork_teams(ptr @{{.+}}, i32 1, ptr [[wrapperfn:@.+]], ptr [[structArg]]) +// CHECK: br label +// CHECK: call void @bar() +// CHECK: ret void +llvm.func @omp_teams_branching_shared(%condition: i1, %arg0: i32, %arg1: f32, %arg2: !llvm.ptr<i32>, %arg3: f128) { + %allocated = llvm.call @my_alloca_fn(): () -> !llvm.ptr<i32> + %loaded = llvm.load %allocated : !llvm.ptr<i32> + llvm.br ^codegenBlock +^codegenBlock: + omp.teams { + llvm.cond_br %condition, ^true_block, ^false_block + ^true_block: + llvm.call @foo(%arg0, %arg1, %arg2, %arg3, %allocated, %loaded) : (i32, f32, !llvm.ptr<i32>, f128, !llvm.ptr<i32>, i32) -> () + llvm.br ^exit + ^false_block: + llvm.br ^exit + ^exit: + omp.terminator + } + llvm.call @bar() : () -> () + llvm.return +} + +// Check the outlined function. +// CHECK: define internal void [[outlinedfn:@.+]](ptr [[data:%.+]]) +// CHECK: [[conditionPtr:%.+]] = getelementptr {{.+}}, ptr [[data]] +// CHECK: [[condition:%.+]] = load i1, ptr [[conditionPtr]] +// CHECK: [[arg0ptr:%.+]] = getelementptr {{.+}}, ptr [[data]], i32 0, i32 1 +// CHECK: [[arg0:%.+]] = load i32, ptr [[arg0ptr]] +// CHECK: [[arg1ptr:%.+]] = getelementptr {{.+}}, ptr [[data]], i32 0, i32 2 +// CHECK: [[arg1:%.+]] = load float, ptr [[arg1ptr]] +// CHECK: [[arg2ptr:%.+]] = getelementptr {{.+}}, ptr [[data]], i32 0, i32 3 +// CHECK: [[arg2:%.+]] = load ptr, ptr [[arg2ptr]] +// CHECK: [[arg3ptr:%.+]] = getelementptr {{.+}}, ptr [[data]], i32 0, i32 4 +// CHECK: [[arg3:%.+]] = load fp128, ptr [[arg3ptr]] +// CHECK: [[allocatedPtr:%.+]] = getelementptr {{.+}}, ptr [[data]], i32 0, i32 5 +// CHECK: [[allocated:%.+]] = load ptr, ptr [[allocatedPtr]] +// CHECK: [[loadedPtr:%.+]] = getelementptr {{.+}}, ptr [[data]], i32 0, i32 6 +// CHECK: [[loaded:%.+]] = load i32, ptr [[loadedPtr]] +// CHECK: br label + +// CHECK: br i1 [[condition]], label %[[true:.+]], label %[[false:.+]] +// CHECK: [[false]]: +// CHECK-NEXT: br label +// CHECK: [[true]]: +// CHECK: call void @foo(i32 [[arg0]], float [[arg1]], ptr [[arg2]], fp128 [[arg3]], ptr [[allocated]], i32 [[loaded]]) +// CHECK-NEXT: br label +// CHECK: ret void + +// Check the wrapper function +// CHECK: define void [[wrapperfn]](ptr [[globalTID:%.+]], ptr [[boundTID:%.+]], ptr [[data:%.+]]) +// CHECK: call void [[outlinedfn]](ptr [[data]]) +// CHECK: ret void >From 4618cca227680ed3487961560f9419050890db55 Mon Sep 17 00:00:00 2001 From: Shraiysh Vaishay <shraiysh.vais...@amd.com> Date: Mon, 2 Oct 2023 20:48:45 -0500 Subject: [PATCH 2/3] Formatting --- .../OpenMP/OpenMPToLLVMIRTranslation.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp index b9643be40e13c01..9eefd1be8ad070e 100644 --- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp @@ -662,20 +662,27 @@ convertOmpSingle(omp::SingleOp &singleOp, llvm::IRBuilderBase &builder, } // Convert an OpenMP Teams construct to LLVM IR using OpenMPIRBuilder -static LogicalResult convertOmpTeams(omp::TeamsOp op, llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation) { +static LogicalResult +convertOmpTeams(omp::TeamsOp op, llvm::IRBuilderBase &builder, + LLVM::ModuleTranslation &moduleTranslation) { using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy; LogicalResult bodyGenStatus = success(); - if(op.getNumTeamsLower() || op.getNumTeamsUpper() || op.getIfExpr() || op.getThreadLimit() || !op.getAllocatorsVars().empty() || op.getReductions()) { + if (op.getNumTeamsLower() || op.getNumTeamsUpper() || op.getIfExpr() || + op.getThreadLimit() || !op.getAllocatorsVars().empty() || + op.getReductions()) { return op.emitError("unhandled clauses for translation to LLVM IR"); } - auto bodyCB = [&](InsertPointTy allocaIP, InsertPointTy codegenIP){ - LLVM::ModuleTranslation::SaveStack<OpenMPAllocaStackFrame> frame(moduleTranslation, allocaIP); + auto bodyCB = [&](InsertPointTy allocaIP, InsertPointTy codegenIP) { + LLVM::ModuleTranslation::SaveStack<OpenMPAllocaStackFrame> frame( + moduleTranslation, allocaIP); builder.restoreIP(codegenIP); - convertOmpOpRegions(op.getRegion(), "omp.teams.region", builder, moduleTranslation, bodyGenStatus); + convertOmpOpRegions(op.getRegion(), "omp.teams.region", builder, + moduleTranslation, bodyGenStatus); }; llvm::OpenMPIRBuilder::LocationDescription ompLoc(builder); - builder.restoreIP(moduleTranslation.getOpenMPBuilder()->createTeams(ompLoc, bodyCB)); + builder.restoreIP( + moduleTranslation.getOpenMPBuilder()->createTeams(ompLoc, bodyCB)); return bodyGenStatus; } >From d28e24d4c3bcb476d75c4f9fb906c5a4b294d340 Mon Sep 17 00:00:00 2001 From: Shraiysh Vaishay <shraiysh.vais...@amd.com> Date: Tue, 3 Oct 2023 13:18:48 -0500 Subject: [PATCH 3/3] Addressed comments --- mlir/test/Target/LLVMIR/openmp-teams.mlir | 110 +++++++++++----------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/mlir/test/Target/LLVMIR/openmp-teams.mlir b/mlir/test/Target/LLVMIR/openmp-teams.mlir index c9005fca94a7c20..16457e88774b93a 100644 --- a/mlir/test/Target/LLVMIR/openmp-teams.mlir +++ b/mlir/test/Target/LLVMIR/openmp-teams.mlir @@ -3,7 +3,7 @@ llvm.func @foo() // CHECK-LABEL: @omp_teams_simple -// CHECK: call void {{.*}} @__kmpc_fork_teams(ptr @{{.+}}, i32 0, ptr [[wrapperfn:.+]]) +// CHECK: call void {{.*}} @__kmpc_fork_teams(ptr @{{.+}}, i32 0, ptr [[WRAPPER_FN:.+]]) // CHECK: ret void llvm.func @omp_teams_simple() { omp.teams { @@ -13,11 +13,11 @@ llvm.func @omp_teams_simple() { llvm.return } -// CHECK: define internal void @[[outlinedfn:.+]]() +// CHECK: define internal void @[[OUTLINED_FN:.+]]() // CHECK: call void @foo() // CHECK: ret void -// CHECK: define void [[wrapperfn]](ptr %[[global_tid:.+]], ptr %[[bound_tid:.+]]) -// CHECK: call void @[[outlinedfn]] +// CHECK: define void [[WRAPPER_FN]](ptr {{.+}}, ptr {{.+}}) +// CHECK: call void @[[OUTLINED_FN]] // CHECK: ret void // ----- @@ -25,12 +25,12 @@ llvm.func @omp_teams_simple() { llvm.func @foo(i32) -> () // CHECK-LABEL: @omp_teams_shared_simple -// CHECK-SAME: (i32 [[arg0:%.+]]) -// CHECK: [[structArg:%.+]] = alloca { i32 } +// CHECK-SAME: (i32 [[ARG0:%.+]]) +// CHECK: [[STRUCT_ARG:%.+]] = alloca { i32 } // CHECK: br -// CHECK: [[gep:%.+]] = getelementptr { i32 }, ptr [[structArg]], i32 0, i32 0 -// CHECK: store i32 [[arg0]], ptr [[gep]] -// CHECK: call void {{.+}} @__kmpc_fork_teams(ptr @{{.+}}, i32 1, ptr [[wrapperfn:.+]], ptr [[structArg]]) +// CHECK: [[GEP:%.+]] = getelementptr { i32 }, ptr [[STRUCT_ARG]], i32 0, i32 0 +// CHECK: store i32 [[ARG0]], ptr [[GEP]] +// CHECK: call void {{.+}} @__kmpc_fork_teams(ptr @{{.+}}, i32 1, ptr [[WRAPPER_FN:.+]], ptr [[STRUCT_ARG]]) // CHECK: ret void llvm.func @omp_teams_shared_simple(%arg0: i32) { omp.teams { @@ -40,13 +40,13 @@ llvm.func @omp_teams_shared_simple(%arg0: i32) { llvm.return } -// CHECK: define internal void [[outlinedfn:@.+]](ptr [[structArg:%.+]]) -// CHECK: [[gep:%.+]] = getelementptr { i32 }, ptr [[structArg]], i32 0, i32 0 -// CHECK: [[loadgep:%.+]] = load i32, ptr [[gep]] -// CHECK: call void @foo(i32 [[loadgep]]) +// CHECK: define internal void [[OUTLINED_FN:@.+]](ptr [[STRUCT_ARG:%.+]]) +// CHECK: [[GEP:%.+]] = getelementptr { i32 }, ptr [[STRUCT_ARG]], i32 0, i32 0 +// CHECK: [[LOAD_GEP:%.+]] = load i32, ptr [[GEP]] +// CHECK: call void @foo(i32 [[LOAD_GEP]]) // CHECK: ret void -// CHECK: define void [[wrapperfn]](ptr [[global_tid:.+]], ptr [[bound_tid:.+]], ptr [[structArg:.+]]) -// CHECK: call void [[outlinedfn]](ptr [[structArg]]) +// CHECK: define void [[WRAPPER_FN]](ptr {{.+}}, ptr {{.+}}, ptr [[STRUCT_ARG:.+]]) +// CHECK: call void [[OUTLINED_FN]](ptr [[STRUCT_ARG]]) // CHECK: ret void // ----- @@ -56,32 +56,32 @@ llvm.func @foo(i32, f32, !llvm.ptr<i32>, f128, !llvm.ptr<i32>, i32) -> () llvm.func @bar() // CHECK-LABEL: @omp_teams_branching_shared -// CHECK-SAME: (i1 [[condition:%.+]], i32 [[arg0:%.+]], float [[arg1:%.+]], ptr [[arg2:%.+]], fp128 [[arg3:%.+]]) +// CHECK-SAME: (i1 [[CONDITION:%.+]], i32 [[ARG0:%.+]], float [[ARG1:%.+]], ptr [[ARG2:%.+]], fp128 [[ARG3:%.+]]) // Checking that the allocation for struct argument happens in the alloca block. -// CHECK: [[structArg:%.+]] = alloca { i1, i32, float, ptr, fp128, ptr, i32 } -// CHECK: [[allocated:%.+]] = call ptr @my_alloca_fn() -// CHECK: [[loaded:%.+]] = load i32, ptr [[allocated]] +// CHECK: [[STRUCT_ARG:%.+]] = alloca { i1, i32, float, ptr, fp128, ptr, i32 } +// CHECK: [[ALLOCATED:%.+]] = call ptr @my_alloca_fn() +// CHECK: [[LOADED:%.+]] = load i32, ptr [[ALLOCATED]] // CHECK: br label // Checking that the shared values are stored properly in the struct arg. -// CHECK: [[conditionPtr:%.+]] = getelementptr {{.+}}, ptr [[structArg]] -// CHECK: store i1 [[condition]], ptr [[conditionPtr]] -// CHECK: [[arg0ptr:%.+]] = getelementptr {{.+}}, ptr [[structArg]], i32 0, i32 1 -// CHECK: store i32 [[arg0]], ptr [[arg0ptr]] -// CHECK: [[arg1ptr:%.+]] = getelementptr {{.+}}, ptr [[structArg]], i32 0, i32 2 -// CHECK: store float [[arg1]], ptr [[arg1ptr]] -// CHECK: [[arg2ptr:%.+]] = getelementptr {{.+}}, ptr [[structArg]], i32 0, i32 3 -// CHECK: store ptr [[arg2]], ptr [[arg2ptr]] -// CHECK: [[arg3ptr:%.+]] = getelementptr {{.+}}, ptr [[structArg]], i32 0, i32 4 -// CHECK: store fp128 [[arg3]], ptr [[arg3ptr]] -// CHECK: [[allocatedPtr:%.+]] = getelementptr {{.+}}, ptr [[structArg]], i32 0, i32 5 -// CHECK: store ptr [[allocated]], ptr [[allocatedPtr]] -// CHECK: [[loadedPtr:%.+]] = getelementptr {{.+}}, ptr [[structArg]], i32 0, i32 6 -// CHECK: store i32 [[loaded]], ptr [[loadedPtr]] +// CHECK: [[CONDITION_PTR:%.+]] = getelementptr {{.+}}, ptr [[STRUCT_ARG]] +// CHECK: store i1 [[CONDITION]], ptr [[CONDITION_PTR]] +// CHECK: [[ARG0_PTR:%.+]] = getelementptr {{.+}}, ptr [[STRUCT_ARG]], i32 0, i32 1 +// CHECK: store i32 [[ARG0]], ptr [[ARG0_PTR]] +// CHECK: [[ARG1_PTR:%.+]] = getelementptr {{.+}}, ptr [[STRUCT_ARG]], i32 0, i32 2 +// CHECK: store float [[ARG1]], ptr [[ARG1_PTR]] +// CHECK: [[ARG2_PTR:%.+]] = getelementptr {{.+}}, ptr [[STRUCT_ARG]], i32 0, i32 3 +// CHECK: store ptr [[ARG2]], ptr [[ARG2_PTR]] +// CHECK: [[ARG3_PTR:%.+]] = getelementptr {{.+}}, ptr [[STRUCT_ARG]], i32 0, i32 4 +// CHECK: store fp128 [[ARG3]], ptr [[ARG3_PTR]] +// CHECK: [[ALLOCATED_PTR:%.+]] = getelementptr {{.+}}, ptr [[STRUCT_ARG]], i32 0, i32 5 +// CHECK: store ptr [[ALLOCATED]], ptr [[ALLOCATED_PTR]] +// CHECK: [[LOADED_PTR:%.+]] = getelementptr {{.+}}, ptr [[STRUCT_ARG]], i32 0, i32 6 +// CHECK: store i32 [[LOADED]], ptr [[LOADED_PTR]] // Runtime call. -// CHECK: call void {{.+}} @__kmpc_fork_teams(ptr @{{.+}}, i32 1, ptr [[wrapperfn:@.+]], ptr [[structArg]]) +// CHECK: call void {{.+}} @__kmpc_fork_teams(ptr @{{.+}}, i32 1, ptr [[WRAPPER_FN:@.+]], ptr [[STRUCT_ARG]]) // CHECK: br label // CHECK: call void @bar() // CHECK: ret void @@ -105,32 +105,32 @@ llvm.func @omp_teams_branching_shared(%condition: i1, %arg0: i32, %arg1: f32, %a } // Check the outlined function. -// CHECK: define internal void [[outlinedfn:@.+]](ptr [[data:%.+]]) -// CHECK: [[conditionPtr:%.+]] = getelementptr {{.+}}, ptr [[data]] -// CHECK: [[condition:%.+]] = load i1, ptr [[conditionPtr]] -// CHECK: [[arg0ptr:%.+]] = getelementptr {{.+}}, ptr [[data]], i32 0, i32 1 -// CHECK: [[arg0:%.+]] = load i32, ptr [[arg0ptr]] -// CHECK: [[arg1ptr:%.+]] = getelementptr {{.+}}, ptr [[data]], i32 0, i32 2 -// CHECK: [[arg1:%.+]] = load float, ptr [[arg1ptr]] -// CHECK: [[arg2ptr:%.+]] = getelementptr {{.+}}, ptr [[data]], i32 0, i32 3 -// CHECK: [[arg2:%.+]] = load ptr, ptr [[arg2ptr]] -// CHECK: [[arg3ptr:%.+]] = getelementptr {{.+}}, ptr [[data]], i32 0, i32 4 -// CHECK: [[arg3:%.+]] = load fp128, ptr [[arg3ptr]] -// CHECK: [[allocatedPtr:%.+]] = getelementptr {{.+}}, ptr [[data]], i32 0, i32 5 -// CHECK: [[allocated:%.+]] = load ptr, ptr [[allocatedPtr]] -// CHECK: [[loadedPtr:%.+]] = getelementptr {{.+}}, ptr [[data]], i32 0, i32 6 -// CHECK: [[loaded:%.+]] = load i32, ptr [[loadedPtr]] +// CHECK: define internal void [[OUTLINED_FN:@.+]](ptr [[DATA:%.+]]) +// CHECK: [[CONDITION_PTR:%.+]] = getelementptr {{.+}}, ptr [[DATA]] +// CHECK: [[CONDITION:%.+]] = load i1, ptr [[CONDITION_PTR]] +// CHECK: [[ARG0_PTR:%.+]] = getelementptr {{.+}}, ptr [[DATA]], i32 0, i32 1 +// CHECK: [[ARG0:%.+]] = load i32, ptr [[ARG0_PTR]] +// CHECK: [[ARG1_PTR:%.+]] = getelementptr {{.+}}, ptr [[DATA]], i32 0, i32 2 +// CHECK: [[ARG1:%.+]] = load float, ptr [[ARG1_PTR]] +// CHECK: [[ARG2_PTR:%.+]] = getelementptr {{.+}}, ptr [[DATA]], i32 0, i32 3 +// CHECK: [[ARG2:%.+]] = load ptr, ptr [[ARG2_PTR]] +// CHECK: [[ARG3_PTR:%.+]] = getelementptr {{.+}}, ptr [[DATA]], i32 0, i32 4 +// CHECK: [[ARG3:%.+]] = load fp128, ptr [[ARG3_PTR]] +// CHECK: [[ALLOCATED_PTR:%.+]] = getelementptr {{.+}}, ptr [[DATA]], i32 0, i32 5 +// CHECK: [[ALLOCATED:%.+]] = load ptr, ptr [[ALLOCATED_PTR]] +// CHECK: [[LOADED_PTR:%.+]] = getelementptr {{.+}}, ptr [[DATA]], i32 0, i32 6 +// CHECK: [[LOADED:%.+]] = load i32, ptr [[LOADED_PTR]] // CHECK: br label -// CHECK: br i1 [[condition]], label %[[true:.+]], label %[[false:.+]] -// CHECK: [[false]]: +// CHECK: br i1 [[CONDITION]], label %[[TRUE:.+]], label %[[FALSE:.+]] +// CHECK: [[FALSE]]: // CHECK-NEXT: br label -// CHECK: [[true]]: -// CHECK: call void @foo(i32 [[arg0]], float [[arg1]], ptr [[arg2]], fp128 [[arg3]], ptr [[allocated]], i32 [[loaded]]) +// CHECK: [[TRUE]]: +// CHECK: call void @foo(i32 [[ARG0]], float [[ARG1]], ptr [[ARG2]], fp128 [[ARG3]], ptr [[ALLOCATED]], i32 [[LOADED]]) // CHECK-NEXT: br label // CHECK: ret void // Check the wrapper function -// CHECK: define void [[wrapperfn]](ptr [[globalTID:%.+]], ptr [[boundTID:%.+]], ptr [[data:%.+]]) -// CHECK: call void [[outlinedfn]](ptr [[data]]) +// CHECK: define void [[WRAPPER_FN]](ptr {{.+}}, ptr {{.+}}, ptr [[DATA:%.+]]) +// CHECK: call void [[OUTLINED_FN]](ptr [[DATA]]) // CHECK: ret void _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits