1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-globals 2; RUN: opt -S -passes=openmp-opt < %s | FileCheck %s 3target triple = "nvptx64" 4 5%struct.KernelEnvironmentTy = type { %struct.ConfigurationEnvironmentTy, ptr, ptr } 6%struct.ConfigurationEnvironmentTy = type { i8, i8, i8, i32, i32, i32, i32, i32, i32 } 7 8@G = external global i8 9@is_spmd_kernel_environment = local_unnamed_addr constant %struct.KernelEnvironmentTy { %struct.ConfigurationEnvironmentTy { i8 0, i8 0, i8 2, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0 }, ptr null, ptr null } 10@will_be_spmd_kernel_environment = local_unnamed_addr constant %struct.KernelEnvironmentTy { %struct.ConfigurationEnvironmentTy { i8 0, i8 0, i8 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0 }, ptr null, ptr null } 11@none_spmd_kernel_environment = local_unnamed_addr constant %struct.KernelEnvironmentTy { %struct.ConfigurationEnvironmentTy { i8 0, i8 0, i8 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0 }, ptr null, ptr null } 12@will_not_be_spmd_kernel_environment = local_unnamed_addr constant %struct.KernelEnvironmentTy { %struct.ConfigurationEnvironmentTy { i8 0, i8 0, i8 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0 }, ptr null, ptr null } 13 14;. 15; CHECK: @G = external global i8 16; CHECK: @is_spmd_kernel_environment = local_unnamed_addr constant %struct.KernelEnvironmentTy { %struct.ConfigurationEnvironmentTy { i8 0, i8 0, i8 2, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0 }, ptr null, ptr null } 17; CHECK: @will_be_spmd_kernel_environment = local_unnamed_addr constant %struct.KernelEnvironmentTy { %struct.ConfigurationEnvironmentTy { i8 0, i8 0, i8 3, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0 }, ptr null, ptr null } 18; CHECK: @none_spmd_kernel_environment = local_unnamed_addr constant %struct.KernelEnvironmentTy { %struct.ConfigurationEnvironmentTy { i8 0, i8 0, i8 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0 }, ptr null, ptr null } 19; CHECK: @will_not_be_spmd_kernel_environment = local_unnamed_addr constant %struct.KernelEnvironmentTy { %struct.ConfigurationEnvironmentTy { i8 0, i8 0, i8 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0 }, ptr null, ptr null } 20;. 21define weak ptx_kernel void @is_spmd() "kernel" { 22; CHECK-LABEL: define {{[^@]+}}@is_spmd 23; CHECK-SAME: () #[[ATTR0:[0-9]+]] { 24; CHECK-NEXT: [[I:%.*]] = call i32 @__kmpc_target_init(ptr @is_spmd_kernel_environment, ptr null) 25; CHECK-NEXT: call void @is_spmd_helper1() 26; CHECK-NEXT: call void @is_spmd_helper2() 27; CHECK-NEXT: call void @is_mixed_helper() 28; CHECK-NEXT: call void @__kmpc_target_deinit() 29; CHECK-NEXT: ret void 30; 31 %i = call i32 @__kmpc_target_init(ptr @is_spmd_kernel_environment, ptr null) 32 call void @is_spmd_helper1() 33 call void @is_spmd_helper2() 34 call void @is_mixed_helper() 35 call void @__kmpc_target_deinit() 36 ret void 37} 38 39define weak ptx_kernel void @will_be_spmd() "kernel" { 40; CHECK-LABEL: define {{[^@]+}}@will_be_spmd 41; CHECK-SAME: () #[[ATTR0]] { 42; CHECK-NEXT: entry: 43; CHECK-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [0 x ptr], align 8 44; CHECK-NEXT: [[I:%.*]] = call i32 @__kmpc_target_init(ptr @will_be_spmd_kernel_environment, ptr null) 45; CHECK-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[I]], -1 46; CHECK-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[COMMON_RET:%.*]] 47; CHECK: common.ret: 48; CHECK-NEXT: ret void 49; CHECK: user_code.entry: 50; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr null) #[[ATTR3:[0-9]+]] 51; CHECK-NEXT: call void @is_spmd_helper2() 52; CHECK-NEXT: call void @__kmpc_parallel_51(ptr null, i32 [[TMP0]], i32 1, i32 -1, i32 -1, ptr @__omp_outlined__, ptr @__omp_outlined___wrapper, ptr [[CAPTURED_VARS_ADDRS]], i64 0) 53; CHECK-NEXT: call void @__kmpc_target_deinit() 54; CHECK-NEXT: ret void 55; 56entry: 57 %captured_vars_addrs = alloca [0 x ptr], align 8 58 %i = call i32 @__kmpc_target_init(ptr @will_be_spmd_kernel_environment, ptr null) 59 %exec_user_code = icmp eq i32 %i, -1 60 br i1 %exec_user_code, label %user_code.entry, label %common.ret 61 62common.ret: 63 ret void 64 65user_code.entry: 66 %0 = call i32 @__kmpc_global_thread_num(ptr null) 67 call void @is_spmd_helper2() 68 call void @__kmpc_parallel_51(ptr null, i32 %0, i32 1, i32 -1, i32 -1, ptr @__omp_outlined__, ptr @__omp_outlined___wrapper, ptr %captured_vars_addrs, i64 0) 69 call void @__kmpc_target_deinit() 70 ret void 71} 72 73define weak ptx_kernel void @non_spmd() "kernel" { 74; CHECK-LABEL: define {{[^@]+}}@non_spmd 75; CHECK-SAME: () #[[ATTR0]] { 76; CHECK-NEXT: [[I:%.*]] = call i32 @__kmpc_target_init(ptr @none_spmd_kernel_environment, ptr null) 77; CHECK-NEXT: call void @is_generic_helper1() 78; CHECK-NEXT: call void @is_generic_helper2() 79; CHECK-NEXT: call void @is_mixed_helper() 80; CHECK-NEXT: call void @__kmpc_target_deinit() 81; CHECK-NEXT: ret void 82; 83 %i = call i32 @__kmpc_target_init(ptr @none_spmd_kernel_environment, ptr null) 84 call void @is_generic_helper1() 85 call void @is_generic_helper2() 86 call void @is_mixed_helper() 87 call void @__kmpc_target_deinit() 88 ret void 89} 90 91define weak ptx_kernel void @will_not_be_spmd() "kernel" { 92; CHECK-LABEL: define {{[^@]+}}@will_not_be_spmd 93; CHECK-SAME: () #[[ATTR0]] { 94; CHECK-NEXT: [[I:%.*]] = call i32 @__kmpc_target_init(ptr @will_not_be_spmd_kernel_environment, ptr null) 95; CHECK-NEXT: call void @is_generic_helper1() 96; CHECK-NEXT: call void @is_generic_helper2() 97; CHECK-NEXT: call void @is_mixed_helper() 98; CHECK-NEXT: call void @__kmpc_target_deinit() 99; CHECK-NEXT: ret void 100; 101 %i = call i32 @__kmpc_target_init(ptr @will_not_be_spmd_kernel_environment, ptr null) 102 call void @is_generic_helper1() 103 call void @is_generic_helper2() 104 call void @is_mixed_helper() 105 call void @__kmpc_target_deinit() 106 ret void 107} 108 109define internal void @is_spmd_helper1() { 110; CHECK-LABEL: define {{[^@]+}}@is_spmd_helper1() { 111; CHECK-NEXT: store i8 1, ptr @G, align 1 112; CHECK-NEXT: ret void 113; 114 %isSPMD = call i8 @__kmpc_is_spmd_exec_mode() 115 store i8 %isSPMD, ptr @G 116 ret void 117} 118 119define internal void @is_spmd_helper2() { 120; CHECK-LABEL: define {{[^@]+}}@is_spmd_helper2() { 121; CHECK-NEXT: br label [[F:%.*]] 122; CHECK: t: 123; CHECK-NEXT: unreachable 124; CHECK: f: 125; CHECK-NEXT: ret void 126; 127 %isSPMD = call i8 @__kmpc_is_spmd_exec_mode() 128 %c = icmp eq i8 %isSPMD, 0 129 br i1 %c, label %t, label %f 130t: 131 call void @spmd_compatible() 132 ret void 133f: 134 ret void 135} 136 137define internal void @is_generic_helper1() { 138; CHECK-LABEL: define {{[^@]+}}@is_generic_helper1() { 139; CHECK-NEXT: store i8 0, ptr @G, align 1 140; CHECK-NEXT: ret void 141; 142 %isSPMD = call i8 @__kmpc_is_spmd_exec_mode() 143 store i8 %isSPMD, ptr @G 144 ret void 145} 146 147define internal void @is_generic_helper2() { 148; CHECK-LABEL: define {{[^@]+}}@is_generic_helper2() { 149; CHECK-NEXT: [[C:%.*]] = icmp eq i8 0, 0 150; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]] 151; CHECK: t: 152; CHECK-NEXT: call void @foo() 153; CHECK-NEXT: ret void 154; CHECK: f: 155; CHECK-NEXT: call void @bar() 156; CHECK-NEXT: ret void 157; 158 %isSPMD = call i8 @__kmpc_is_spmd_exec_mode() 159 %c = icmp eq i8 %isSPMD, 0 160 br i1 %c, label %t, label %f 161t: 162 call void @foo() 163 ret void 164f: 165 call void @bar() 166 ret void 167} 168 169define internal void @is_mixed_helper() { 170; CHECK-LABEL: define {{[^@]+}}@is_mixed_helper() { 171; CHECK-NEXT: [[ISSPMD:%.*]] = call i8 @__kmpc_is_spmd_exec_mode() 172; CHECK-NEXT: store i8 [[ISSPMD]], ptr @G, align 1 173; CHECK-NEXT: ret void 174; 175 %isSPMD = call i8 @__kmpc_is_spmd_exec_mode() 176 store i8 %isSPMD, ptr @G 177 ret void 178} 179 180define internal void @__omp_outlined__(ptr noalias %.global_tid., ptr noalias %.bound_tid.) { 181; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__ 182; CHECK-SAME: (ptr noalias [[DOTGLOBAL_TID_:%.*]], ptr noalias [[DOTBOUND_TID_:%.*]]) { 183; CHECK-NEXT: entry: 184; CHECK-NEXT: ret void 185; 186entry: 187 ret void 188} 189 190define internal void @__omp_outlined___wrapper(i16 zeroext %0, i32 %1) { 191; CHECK-LABEL: define {{[^@]+}}@__omp_outlined___wrapper 192; CHECK-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) { 193; CHECK-NEXT: entry: 194; CHECK-NEXT: ret void 195; 196entry: 197 ret void 198} 199 200declare void @spmd_compatible() "llvm.assume"="ompx_spmd_amenable" 201declare i8 @__kmpc_is_spmd_exec_mode() 202declare i32 @__kmpc_target_init(ptr, ptr) 203declare void @__kmpc_target_deinit() 204declare void @__kmpc_parallel_51(ptr, i32, i32, i32, i32, ptr, ptr, ptr, i64) 205declare i32 @__kmpc_global_thread_num(ptr) 206declare void @foo() 207declare void @bar() 208 209!llvm.module.flags = !{!0, !1} 210 211!0 = !{i32 7, !"openmp", i32 50} 212!1 = !{i32 7, !"openmp-device", i32 50} 213;. 214; CHECK: attributes #[[ATTR0]] = { "kernel" } 215; CHECK: attributes #[[ATTR1:[0-9]+]] = { "llvm.assume"="ompx_spmd_amenable" } 216; CHECK: attributes #[[ATTR2:[0-9]+]] = { alwaysinline } 217; CHECK: attributes #[[ATTR3]] = { nounwind } 218;. 219; CHECK: [[META0:![0-9]+]] = !{i32 7, !"openmp", i32 50} 220; CHECK: [[META1:![0-9]+]] = !{i32 7, !"openmp-device", i32 50} 221;. 222