[llvm] [SPIRV] Fix OpBuildNDRange (PR #186153)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 18 08:09:33 PDT 2026
https://github.com/idubinov updated https://github.com/llvm/llvm-project/pull/186153
>From 55e06937a650282e550685d0a9b050307b628c56 Mon Sep 17 00:00:00 2001
From: idubinov <igor.dubinov at amd.com>
Date: Wed, 11 Mar 2026 06:32:07 -0500
Subject: [PATCH 1/8] Fix buildNDRange
---
llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp | 150 ++++++++++++++++--------
llvm/lib/Target/SPIRV/SPIRVBuiltins.td | 6 +-
2 files changed, 106 insertions(+), 50 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index f9a9127446013..9a5d14276a321 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -2620,65 +2620,121 @@ static bool generatePredicatedLoadStoreInst(const SPIRV::IncomingCall *Call,
static bool buildNDRange(const SPIRV::IncomingCall *Call,
MachineIRBuilder &MIRBuilder,
SPIRVGlobalRegistry *GR) {
+ // The OpenCL ndrange_*D functions are overloaded and support 1D, 2D, and 3D
+ // variants, accepting 1 to 3 arguments:
+ // (global_work_size)
+ // (global_work_size, local_work_size)
+ // (global_work_offset, global_work_size, local_work_size) -- note the
+ // argument reordering
+ //
+ // SPIR-V's OpBuildNDRange takes all three arguments (GlobalWorkSize,
+ // LocalWorkSize, GlobalWorkOffset). For 1D kernels the values are scalars;
+ // for 2D/3D they are arrays of 2 or 3 elements. Any missing argument is
+ // set to zero.
+
+ unsigned NumArgs = Call->Arguments.size();
+ assert(NumArgs >= 2 && NumArgs <= 4);
+
+ const unsigned ReturnValueArgIdx = 0;
+ const unsigned IncorrectArgIdx = 5;
+ const unsigned GlobalWorkSizeArgIdx = NumArgs < 4 ? 1 : 2;
+ const unsigned LocalWorkSizeArgIdx =
+ NumArgs == 2 ? IncorrectArgIdx : (NumArgs == 3 ? 2 : 3);
+ const unsigned GlobalWorkOffsetArgIdx = NumArgs < 4 ? IncorrectArgIdx : 1;
+
+ // Return type is the nd_range struct pointed to by the first argument.
MachineRegisterInfo *MRI = MIRBuilder.getMRI();
- SPIRVTypeInst PtrType = GR->getSPIRVTypeForVReg(Call->Arguments[0]);
+ SPIRVTypeInst PtrType =
+ GR->getSPIRVTypeForVReg(Call->Arguments[ReturnValueArgIdx]);
assert(PtrType->getOpcode() == SPIRV::OpTypePointer &&
- PtrType->getOperand(2).isReg());
- Register TypeReg = PtrType->getOperand(2).getReg();
- SPIRVTypeInst StructType = GR->getSPIRVTypeForVReg(TypeReg);
+ PtrType->getOperand(2 /*Pointee*/).isReg());
+ Register ReturnTypeReg = PtrType->getOperand(2).getReg();
+ SPIRVTypeInst ReturnStructType = GR->getSPIRVTypeForVReg(ReturnTypeReg);
MachineFunction &MF = MIRBuilder.getMF();
Register TmpReg = MRI->createVirtualRegister(&SPIRV::iIDRegClass);
- GR->assignSPIRVTypeToVReg(StructType, TmpReg, MF);
- // Skip the first arg, it's the destination pointer. OpBuildNDRange takes
- // three other arguments, so pass zero constant on absence.
- unsigned NumArgs = Call->Arguments.size();
- assert(NumArgs >= 2);
- Register GlobalWorkSize = Call->Arguments[NumArgs < 4 ? 1 : 2];
- Register LocalWorkSize =
- NumArgs == 2 ? Register(0) : Call->Arguments[NumArgs < 4 ? 2 : 3];
- Register GlobalWorkOffset = NumArgs <= 3 ? Register(0) : Call->Arguments[1];
- if (NumArgs < 4) {
- Register Const;
- SPIRVTypeInst SpvTy = GR->getSPIRVTypeForVReg(GlobalWorkSize);
- if (SpvTy->getOpcode() == SPIRV::OpTypePointer) {
- MachineInstr *DefInstr = MRI->getUniqueVRegDef(GlobalWorkSize);
- assert(DefInstr && isSpvIntrinsic(*DefInstr, Intrinsic::spv_gep) &&
- DefInstr->getOperand(3).isReg());
- Register GWSPtr = DefInstr->getOperand(3).getReg();
- // TODO: Maybe simplify generation of the type of the fields.
- unsigned Size = Call->Builtin->Name == "ndrange_3D" ? 3 : 2;
- unsigned BitWidth = GR->getPointerSize() == 64 ? 64 : 32;
- Type *BaseTy = IntegerType::get(MF.getFunction().getContext(), BitWidth);
- Type *FieldTy = ArrayType::get(BaseTy, Size);
- SPIRVTypeInst SpvFieldTy = GR->getOrCreateSPIRVType(
- FieldTy, MIRBuilder, SPIRV::AccessQualifier::ReadWrite, true);
- GlobalWorkSize = MRI->createVirtualRegister(&SPIRV::iIDRegClass);
- GR->assignSPIRVTypeToVReg(SpvFieldTy, GlobalWorkSize, MF);
- MIRBuilder.buildInstr(SPIRV::OpLoad)
- .addDef(GlobalWorkSize)
- .addUse(GR->getSPIRVTypeID(SpvFieldTy))
- .addUse(GWSPtr);
- const SPIRVSubtarget &ST =
- cast<SPIRVSubtarget>(MIRBuilder.getMF().getSubtarget());
- Const = GR->getOrCreateConstIntArray(0, Size, *MIRBuilder.getInsertPt(),
- SpvFieldTy, *ST.getInstrInfo());
- } else {
- Const = GR->buildConstantInt(0, MIRBuilder, SpvTy, true);
+ GR->assignSPIRVTypeToVReg(ReturnStructType, TmpReg, MF);
+
+ // Each nd_range field is an array of <Dimension> integers matching the
+ // address model width (32 or 64 bits).
+ const unsigned AddressModelBits = GR->getPointerSize();
+ assert(AddressModelBits == 64 || AddressModelBits == 32);
+
+
+ // The dimension is encoded in the function name as "ndrange_XD" where X is
+ // 1, 2, or 3.
+ unsigned Dimension = atoi(Call->Builtin->Name.substr(8, 1).data());
+ assert(Dimension <= 3 && Dimension >= 1);
+
+
+ // Get work size type; When fewer than 4 arguments are provided, build a zero constant for the
+ // missing one.
+ SPIRVTypeInst SpvFieldTy;
+ Register ConstZero;
+ if (Dimension == 1) {
+ SpvFieldTy =
+ GR->getSPIRVTypeForVReg(Call->Arguments[GlobalWorkSizeArgIdx]);
+ assert(SpvFieldTy && SpvFieldTy->getOpcode() == SPIRV::OpTypeInt &&
+ "Expected scalar integer type");
+
+ if (NumArgs < 4)
+ ConstZero = GR->buildConstantInt(0, MIRBuilder, SpvFieldTy, true);
+ } else {
+ Type *BaseTy =
+ IntegerType::get(MF.getFunction().getContext(), AddressModelBits);
+ Type *FieldTy = ArrayType::get(BaseTy, Dimension);
+ SpvFieldTy = GR->getOrCreateSPIRVType(
+ FieldTy, MIRBuilder, SPIRV::AccessQualifier::ReadOnly, true);
+
+ if (NumArgs < 4) {
+ auto InsertIt = MIRBuilder.getInsertPt();
+ MachineBasicBlock &MBB = MIRBuilder.getMBB();
+ MachineInstr &InsertMI = (InsertIt != MBB.end()) ? *InsertIt : MBB.back();
+ const SPIRVSubtarget &ST = cast<SPIRVSubtarget>(MF.getSubtarget());
+ ConstZero = GR->getOrCreateConstIntArray(0, Dimension, InsertMI,
+ SpvFieldTy, *ST.getInstrInfo());
}
- if (!LocalWorkSize.isValid())
- LocalWorkSize = Const;
- if (!GlobalWorkOffset.isValid())
- GlobalWorkOffset = Const;
}
- assert(LocalWorkSize.isValid() && GlobalWorkOffset.isValid());
+
+
+ Register GlobalWorkSize;
+ Register LocalWorkSize;
+ Register GlobalWorkOffset;
+
+ auto LoadRegisterData = [&](Register &Reg, unsigned Idx) {
+ Reg = (Idx == IncorrectArgIdx) ? ConstZero : Call->Arguments[Idx];
+
+ if (GR->getSPIRVTypeForVReg(Reg) == SpvFieldTy) {
+ // Already has the correct type
+ return;
+ }
+
+ assert(GR->getSPIRVTypeForVReg(Reg)->getOpcode() == SPIRV::OpTypePointer &&
+ "Only pointer types are supported for loading values");
+
+ Register Ptr = Reg;
+
+ Reg = MRI->createVirtualRegister(&SPIRV::iIDRegClass);
+ GR->assignSPIRVTypeToVReg(SpvFieldTy, Reg, MF);
+
+ MIRBuilder.buildInstr(SPIRV::OpLoad)
+ .addDef(Reg)
+ .addUse(GR->getSPIRVTypeID(SpvFieldTy))
+ .addUse(Ptr);
+ return;
+ };
+
+ LoadRegisterData(GlobalWorkSize, GlobalWorkSizeArgIdx);
+ LoadRegisterData(LocalWorkSize, LocalWorkSizeArgIdx);
+ LoadRegisterData(GlobalWorkOffset, GlobalWorkOffsetArgIdx);
+
MIRBuilder.buildInstr(SPIRV::OpBuildNDRange)
.addDef(TmpReg)
- .addUse(TypeReg)
+ .addUse(ReturnTypeReg)
.addUse(GlobalWorkSize)
.addUse(LocalWorkSize)
.addUse(GlobalWorkOffset);
return MIRBuilder.buildInstr(SPIRV::OpStore)
- .addUse(Call->Arguments[0])
+ .addUse(Call->Arguments[ReturnValueArgIdx])
.addUse(TmpReg);
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.td b/llvm/lib/Target/SPIRV/SPIRVBuiltins.td
index eb1b6c3185e7d..3820713db3e4a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.td
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.td
@@ -702,9 +702,9 @@ defm : DemangledNativeBuiltin<"capture_event_profiling_info", OpenCL_std, Enqueu
defm : DemangledNativeBuiltin<"__spirv_CaptureEventProfilingInfo", OpenCL_std, Enqueue, 3, 3, OpCaptureEventProfilingInfo>;
defm : DemangledNativeBuiltin<"get_default_queue", OpenCL_std, Enqueue, 0, 0, OpGetDefaultQueue>;
defm : DemangledNativeBuiltin<"__spirv_GetDefaultQueue", OpenCL_std, Enqueue, 0, 0, OpGetDefaultQueue>;
-defm : DemangledNativeBuiltin<"ndrange_1D", OpenCL_std, Enqueue, 1, 3, OpBuildNDRange>;
-defm : DemangledNativeBuiltin<"ndrange_2D", OpenCL_std, Enqueue, 1, 3, OpBuildNDRange>;
-defm : DemangledNativeBuiltin<"ndrange_3D", OpenCL_std, Enqueue, 1, 3, OpBuildNDRange>;
+defm : DemangledNativeBuiltin<"ndrange_1D", OpenCL_std, Enqueue, 2, 4, OpBuildNDRange>;
+defm : DemangledNativeBuiltin<"ndrange_2D", OpenCL_std, Enqueue, 2, 4, OpBuildNDRange>;
+defm : DemangledNativeBuiltin<"ndrange_3D", OpenCL_std, Enqueue, 2, 4, OpBuildNDRange>;
// Spec constant builtin records:
defm : DemangledNativeBuiltin<"__spirv_SpecConstant", OpenCL_std, SpecConstant, 2, 2, OpSpecConstant>;
>From a5aa2470633d768516f6bf99172b7935a76a9452 Mon Sep 17 00:00:00 2001
From: idubinov <igor.dubinov at amd.com>
Date: Thu, 12 Mar 2026 10:20:07 -0500
Subject: [PATCH 2/8] tests
---
.../CodeGen/SPIRV/transcoding/BuildNDRange.ll | 634 +++++++++++++++++-
.../SPIRV/transcoding/BuildNDRange_2.ll | 83 ---
2 files changed, 623 insertions(+), 94 deletions(-)
delete mode 100644 llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange_2.ll
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange.ll b/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange.ll
index 9258a3f23bf79..fac6aebfaa500 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange.ll
@@ -1,17 +1,629 @@
-; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
-; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+;; Test that checks all variants of ndrange and what ndrange_1D, ndrange_2D and ndrange_3D can coexist in the same module
+;;
+;; bash$ cat BuildNDRange.cl
+;; void test_ndrange_2D3D() {
+;; size_t GS1 = 1;
+;; size_t LS1 = 2;
+;; size_t WO1 = 3;
+;; ndrange_1D(GS1);
+;; ndrange_1D(GS1, LS1);
+;; ndrange_1D(WO1, GS1, LS1);
+;; ndrange_1D(GS1, GS1);
+;; ndrange_1D(GS1, GS1, GS1);
+;; size_t GS2[2] = {1, 1};
+;; size_t LS2[2] = {2, 2};
+;; size_t WO2[2] = {3, 3};
+;; ndrange_2D(GS2);
+;; ndrange_2D(GS2, LS2);
+;; ndrange_2D(WO2, GS2, LS2);
+;; ndrange_2D(GS2, GS2);
+;; ndrange_2D(GS2, GS2, GS2);
+;; size_t GS3[3] = {1, 1, 1};
+;; size_t LS3[3] = {1, 2, 1};
+;; size_t WO3[3] = {1, 3, 1};
+;; ndrange_3D(GS3);
+;; ndrange_2D(GS3, LS3);
+;; ndrange_2D(WO3, GS3, LS3);
+;; ndrange_2D(GS3, GS3);
+;; ndrange_2D(GS3, GS3, GS3);
+;; const size_t GS1c = 1;
+;; const size_t LS1c = 2;
+;; const size_t WO1c = 3;
+;; ndrange_1D(GS1c);
+;; ndrange_1D(GS1c, LS1c);
+;; ndrange_1D(WO1c, GS1c, LS1c);
+;; ndrange_1D(GS1c, GS1c);
+;; ndrange_1D(GS1c, GS1c, GS1c);
+;; const size_t GS2c[2] = {1, 1};
+;; const size_t LS2c[2] = {1, 2};
+;; const size_t WO2c[2] = {1, 3};
+;; ndrange_2D(GS2c);
+;; ndrange_2D(GS2c, LS2c);
+;; ndrange_2D(WO2c, GS2c, LS2c);
+;; ndrange_2D(GS2c, GS2c);
+;; ndrange_2D(GS2c, GS2c, GS2c);
+;; const size_t GS3c[3] = {1, 1, 1};
+;; const size_t LS3c[3] = {1, 1, 2};
+;; const size_t WO3c[3] = {1, 1, 3};
+;; ndrange_3D(GS3c);
+;; ndrange_2D(GS3c, LS3c);
+;; ndrange_2D(WO3c, GS3c, LS3c);
+;; ndrange_2D(GS3c, GS3c);
+;; ndrange_2D(GS3c, GS3c, GS3c);
+;; }
+;; bash$ clang -cc1 -cl-std=CL2.0 -triple spirv64-unknown-unknown -emit-llvm -finclude-default-header -cl-single-precision-constant BuildNDRange.cl -o BuildNDRange.ll
-; CHECK-SPIRV-DAG: %[[#]] = OpBuildNDRange %[[#]] %[[#GWS:]] %[[#LWS:]] %[[#GWO:]]
-; CHECK-SPIRV-DAG: %[[#GWS]] = OpConstant %[[#]] 123
-; CHECK-SPIRV-DAG: %[[#LWS]] = OpConstant %[[#]] 456
-; CHECK-SPIRV-DAG: %[[#GWO]] = OpConstantNull %[[#]]
-%struct.ndrange_t = type { i32, [3 x i32], [3 x i32], [3 x i32] }
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-define spir_kernel void @test() {
- %ndrange = alloca %struct.ndrange_t, align 4
- call spir_func void @_Z10ndrange_1Djj(ptr sret(ptr) %ndrange, i32 123, i32 456)
+%struct.ndrange_t = type { i32, [3 x i64], [3 x i64], [3 x i64] }
+
+ at __const.test_ndrange_2D3D.GS2 = private unnamed_addr addrspace(2) constant [2 x i64] [i64 1, i64 1], align 8
+ at __const.test_ndrange_2D3D.LS2 = private unnamed_addr addrspace(2) constant [2 x i64] [i64 2, i64 2], align 8
+ at __const.test_ndrange_2D3D.WO2 = private unnamed_addr addrspace(2) constant [2 x i64] [i64 3, i64 3], align 8
+ at __const.test_ndrange_2D3D.GS3 = private unnamed_addr addrspace(2) constant [3 x i64] [i64 1, i64 1, i64 1], align 8
+ at __const.test_ndrange_2D3D.LS3 = private unnamed_addr addrspace(2) constant [3 x i64] [i64 1, i64 2, i64 1], align 8
+ at __const.test_ndrange_2D3D.WO3 = private unnamed_addr addrspace(2) constant [3 x i64] [i64 1, i64 3, i64 1], align 8
+ at __const.test_ndrange_2D3D.GS2c = private unnamed_addr addrspace(2) constant [2 x i64] [i64 1, i64 1], align 8
+ at __const.test_ndrange_2D3D.LS2c = private unnamed_addr addrspace(2) constant [2 x i64] [i64 1, i64 2], align 8
+ at __const.test_ndrange_2D3D.WO2c = private unnamed_addr addrspace(2) constant [2 x i64] [i64 1, i64 3], align 8
+ at __const.test_ndrange_2D3D.GS3c = private unnamed_addr addrspace(2) constant [3 x i64] [i64 1, i64 1, i64 1], align 8
+ at __const.test_ndrange_2D3D.LS3c = private unnamed_addr addrspace(2) constant [3 x i64] [i64 1, i64 1, i64 2], align 8
+ at __const.test_ndrange_2D3D.WO3c = private unnamed_addr addrspace(2) constant [3 x i64] [i64 1, i64 1, i64 3], align 8
+
+define spir_func void @test_ndrange_2D3D() local_unnamed_addr #0 {
+; CHECK-LABEL: test_ndrange_2D3D
+; CHECK: %50 = OpFunction %3 None %4 ; -- Begin function test_ndrange_2D3D
+; CHECK-NEXT: %2 = OpLabel
+; CHECK-NEXT: %51 = OpVariable %10 Function
+; CHECK-NEXT: %52 = OpVariable %10 Function
+; CHECK-NEXT: %53 = OpVariable %10 Function
+; CHECK-NEXT: %54 = OpVariable %10 Function
+; CHECK-NEXT: %55 = OpVariable %10 Function
+; CHECK-NEXT: %56 = OpVariable %13 Function
+; CHECK-NEXT: %57 = OpVariable %13 Function
+; CHECK-NEXT: %58 = OpVariable %13 Function
+; CHECK-NEXT: %59 = OpVariable %10 Function
+; CHECK-NEXT: %60 = OpVariable %10 Function
+; CHECK-NEXT: %61 = OpVariable %10 Function
+; CHECK-NEXT: %62 = OpVariable %10 Function
+; CHECK-NEXT: %63 = OpVariable %10 Function
+; CHECK-NEXT: %64 = OpVariable %16 Function
+; CHECK-NEXT: %65 = OpVariable %16 Function
+; CHECK-NEXT: %66 = OpVariable %16 Function
+; CHECK-NEXT: %67 = OpVariable %10 Function
+; CHECK-NEXT: %68 = OpVariable %10 Function
+; CHECK-NEXT: %69 = OpVariable %10 Function
+; CHECK-NEXT: %70 = OpVariable %10 Function
+; CHECK-NEXT: %71 = OpVariable %10 Function
+; CHECK-NEXT: %72 = OpVariable %10 Function
+; CHECK-NEXT: %73 = OpVariable %10 Function
+; CHECK-NEXT: %74 = OpVariable %10 Function
+; CHECK-NEXT: %75 = OpVariable %10 Function
+; CHECK-NEXT: %76 = OpVariable %10 Function
+; CHECK-NEXT: %77 = OpVariable %13 Function
+; CHECK-NEXT: %78 = OpVariable %13 Function
+; CHECK-NEXT: %79 = OpVariable %13 Function
+; CHECK-NEXT: %80 = OpVariable %10 Function
+; CHECK-NEXT: %81 = OpVariable %10 Function
+; CHECK-NEXT: %82 = OpVariable %10 Function
+; CHECK-NEXT: %83 = OpVariable %10 Function
+; CHECK-NEXT: %84 = OpVariable %10 Function
+; CHECK-NEXT: %85 = OpVariable %16 Function
+; CHECK-NEXT: %86 = OpVariable %16 Function
+; CHECK-NEXT: %87 = OpVariable %16 Function
+; CHECK-NEXT: %88 = OpVariable %10 Function
+; CHECK-NEXT: %89 = OpVariable %10 Function
+; CHECK-NEXT: %90 = OpVariable %10 Function
+; CHECK-NEXT: %91 = OpVariable %10 Function
+; CHECK-NEXT: %92 = OpVariable %10 Function
+; CHECK-NEXT: %93 = OpBitcast %27 %51
+; CHECK-NEXT: OpLifetimeStart %93 80
+; CHECK-NEXT: %94 = OpBuildNDRange %9 %24 %25 %25
+; CHECK-NEXT: OpStore %51 %94
+; CHECK-NEXT: %95 = OpBitcast %27 %51
+; CHECK-NEXT: OpLifetimeStop %95 80
+; CHECK-NEXT: %96 = OpBitcast %27 %52
+; CHECK-NEXT: OpLifetimeStart %96 80
+; CHECK-NEXT: %97 = OpBuildNDRange %9 %24 %23 %25
+; CHECK-NEXT: OpStore %52 %97
+; CHECK-NEXT: %98 = OpBitcast %27 %52
+; CHECK-NEXT: OpLifetimeStop %98 80
+; CHECK-NEXT: %99 = OpBitcast %27 %53
+; CHECK-NEXT: OpLifetimeStart %99 80
+; CHECK-NEXT: %100 = OpBuildNDRange %9 %24 %23 %22
+; CHECK-NEXT: OpStore %53 %100
+; CHECK-NEXT: %101 = OpBitcast %27 %53
+; CHECK-NEXT: OpLifetimeStop %101 80
+; CHECK-NEXT: %102 = OpBitcast %27 %54
+; CHECK-NEXT: OpLifetimeStart %102 80
+; CHECK-NEXT: %103 = OpBuildNDRange %9 %24 %24 %25
+; CHECK-NEXT: OpStore %54 %103
+; CHECK-NEXT: %104 = OpBitcast %27 %54
+; CHECK-NEXT: OpLifetimeStop %104 80
+; CHECK-NEXT: %105 = OpBitcast %27 %55
+; CHECK-NEXT: OpLifetimeStart %105 80
+; CHECK-NEXT: %106 = OpBuildNDRange %9 %24 %24 %24
+; CHECK-NEXT: OpStore %55 %106
+; CHECK-NEXT: %107 = OpBitcast %27 %55
+; CHECK-NEXT: OpLifetimeStop %107 80
+; CHECK-NEXT: %108 = OpBitcast %27 %56
+; CHECK-NEXT: OpLifetimeStart %108 16
+; CHECK-NEXT: OpCopyMemorySized %56 %29 %21 Aligned 8
+; CHECK-NEXT: %109 = OpBitcast %27 %57
+; CHECK-NEXT: OpLifetimeStart %109 16
+; CHECK-NEXT: OpCopyMemorySized %57 %31 %21 Aligned 8
+; CHECK-NEXT: %110 = OpBitcast %27 %58
+; CHECK-NEXT: OpLifetimeStart %110 16
+; CHECK-NEXT: OpCopyMemorySized %58 %33 %21 Aligned 8
+; CHECK-NEXT: %111 = OpBitcast %27 %59
+; CHECK-NEXT: OpLifetimeStart %111 80
+; CHECK-NEXT: %112 = OpLoad %12 %56
+; CHECK-NEXT: %113 = OpBuildNDRange %9 %112 %14 %14
+; CHECK-NEXT: OpStore %59 %113
+; CHECK-NEXT: %114 = OpBitcast %27 %59
+; CHECK-NEXT: OpLifetimeStop %114 80
+; CHECK-NEXT: %115 = OpBitcast %27 %60
+; CHECK-NEXT: OpLifetimeStart %115 80
+; CHECK-NEXT: %116 = OpBitcast %15 %56
+; CHECK-NEXT: %117 = OpBitcast %13 %116
+; CHECK-NEXT: %118 = OpLoad %12 %117
+; CHECK-NEXT: %119 = OpLoad %12 %57
+; CHECK-NEXT: %120 = OpBuildNDRange %9 %118 %119 %14
+; CHECK-NEXT: OpStore %60 %120
+; CHECK-NEXT: %121 = OpBitcast %27 %60
+; CHECK-NEXT: OpLifetimeStop %121 80
+; CHECK-NEXT: %122 = OpBitcast %27 %61
+; CHECK-NEXT: OpLifetimeStart %122 80
+; CHECK-NEXT: %123 = OpBitcast %15 %58
+; CHECK-NEXT: %124 = OpBitcast %13 %116
+; CHECK-NEXT: %125 = OpLoad %12 %124
+; CHECK-NEXT: %126 = OpLoad %12 %57
+; CHECK-NEXT: %127 = OpBitcast %13 %123
+; CHECK-NEXT: %128 = OpLoad %12 %127
+; CHECK-NEXT: %129 = OpBuildNDRange %9 %125 %126 %128
+; CHECK-NEXT: OpStore %61 %129
+; CHECK-NEXT: %130 = OpBitcast %27 %61
+; CHECK-NEXT: OpLifetimeStop %130 80
+; CHECK-NEXT: %131 = OpBitcast %27 %62
+; CHECK-NEXT: OpLifetimeStart %131 80
+; CHECK-NEXT: %132 = OpBitcast %13 %116
+; CHECK-NEXT: %133 = OpLoad %12 %132
+; CHECK-NEXT: %134 = OpLoad %12 %56
+; CHECK-NEXT: %135 = OpBuildNDRange %9 %133 %134 %14
+; CHECK-NEXT: OpStore %62 %135
+; CHECK-NEXT: %136 = OpBitcast %27 %62
+; CHECK-NEXT: OpLifetimeStop %136 80
+; CHECK-NEXT: %137 = OpBitcast %27 %63
+; CHECK-NEXT: OpLifetimeStart %137 80
+; CHECK-NEXT: %138 = OpBitcast %13 %116
+; CHECK-NEXT: %139 = OpLoad %12 %138
+; CHECK-NEXT: %140 = OpLoad %12 %56
+; CHECK-NEXT: %141 = OpBitcast %13 %116
+; CHECK-NEXT: %142 = OpLoad %12 %141
+; CHECK-NEXT: %143 = OpBuildNDRange %9 %139 %140 %142
+; CHECK-NEXT: OpStore %63 %143
+; CHECK-NEXT: %144 = OpBitcast %27 %63
+; CHECK-NEXT: OpLifetimeStop %144 80
+; CHECK-NEXT: %145 = OpBitcast %27 %64
+; CHECK-NEXT: OpLifetimeStart %145 24
+; CHECK-NEXT: OpCopyMemorySized %64 %35 %20 Aligned 8
+; CHECK-NEXT: %146 = OpBitcast %27 %65
+; CHECK-NEXT: OpLifetimeStart %146 24
+; CHECK-NEXT: OpCopyMemorySized %65 %37 %20 Aligned 8
+; CHECK-NEXT: %147 = OpBitcast %27 %66
+; CHECK-NEXT: OpLifetimeStart %147 24
+; CHECK-NEXT: OpCopyMemorySized %66 %39 %20 Aligned 8
+; CHECK-NEXT: %148 = OpBitcast %27 %67
+; CHECK-NEXT: OpLifetimeStart %148 80
+; CHECK-NEXT: %149 = OpLoad %8 %64
+; CHECK-NEXT: %150 = OpBuildNDRange %9 %149 %17 %17
+; CHECK-NEXT: OpStore %67 %150
+; CHECK-NEXT: %151 = OpBitcast %27 %67
+; CHECK-NEXT: OpLifetimeStop %151 80
+; CHECK-NEXT: %152 = OpBitcast %27 %68
+; CHECK-NEXT: OpLifetimeStart %152 80
+; CHECK-NEXT: %153 = OpBitcast %15 %64
+; CHECK-NEXT: %154 = OpBitcast %13 %153
+; CHECK-NEXT: %155 = OpLoad %12 %154
+; CHECK-NEXT: %156 = OpBitcast %13 %65
+; CHECK-NEXT: %157 = OpLoad %12 %156
+; CHECK-NEXT: %158 = OpBuildNDRange %9 %155 %157 %14
+; CHECK-NEXT: OpStore %68 %158
+; CHECK-NEXT: %159 = OpBitcast %27 %68
+; CHECK-NEXT: OpLifetimeStop %159 80
+; CHECK-NEXT: %160 = OpBitcast %27 %69
+; CHECK-NEXT: OpLifetimeStart %160 80
+; CHECK-NEXT: %161 = OpBitcast %15 %66
+; CHECK-NEXT: %162 = OpBitcast %13 %153
+; CHECK-NEXT: %163 = OpLoad %12 %162
+; CHECK-NEXT: %164 = OpBitcast %13 %65
+; CHECK-NEXT: %165 = OpLoad %12 %164
+; CHECK-NEXT: %166 = OpBitcast %13 %161
+; CHECK-NEXT: %167 = OpLoad %12 %166
+; CHECK-NEXT: %168 = OpBuildNDRange %9 %163 %165 %167
+; CHECK-NEXT: OpStore %69 %168
+; CHECK-NEXT: %169 = OpBitcast %27 %69
+; CHECK-NEXT: OpLifetimeStop %169 80
+; CHECK-NEXT: %170 = OpBitcast %27 %70
+; CHECK-NEXT: OpLifetimeStart %170 80
+; CHECK-NEXT: %171 = OpBitcast %13 %153
+; CHECK-NEXT: %172 = OpLoad %12 %171
+; CHECK-NEXT: %173 = OpBitcast %13 %64
+; CHECK-NEXT: %174 = OpLoad %12 %173
+; CHECK-NEXT: %175 = OpBuildNDRange %9 %172 %174 %14
+; CHECK-NEXT: OpStore %70 %175
+; CHECK-NEXT: %176 = OpBitcast %27 %70
+; CHECK-NEXT: OpLifetimeStop %176 80
+; CHECK-NEXT: %177 = OpBitcast %27 %71
+; CHECK-NEXT: OpLifetimeStart %177 80
+; CHECK-NEXT: %178 = OpBitcast %13 %153
+; CHECK-NEXT: %179 = OpLoad %12 %178
+; CHECK-NEXT: %180 = OpBitcast %13 %64
+; CHECK-NEXT: %181 = OpLoad %12 %180
+; CHECK-NEXT: %182 = OpBitcast %13 %153
+; CHECK-NEXT: %183 = OpLoad %12 %182
+; CHECK-NEXT: %184 = OpBuildNDRange %9 %179 %181 %183
+; CHECK-NEXT: OpStore %71 %184
+; CHECK-NEXT: %185 = OpBitcast %27 %71
+; CHECK-NEXT: OpLifetimeStop %185 80
+; CHECK-NEXT: %186 = OpBitcast %27 %72
+; CHECK-NEXT: OpLifetimeStart %186 80
+; CHECK-NEXT: %187 = OpBuildNDRange %9 %24 %25 %25
+; CHECK-NEXT: OpStore %72 %187
+; CHECK-NEXT: %188 = OpBitcast %27 %72
+; CHECK-NEXT: OpLifetimeStop %188 80
+; CHECK-NEXT: %189 = OpBitcast %27 %73
+; CHECK-NEXT: OpLifetimeStart %189 80
+; CHECK-NEXT: %190 = OpBuildNDRange %9 %24 %23 %25
+; CHECK-NEXT: OpStore %73 %190
+; CHECK-NEXT: %191 = OpBitcast %27 %73
+; CHECK-NEXT: OpLifetimeStop %191 80
+; CHECK-NEXT: %192 = OpBitcast %27 %74
+; CHECK-NEXT: OpLifetimeStart %192 80
+; CHECK-NEXT: %193 = OpBuildNDRange %9 %24 %23 %22
+; CHECK-NEXT: OpStore %74 %193
+; CHECK-NEXT: %194 = OpBitcast %27 %74
+; CHECK-NEXT: OpLifetimeStop %194 80
+; CHECK-NEXT: %195 = OpBitcast %27 %75
+; CHECK-NEXT: OpLifetimeStart %195 80
+; CHECK-NEXT: %196 = OpBuildNDRange %9 %24 %24 %25
+; CHECK-NEXT: OpStore %75 %196
+; CHECK-NEXT: %197 = OpBitcast %27 %75
+; CHECK-NEXT: OpLifetimeStop %197 80
+; CHECK-NEXT: %198 = OpBitcast %27 %76
+; CHECK-NEXT: OpLifetimeStart %198 80
+; CHECK-NEXT: %199 = OpBuildNDRange %9 %24 %24 %24
+; CHECK-NEXT: OpStore %76 %199
+; CHECK-NEXT: %200 = OpBitcast %27 %76
+; CHECK-NEXT: OpLifetimeStop %200 80
+; CHECK-NEXT: %201 = OpBitcast %27 %77
+; CHECK-NEXT: OpLifetimeStart %201 16
+; CHECK-NEXT: OpCopyMemorySized %77 %40 %21 Aligned 8
+; CHECK-NEXT: %202 = OpBitcast %27 %78
+; CHECK-NEXT: OpLifetimeStart %202 16
+; CHECK-NEXT: OpCopyMemorySized %78 %42 %21 Aligned 8
+; CHECK-NEXT: %203 = OpBitcast %27 %79
+; CHECK-NEXT: OpLifetimeStart %203 16
+; CHECK-NEXT: OpCopyMemorySized %79 %44 %21 Aligned 8
+; CHECK-NEXT: %204 = OpBitcast %27 %80
+; CHECK-NEXT: OpLifetimeStart %204 80
+; CHECK-NEXT: %205 = OpLoad %12 %77
+; CHECK-NEXT: %206 = OpBuildNDRange %9 %205 %14 %14
+; CHECK-NEXT: OpStore %80 %206
+; CHECK-NEXT: %207 = OpBitcast %27 %80
+; CHECK-NEXT: OpLifetimeStop %207 80
+; CHECK-NEXT: %208 = OpBitcast %27 %81
+; CHECK-NEXT: OpLifetimeStart %208 80
+; CHECK-NEXT: %209 = OpBitcast %15 %77
+; CHECK-NEXT: %210 = OpBitcast %13 %209
+; CHECK-NEXT: %211 = OpLoad %12 %210
+; CHECK-NEXT: %212 = OpLoad %12 %78
+; CHECK-NEXT: %213 = OpBuildNDRange %9 %211 %212 %14
+; CHECK-NEXT: OpStore %81 %213
+; CHECK-NEXT: %214 = OpBitcast %27 %81
+; CHECK-NEXT: OpLifetimeStop %214 80
+; CHECK-NEXT: %215 = OpBitcast %27 %82
+; CHECK-NEXT: OpLifetimeStart %215 80
+; CHECK-NEXT: %216 = OpBitcast %15 %79
+; CHECK-NEXT: %217 = OpBitcast %13 %209
+; CHECK-NEXT: %218 = OpLoad %12 %217
+; CHECK-NEXT: %219 = OpLoad %12 %78
+; CHECK-NEXT: %220 = OpBitcast %13 %216
+; CHECK-NEXT: %221 = OpLoad %12 %220
+; CHECK-NEXT: %222 = OpBuildNDRange %9 %218 %219 %221
+; CHECK-NEXT: OpStore %82 %222
+; CHECK-NEXT: %223 = OpBitcast %27 %82
+; CHECK-NEXT: OpLifetimeStop %223 80
+; CHECK-NEXT: %224 = OpBitcast %27 %83
+; CHECK-NEXT: OpLifetimeStart %224 80
+; CHECK-NEXT: %225 = OpBitcast %13 %209
+; CHECK-NEXT: %226 = OpLoad %12 %225
+; CHECK-NEXT: %227 = OpLoad %12 %77
+; CHECK-NEXT: %228 = OpBuildNDRange %9 %226 %227 %14
+; CHECK-NEXT: OpStore %83 %228
+; CHECK-NEXT: %229 = OpBitcast %27 %83
+; CHECK-NEXT: OpLifetimeStop %229 80
+; CHECK-NEXT: %230 = OpBitcast %27 %84
+; CHECK-NEXT: OpLifetimeStart %230 80
+; CHECK-NEXT: %231 = OpBitcast %13 %209
+; CHECK-NEXT: %232 = OpLoad %12 %231
+; CHECK-NEXT: %233 = OpLoad %12 %77
+; CHECK-NEXT: %234 = OpBitcast %13 %209
+; CHECK-NEXT: %235 = OpLoad %12 %234
+; CHECK-NEXT: %236 = OpBuildNDRange %9 %232 %233 %235
+; CHECK-NEXT: OpStore %84 %236
+; CHECK-NEXT: %237 = OpBitcast %27 %84
+; CHECK-NEXT: OpLifetimeStop %237 80
+; CHECK-NEXT: %238 = OpBitcast %27 %85
+; CHECK-NEXT: OpLifetimeStart %238 24
+; CHECK-NEXT: OpCopyMemorySized %85 %45 %20 Aligned 8
+; CHECK-NEXT: %239 = OpBitcast %27 %86
+; CHECK-NEXT: OpLifetimeStart %239 24
+; CHECK-NEXT: OpCopyMemorySized %86 %47 %20 Aligned 8
+; CHECK-NEXT: %240 = OpBitcast %27 %87
+; CHECK-NEXT: OpLifetimeStart %240 24
+; CHECK-NEXT: OpCopyMemorySized %87 %49 %20 Aligned 8
+; CHECK-NEXT: %241 = OpBitcast %27 %88
+; CHECK-NEXT: OpLifetimeStart %241 80
+; CHECK-NEXT: %242 = OpLoad %8 %85
+; CHECK-NEXT: %243 = OpBuildNDRange %9 %242 %17 %17
+; CHECK-NEXT: OpStore %88 %243
+; CHECK-NEXT: %244 = OpBitcast %27 %88
+; CHECK-NEXT: OpLifetimeStop %244 80
+; CHECK-NEXT: %245 = OpBitcast %27 %89
+; CHECK-NEXT: OpLifetimeStart %245 80
+; CHECK-NEXT: %246 = OpBitcast %15 %85
+; CHECK-NEXT: %247 = OpBitcast %13 %246
+; CHECK-NEXT: %248 = OpLoad %12 %247
+; CHECK-NEXT: %249 = OpBitcast %13 %86
+; CHECK-NEXT: %250 = OpLoad %12 %249
+; CHECK-NEXT: %251 = OpBuildNDRange %9 %248 %250 %14
+; CHECK-NEXT: OpStore %89 %251
+; CHECK-NEXT: %252 = OpBitcast %27 %89
+; CHECK-NEXT: OpLifetimeStop %252 80
+; CHECK-NEXT: %253 = OpBitcast %27 %90
+; CHECK-NEXT: OpLifetimeStart %253 80
+; CHECK-NEXT: %254 = OpBitcast %15 %87
+; CHECK-NEXT: %255 = OpBitcast %13 %246
+; CHECK-NEXT: %256 = OpLoad %12 %255
+; CHECK-NEXT: %257 = OpBitcast %13 %86
+; CHECK-NEXT: %258 = OpLoad %12 %257
+; CHECK-NEXT: %259 = OpBitcast %13 %254
+; CHECK-NEXT: %260 = OpLoad %12 %259
+; CHECK-NEXT: %261 = OpBuildNDRange %9 %256 %258 %260
+; CHECK-NEXT: OpStore %90 %261
+; CHECK-NEXT: %262 = OpBitcast %27 %90
+; CHECK-NEXT: OpLifetimeStop %262 80
+; CHECK-NEXT: %263 = OpBitcast %27 %91
+; CHECK-NEXT: OpLifetimeStart %263 80
+; CHECK-NEXT: %264 = OpBitcast %13 %246
+; CHECK-NEXT: %265 = OpLoad %12 %264
+; CHECK-NEXT: %266 = OpBitcast %13 %85
+; CHECK-NEXT: %267 = OpLoad %12 %266
+; CHECK-NEXT: %268 = OpBuildNDRange %9 %265 %267 %14
+; CHECK-NEXT: OpStore %91 %268
+; CHECK-NEXT: %269 = OpBitcast %27 %91
+; CHECK-NEXT: OpLifetimeStop %269 80
+; CHECK-NEXT: %270 = OpBitcast %27 %92
+; CHECK-NEXT: OpLifetimeStart %270 80
+; CHECK-NEXT: %271 = OpBitcast %13 %246
+; CHECK-NEXT: %272 = OpLoad %12 %271
+; CHECK-NEXT: %273 = OpBitcast %13 %85
+; CHECK-NEXT: %274 = OpLoad %12 %273
+; CHECK-NEXT: %275 = OpBitcast %13 %246
+; CHECK-NEXT: %276 = OpLoad %12 %275
+; CHECK-NEXT: %277 = OpBuildNDRange %9 %272 %274 %276
+; CHECK-NEXT: OpStore %92 %277
+; CHECK-NEXT: %278 = OpBitcast %27 %92
+; CHECK-NEXT: OpLifetimeStop %278 80
+; CHECK-NEXT: %279 = OpBitcast %27 %87
+; CHECK-NEXT: OpLifetimeStop %279 24
+; CHECK-NEXT: %280 = OpBitcast %27 %86
+; CHECK-NEXT: OpLifetimeStop %280 24
+; CHECK-NEXT: %281 = OpBitcast %27 %85
+; CHECK-NEXT: OpLifetimeStop %281 24
+; CHECK-NEXT: %282 = OpBitcast %27 %79
+; CHECK-NEXT: OpLifetimeStop %282 16
+; CHECK-NEXT: %283 = OpBitcast %27 %78
+; CHECK-NEXT: OpLifetimeStop %283 16
+; CHECK-NEXT: %284 = OpBitcast %27 %77
+; CHECK-NEXT: OpLifetimeStop %284 16
+; CHECK-NEXT: %285 = OpBitcast %27 %66
+; CHECK-NEXT: OpLifetimeStop %285 24
+; CHECK-NEXT: %286 = OpBitcast %27 %65
+; CHECK-NEXT: OpLifetimeStop %286 24
+; CHECK-NEXT: %287 = OpBitcast %27 %64
+; CHECK-NEXT: OpLifetimeStop %287 24
+; CHECK-NEXT: %288 = OpBitcast %27 %58
+; CHECK-NEXT: OpLifetimeStop %288 16
+; CHECK-NEXT: %289 = OpBitcast %27 %57
+; CHECK-NEXT: OpLifetimeStop %289 16
+; CHECK-NEXT: %290 = OpBitcast %27 %56
+; CHECK-NEXT: OpLifetimeStop %290 16
+; CHECK-NEXT: OpReturn
+; CHECK-NEXT: OpFunctionEnd
+entry:
+ %tmp = alloca %struct.ndrange_t, align 8
+ %tmp1 = alloca %struct.ndrange_t, align 8
+ %tmp2 = alloca %struct.ndrange_t, align 8
+ %tmp3 = alloca %struct.ndrange_t, align 8
+ %tmp4 = alloca %struct.ndrange_t, align 8
+ %GS2 = alloca [2 x i64], align 8
+ %LS2 = alloca [2 x i64], align 8
+ %WO2 = alloca [2 x i64], align 8
+ %tmp5 = alloca %struct.ndrange_t, align 8
+ %tmp8 = alloca %struct.ndrange_t, align 8
+ %tmp12 = alloca %struct.ndrange_t, align 8
+ %tmp15 = alloca %struct.ndrange_t, align 8
+ %tmp19 = alloca %struct.ndrange_t, align 8
+ %GS3 = alloca [3 x i64], align 8
+ %LS3 = alloca [3 x i64], align 8
+ %WO3 = alloca [3 x i64], align 8
+ %tmp21 = alloca %struct.ndrange_t, align 8
+ %tmp24 = alloca %struct.ndrange_t, align 8
+ %tmp28 = alloca %struct.ndrange_t, align 8
+ %tmp31 = alloca %struct.ndrange_t, align 8
+ %tmp35 = alloca %struct.ndrange_t, align 8
+ %tmp36 = alloca %struct.ndrange_t, align 8
+ %tmp37 = alloca %struct.ndrange_t, align 8
+ %tmp38 = alloca %struct.ndrange_t, align 8
+ %tmp39 = alloca %struct.ndrange_t, align 8
+ %tmp40 = alloca %struct.ndrange_t, align 8
+ %GS2c = alloca [2 x i64], align 8
+ %LS2c = alloca [2 x i64], align 8
+ %WO2c = alloca [2 x i64], align 8
+ %tmp42 = alloca %struct.ndrange_t, align 8
+ %tmp45 = alloca %struct.ndrange_t, align 8
+ %tmp49 = alloca %struct.ndrange_t, align 8
+ %tmp52 = alloca %struct.ndrange_t, align 8
+ %tmp56 = alloca %struct.ndrange_t, align 8
+ %GS3c = alloca [3 x i64], align 8
+ %LS3c = alloca [3 x i64], align 8
+ %WO3c = alloca [3 x i64], align 8
+ %tmp58 = alloca %struct.ndrange_t, align 8
+ %tmp61 = alloca %struct.ndrange_t, align 8
+ %tmp65 = alloca %struct.ndrange_t, align 8
+ %tmp68 = alloca %struct.ndrange_t, align 8
+ %tmp72 = alloca %struct.ndrange_t, align 8
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp) #4
+ call spir_func void @_Z10ndrange_1Dm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp, i64 noundef 1) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp1) #4
+ call spir_func void @_Z10ndrange_1Dmm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp1, i64 noundef 1, i64 noundef 2) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp1) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp2) #4
+ call spir_func void @_Z10ndrange_1Dmmm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp2, i64 noundef 3, i64 noundef 1, i64 noundef 2) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp2) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp3) #4
+ call spir_func void @_Z10ndrange_1Dmm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp3, i64 noundef 1, i64 noundef 1) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp3) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp4) #4
+ call spir_func void @_Z10ndrange_1Dmmm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp4, i64 noundef 1, i64 noundef 1, i64 noundef 1) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp4) #4
+ call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %GS2) #4
+ call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(16) %GS2, ptr addrspace(2) noundef align 8 dereferenceable(16) @__const.test_ndrange_2D3D.GS2, i64 16, i1 false)
+ call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %LS2) #4
+ call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(16) %LS2, ptr addrspace(2) noundef align 8 dereferenceable(16) @__const.test_ndrange_2D3D.LS2, i64 16, i1 false)
+ call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %WO2) #4
+ call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(16) %WO2, ptr addrspace(2) noundef align 8 dereferenceable(16) @__const.test_ndrange_2D3D.WO2, i64 16, i1 false)
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp5) #4
+ call spir_func void @_Z10ndrange_2DPKm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp5, ptr noundef nonnull %GS2) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp5) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp8) #4
+ call spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp8, ptr noundef nonnull %GS2, ptr noundef nonnull %LS2) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp8) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp12) #4
+ call spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp12, ptr noundef nonnull %WO2, ptr noundef nonnull %GS2, ptr noundef nonnull %LS2) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp12) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp15) #4
+ call spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp15, ptr noundef nonnull %GS2, ptr noundef nonnull %GS2) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp15) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp19) #4
+ call spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp19, ptr noundef nonnull %GS2, ptr noundef nonnull %GS2, ptr noundef nonnull %GS2) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp19) #4
+ call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %GS3) #4
+ call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(24) %GS3, ptr addrspace(2) noundef align 8 dereferenceable(24) @__const.test_ndrange_2D3D.GS3, i64 24, i1 false)
+ call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %LS3) #4
+ call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(24) %LS3, ptr addrspace(2) noundef align 8 dereferenceable(24) @__const.test_ndrange_2D3D.LS3, i64 24, i1 false)
+ call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %WO3) #4
+ call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(24) %WO3, ptr addrspace(2) noundef align 8 dereferenceable(24) @__const.test_ndrange_2D3D.WO3, i64 24, i1 false)
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp21) #4
+ call spir_func void @_Z10ndrange_3DPKm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp21, ptr noundef nonnull %GS3) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp21) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp24) #4
+ call spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp24, ptr noundef nonnull %GS3, ptr noundef nonnull %LS3) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp24) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp28) #4
+ call spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp28, ptr noundef nonnull %WO3, ptr noundef nonnull %GS3, ptr noundef nonnull %LS3) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp28) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp31) #4
+ call spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp31, ptr noundef nonnull %GS3, ptr noundef nonnull %GS3) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp31) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp35) #4
+ call spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp35, ptr noundef nonnull %GS3, ptr noundef nonnull %GS3, ptr noundef nonnull %GS3) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp35) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp36) #4
+ call spir_func void @_Z10ndrange_1Dm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp36, i64 noundef 1) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp36) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp37) #4
+ call spir_func void @_Z10ndrange_1Dmm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp37, i64 noundef 1, i64 noundef 2) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp37) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp38) #4
+ call spir_func void @_Z10ndrange_1Dmmm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp38, i64 noundef 3, i64 noundef 1, i64 noundef 2) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp38) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp39) #4
+ call spir_func void @_Z10ndrange_1Dmm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp39, i64 noundef 1, i64 noundef 1) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp39) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp40) #4
+ call spir_func void @_Z10ndrange_1Dmmm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp40, i64 noundef 1, i64 noundef 1, i64 noundef 1) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp40) #4
+ call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %GS2c) #4
+ call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(16) %GS2c, ptr addrspace(2) noundef align 8 dereferenceable(16) @__const.test_ndrange_2D3D.GS2c, i64 16, i1 false)
+ call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %LS2c) #4
+ call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(16) %LS2c, ptr addrspace(2) noundef align 8 dereferenceable(16) @__const.test_ndrange_2D3D.LS2c, i64 16, i1 false)
+ call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %WO2c) #4
+ call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(16) %WO2c, ptr addrspace(2) noundef align 8 dereferenceable(16) @__const.test_ndrange_2D3D.WO2c, i64 16, i1 false)
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp42) #4
+ call spir_func void @_Z10ndrange_2DPKm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp42, ptr noundef nonnull %GS2c) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp42) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp45) #4
+ call spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp45, ptr noundef nonnull %GS2c, ptr noundef nonnull %LS2c) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp45) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp49) #4
+ call spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp49, ptr noundef nonnull %WO2c, ptr noundef nonnull %GS2c, ptr noundef nonnull %LS2c) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp49) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp52) #4
+ call spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp52, ptr noundef nonnull %GS2c, ptr noundef nonnull %GS2c) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp52) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp56) #4
+ call spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp56, ptr noundef nonnull %GS2c, ptr noundef nonnull %GS2c, ptr noundef nonnull %GS2c) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp56) #4
+ call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %GS3c) #4
+ call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(24) %GS3c, ptr addrspace(2) noundef align 8 dereferenceable(24) @__const.test_ndrange_2D3D.GS3c, i64 24, i1 false)
+ call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %LS3c) #4
+ call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(24) %LS3c, ptr addrspace(2) noundef align 8 dereferenceable(24) @__const.test_ndrange_2D3D.LS3c, i64 24, i1 false)
+ call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %WO3c) #4
+ call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(24) %WO3c, ptr addrspace(2) noundef align 8 dereferenceable(24) @__const.test_ndrange_2D3D.WO3c, i64 24, i1 false)
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp58) #4
+ call spir_func void @_Z10ndrange_3DPKm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp58, ptr noundef nonnull %GS3c) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp58) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp61) #4
+ call spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp61, ptr noundef nonnull %GS3c, ptr noundef nonnull %LS3c) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp61) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp65) #4
+ call spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp65, ptr noundef nonnull %WO3c, ptr noundef nonnull %GS3c, ptr noundef nonnull %LS3c) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp65) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp68) #4
+ call spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp68, ptr noundef nonnull %GS3c, ptr noundef nonnull %GS3c) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp68) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp72) #4
+ call spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp72, ptr noundef nonnull %GS3c, ptr noundef nonnull %GS3c, ptr noundef nonnull %GS3c) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp72) #4
+ call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %WO3c) #4
+ call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %LS3c) #4
+ call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %GS3c) #4
+ call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %WO2c) #4
+ call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %LS2c) #4
+ call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %GS2c) #4
+ call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %WO3) #4
+ call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %LS3) #4
+ call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %GS3) #4
+ call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %WO2) #4
+ call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %LS2) #4
+ call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %GS2) #4
ret void
}
-declare spir_func void @_Z10ndrange_1Djj(ptr sret(ptr), i32, i32)
+declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1
+declare spir_func void @_Z10ndrange_1Dm(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, i64 noundef) local_unnamed_addr #2
+declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1
+declare spir_func void @_Z10ndrange_1Dmm(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, i64 noundef, i64 noundef) local_unnamed_addr #2
+declare spir_func void @_Z10ndrange_1Dmmm(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, i64 noundef, i64 noundef, i64 noundef) local_unnamed_addr #2
+declare void @llvm.memcpy.p0.p2.i64(ptr noalias nocapture writeonly, ptr addrspace(2) noalias nocapture readonly, i64, i1 immarg) #3
+declare spir_func void @_Z10ndrange_2DPKm(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, ptr noundef) local_unnamed_addr #2
+declare spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, ptr noundef, ptr noundef) local_unnamed_addr #2
+declare spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #2
+declare spir_func void @_Z10ndrange_3DPKm(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, ptr noundef) local_unnamed_addr #2
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange_2.ll b/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange_2.ll
deleted file mode 100644
index 8ba5e99df52ae..0000000000000
--- a/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange_2.ll
+++ /dev/null
@@ -1,83 +0,0 @@
-;; Test what ndrange_2D and ndrange_3D can coexist in the same module
-;;
-;; bash$ cat BuildNDRange_2.cl
-;; void test_ndrange_2D3D() {
-;; size_t lsize2[2] = {1, 1};
-;; ndrange_2D(lsize2);
-;;
-;; size_t lsize3[3] = {1, 1, 1};
-;; ndrange_3D(lsize3);
-;; }
-;;
-;; void test_ndrange_const_2D3D() {
-;; const size_t lsize2[2] = {1, 1};
-;; ndrange_2D(lsize2);
-;;
-;; const size_t lsize3[3] = {1, 1, 1};
-;; ndrange_3D(lsize3);
-;; }
-;; bash$ $PATH_TO_GEN/bin/clang -cc1 -x cl -cl-std=CL2.0 -triple spir64-unknown-unknown -emit-llvm -include opencl-20.h BuildNDRange_2.cl -o BuildNDRange_2.ll
-
-; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
-; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-
-; TODO(#60133): Requires updates following opaque pointer migration.
-; XFAIL: *
-; REQUIRES: asserts
-
-; CHECK-SPIRV-DAG: %[[#LEN2_ID:]] = OpConstant %[[#]] 2
-; CHECK-SPIRV-DAG: %[[#LEN3_ID:]] = OpConstant %[[#]] 3
-; CHECK-SPIRV-DAG: %[[#ARRAY_T2:]] = OpTypeArray %[[#]] %[[#LEN2_ID]]
-; CHECK-SPIRV-DAG: %[[#ARRAY_T3:]] = OpTypeArray %[[#]] %[[#LEN3_ID]]
-
-; CHECK-SPIRV-LABEL: OpFunction
-; CHECK-SPIRV: %[[#LOAD2_ID:]] = OpLoad %[[#ARRAY_T2]]
-; CHECK-SPIRV: %[[#]] = OpBuildNDRange %[[#]] %[[#LOAD2_ID]]
-; CHECK-SPIRV: %[[#LOAD3_ID:]] = OpLoad %[[#ARRAY_T3]]
-; CHECK-SPIRV: %[[#]] = OpBuildNDRange %[[#]] %[[#LOAD3_ID]]
-; CHECK-SPIRV-LABEL: OpFunctionEnd
-
-; CHECK-SPIRV-LABEL: OpFunction
-; CHECK-SPIRV: %[[#CONST_LOAD2_ID:]] = OpLoad %[[#ARRAY_T2]]
-; CHECK-SPIRV: %[[#]] = OpBuildNDRange %[[#]] %[[#CONST_LOAD2_ID]]
-; CHECK-SPIRV: %[[#CONST_LOAD3_ID:]] = OpLoad %[[#ARRAY_T3]]
-; CHECK-SPIRV: %[[#]] = OpBuildNDRange %[[#]] %[[#CONST_LOAD3_ID]]
-; CHECK-SPIRV-LABEL: OpFunctionEnd
-
-%struct.ndrange_t = type { i32, [3 x i64], [3 x i64], [3 x i64] }
-
- at test_ndrange_2D3D.lsize2 = private constant [2 x i64] [i64 1, i64 1], align 8
- at test_ndrange_2D3D.lsize3 = private constant [3 x i64] [i64 1, i64 1, i64 1], align 8
-
-
-define spir_func void @test_ndrange_2D3D() {
-entry:
- %lsize2 = alloca [2 x i64], align 8
- %tmp = alloca %struct.ndrange_t, align 8
- %lsize3 = alloca [3 x i64], align 8
- %tmp3 = alloca %struct.ndrange_t, align 8
- %0 = bitcast ptr %lsize2 to ptr
- call void @llvm.memcpy.p0.p0.i64(ptr align 8 %0, ptr align 8 @test_ndrange_2D3D.lsize2, i64 16, i1 false)
- %arraydecay = getelementptr inbounds [2 x i64], ptr %lsize2, i64 0, i64 0
- call spir_func void @_Z10ndrange_2DPKm(ptr sret(ptr) %tmp, ptr %arraydecay)
- %1 = bitcast ptr %lsize3 to ptr
- call void @llvm.memcpy.p0.p0.i64(ptr align 8 %1, ptr align 8 @test_ndrange_2D3D.lsize3, i64 24, i1 false)
- %arraydecay2 = getelementptr inbounds [3 x i64], ptr %lsize3, i64 0, i64 0
- call spir_func void @_Z10ndrange_3DPKm(ptr sret(ptr) %tmp3, ptr %arraydecay2)
- ret void
-}
-
-declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture readonly, i64, i1)
-
-declare spir_func void @_Z10ndrange_2DPKm(ptr sret(ptr), ptr)
-
-declare spir_func void @_Z10ndrange_3DPKm(ptr sret(ptr), ptr)
-
-define spir_func void @test_ndrange_const_2D3D() {
-entry:
- %tmp = alloca %struct.ndrange_t, align 8
- %tmp1 = alloca %struct.ndrange_t, align 8
- call spir_func void @_Z10ndrange_2DPKm(ptr sret(ptr) %tmp, ptr @test_ndrange_2D3D.lsize2)
- call spir_func void @_Z10ndrange_3DPKm(ptr sret(ptr) %tmp1, ptr @test_ndrange_2D3D.lsize3)
- ret void
-}
>From 5a233bac8ad58524854493cb2a64bceb1198f25e Mon Sep 17 00:00:00 2001
From: idubinov <igor.dubinov at amd.com>
Date: Thu, 12 Mar 2026 10:25:22 -0500
Subject: [PATCH 3/8] code format
---
llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index 9a5d14276a321..2677ad1b5ca3e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -2659,24 +2659,21 @@ static bool buildNDRange(const SPIRV::IncomingCall *Call,
const unsigned AddressModelBits = GR->getPointerSize();
assert(AddressModelBits == 64 || AddressModelBits == 32);
-
// The dimension is encoded in the function name as "ndrange_XD" where X is
// 1, 2, or 3.
unsigned Dimension = atoi(Call->Builtin->Name.substr(8, 1).data());
assert(Dimension <= 3 && Dimension >= 1);
-
- // Get work size type; When fewer than 4 arguments are provided, build a zero constant for the
- // missing one.
+ // Get work size type; When fewer than 4 arguments are provided, build a zero
+ // constant for the missing one.
SPIRVTypeInst SpvFieldTy;
Register ConstZero;
if (Dimension == 1) {
- SpvFieldTy =
- GR->getSPIRVTypeForVReg(Call->Arguments[GlobalWorkSizeArgIdx]);
+ SpvFieldTy = GR->getSPIRVTypeForVReg(Call->Arguments[GlobalWorkSizeArgIdx]);
assert(SpvFieldTy && SpvFieldTy->getOpcode() == SPIRV::OpTypeInt &&
- "Expected scalar integer type");
+ "Expected scalar integer type");
- if (NumArgs < 4)
+ if (NumArgs < 4)
ConstZero = GR->buildConstantInt(0, MIRBuilder, SpvFieldTy, true);
} else {
Type *BaseTy =
@@ -2695,7 +2692,6 @@ static bool buildNDRange(const SPIRV::IncomingCall *Call,
}
}
-
Register GlobalWorkSize;
Register LocalWorkSize;
Register GlobalWorkOffset;
>From abb41d1516307ae6f2699aabb8aba5e6c9b670bb Mon Sep 17 00:00:00 2001
From: idubinov <igor.dubinov at amd.com>
Date: Tue, 17 Mar 2026 11:20:00 -0500
Subject: [PATCH 4/8] Add support of no sret calls
---
llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp | 81 +++++++++++--------
llvm/lib/Target/SPIRV/SPIRVBuiltins.td | 6 +-
.../SPIRV/transcoding/BuildNDRange_no_sret.ll | 27 +++++++
3 files changed, 76 insertions(+), 38 deletions(-)
create mode 100644 llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange_no_sret.ll
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index 2677ad1b5ca3e..a28ba27365b2f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -2625,34 +2625,28 @@ static bool buildNDRange(const SPIRV::IncomingCall *Call,
// (global_work_size)
// (global_work_size, local_work_size)
// (global_work_offset, global_work_size, local_work_size) -- note the
- // argument reordering
+ // argument reordering when max arguments presented
+ // The function can return data throught sret argument on position 0, while function return value is void - in that case other argument indexes should be adjusted accordingly.
//
// SPIR-V's OpBuildNDRange takes all three arguments (GlobalWorkSize,
// LocalWorkSize, GlobalWorkOffset). For 1D kernels the values are scalars;
// for 2D/3D they are arrays of 2 or 3 elements. Any missing argument is
// set to zero.
-
+ //
+ // Lets calculate argument indexes based on that info:
unsigned NumArgs = Call->Arguments.size();
- assert(NumArgs >= 2 && NumArgs <= 4);
+ const unsigned maxArgs = Call->Builtin->MaxNumArgs;
+ const unsigned IncorrectArgIdx = maxArgs + 1;
- const unsigned ReturnValueArgIdx = 0;
- const unsigned IncorrectArgIdx = 5;
- const unsigned GlobalWorkSizeArgIdx = NumArgs < 4 ? 1 : 2;
- const unsigned LocalWorkSizeArgIdx =
- NumArgs == 2 ? IncorrectArgIdx : (NumArgs == 3 ? 2 : 3);
- const unsigned GlobalWorkOffsetArgIdx = NumArgs < 4 ? IncorrectArgIdx : 1;
+ const Type *RetTy = GR->getTypeForSPIRVType(Call->ReturnType);
+ bool hasSRetArg = RetTy->isVoidTy();
- // Return type is the nd_range struct pointed to by the first argument.
- MachineRegisterInfo *MRI = MIRBuilder.getMRI();
- SPIRVTypeInst PtrType =
- GR->getSPIRVTypeForVReg(Call->Arguments[ReturnValueArgIdx]);
- assert(PtrType->getOpcode() == SPIRV::OpTypePointer &&
- PtrType->getOperand(2 /*Pointee*/).isReg());
- Register ReturnTypeReg = PtrType->getOperand(2).getReg();
- SPIRVTypeInst ReturnStructType = GR->getSPIRVTypeForVReg(ReturnTypeReg);
- MachineFunction &MF = MIRBuilder.getMF();
- Register TmpReg = MRI->createVirtualRegister(&SPIRV::iIDRegClass);
- GR->assignSPIRVTypeToVReg(ReturnStructType, TmpReg, MF);
+ const unsigned SRetArgIdx = hasSRetArg ? 0 : IncorrectArgIdx;
+ const unsigned ArgBase = hasSRetArg ? 1 : 0;
+ const unsigned GlobalWorkSizeArgIdx = NumArgs < maxArgs ? ArgBase : ArgBase + 1;
+ const unsigned LocalWorkSizeArgIdx =
+ (NumArgs - ArgBase == 1) ? IncorrectArgIdx : (NumArgs == maxArgs ? ArgBase + 2 : ArgBase + 1);
+ const unsigned GlobalWorkOffsetArgIdx = NumArgs == maxArgs ? ArgBase : IncorrectArgIdx;
// Each nd_range field is an array of <Dimension> integers matching the
// address model width (32 or 64 bits).
@@ -2666,6 +2660,7 @@ static bool buildNDRange(const SPIRV::IncomingCall *Call,
// Get work size type; When fewer than 4 arguments are provided, build a zero
// constant for the missing one.
+ MachineFunction &MF = MIRBuilder.getMF();
SPIRVTypeInst SpvFieldTy;
Register ConstZero;
if (Dimension == 1) {
@@ -2673,7 +2668,7 @@ static bool buildNDRange(const SPIRV::IncomingCall *Call,
assert(SpvFieldTy && SpvFieldTy->getOpcode() == SPIRV::OpTypeInt &&
"Expected scalar integer type");
- if (NumArgs < 4)
+ if (NumArgs < maxArgs)
ConstZero = GR->buildConstantInt(0, MIRBuilder, SpvFieldTy, true);
} else {
Type *BaseTy =
@@ -2682,7 +2677,7 @@ static bool buildNDRange(const SPIRV::IncomingCall *Call,
SpvFieldTy = GR->getOrCreateSPIRVType(
FieldTy, MIRBuilder, SPIRV::AccessQualifier::ReadOnly, true);
- if (NumArgs < 4) {
+ if (NumArgs < maxArgs) {
auto InsertIt = MIRBuilder.getInsertPt();
MachineBasicBlock &MBB = MIRBuilder.getMBB();
MachineInstr &InsertMI = (InsertIt != MBB.end()) ? *InsertIt : MBB.back();
@@ -2692,16 +2687,14 @@ static bool buildNDRange(const SPIRV::IncomingCall *Call,
}
}
- Register GlobalWorkSize;
- Register LocalWorkSize;
- Register GlobalWorkOffset;
+ MachineRegisterInfo *MRI = MIRBuilder.getMRI();
- auto LoadRegisterData = [&](Register &Reg, unsigned Idx) {
- Reg = (Idx == IncorrectArgIdx) ? ConstZero : Call->Arguments[Idx];
+ auto CreateDataRegister = [&](unsigned Idx) -> Register {
+ Register Reg = (Idx == IncorrectArgIdx) ? ConstZero : Call->Arguments[Idx];
if (GR->getSPIRVTypeForVReg(Reg) == SpvFieldTy) {
- // Already has the correct type
- return;
+ // Already has the correct type.
+ return Reg;
}
assert(GR->getSPIRVTypeForVReg(Reg)->getOpcode() == SPIRV::OpTypePointer &&
@@ -2716,21 +2709,39 @@ static bool buildNDRange(const SPIRV::IncomingCall *Call,
.addDef(Reg)
.addUse(GR->getSPIRVTypeID(SpvFieldTy))
.addUse(Ptr);
- return;
+ return Reg;
};
- LoadRegisterData(GlobalWorkSize, GlobalWorkSizeArgIdx);
- LoadRegisterData(LocalWorkSize, LocalWorkSizeArgIdx);
- LoadRegisterData(GlobalWorkOffset, GlobalWorkOffsetArgIdx);
+ Register GlobalWorkSize = CreateDataRegister(GlobalWorkSizeArgIdx);
+ Register LocalWorkSize = CreateDataRegister(LocalWorkSizeArgIdx);
+ Register GlobalWorkOffset = CreateDataRegister(GlobalWorkOffsetArgIdx);
+
+ if (!hasSRetArg) {
+ return MIRBuilder.buildInstr(SPIRV::OpBuildNDRange)
+ .addDef(Call->ReturnRegister)
+ .addUse(GR->getSPIRVTypeID(Call->ReturnType))
+ .addUse(GlobalWorkSize)
+ .addUse(LocalWorkSize)
+ .addUse(GlobalWorkOffset);
+ }
+
+ // SRet argument presented - return type is the nd_range struct pointed to by the first argument.
+ Register SRetReg = Call->Arguments[SRetArgIdx];
+ SPIRVTypeInst SRetPtrType =
+ GR->getSPIRVTypeForVReg(SRetReg);
+ SPIRVTypeInst SRetType = GR->getPointeeType(SRetPtrType);
+
+ Register TmpReg = MRI->createVirtualRegister(&SPIRV::iIDRegClass);
+ GR->assignSPIRVTypeToVReg(SRetType, TmpReg, MF);
MIRBuilder.buildInstr(SPIRV::OpBuildNDRange)
.addDef(TmpReg)
- .addUse(ReturnTypeReg)
+ .addUse(GR->getSPIRVTypeID(SRetType))
.addUse(GlobalWorkSize)
.addUse(LocalWorkSize)
.addUse(GlobalWorkOffset);
return MIRBuilder.buildInstr(SPIRV::OpStore)
- .addUse(Call->Arguments[ReturnValueArgIdx])
+ .addUse(Call->Arguments[SRetArgIdx])
.addUse(TmpReg);
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.td b/llvm/lib/Target/SPIRV/SPIRVBuiltins.td
index 3820713db3e4a..f3daf7c22674e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.td
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.td
@@ -702,9 +702,9 @@ defm : DemangledNativeBuiltin<"capture_event_profiling_info", OpenCL_std, Enqueu
defm : DemangledNativeBuiltin<"__spirv_CaptureEventProfilingInfo", OpenCL_std, Enqueue, 3, 3, OpCaptureEventProfilingInfo>;
defm : DemangledNativeBuiltin<"get_default_queue", OpenCL_std, Enqueue, 0, 0, OpGetDefaultQueue>;
defm : DemangledNativeBuiltin<"__spirv_GetDefaultQueue", OpenCL_std, Enqueue, 0, 0, OpGetDefaultQueue>;
-defm : DemangledNativeBuiltin<"ndrange_1D", OpenCL_std, Enqueue, 2, 4, OpBuildNDRange>;
-defm : DemangledNativeBuiltin<"ndrange_2D", OpenCL_std, Enqueue, 2, 4, OpBuildNDRange>;
-defm : DemangledNativeBuiltin<"ndrange_3D", OpenCL_std, Enqueue, 2, 4, OpBuildNDRange>;
+defm : DemangledNativeBuiltin<"ndrange_1D", OpenCL_std, Enqueue, 1, 4, OpBuildNDRange>;
+defm : DemangledNativeBuiltin<"ndrange_2D", OpenCL_std, Enqueue, 1, 4, OpBuildNDRange>;
+defm : DemangledNativeBuiltin<"ndrange_3D", OpenCL_std, Enqueue, 1, 4, OpBuildNDRange>;
// Spec constant builtin records:
defm : DemangledNativeBuiltin<"__spirv_SpecConstant", OpenCL_std, SpecConstant, 2, 2, OpSpecConstant>;
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange_no_sret.ll b/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange_no_sret.ll
new file mode 100644
index 0000000000000..d13e7cba6d9bf
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange_no_sret.ll
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+
+%struct.ndrange_t = type { i32, [3 x i64], [3 x i64], [3 x i64] }
+
+define spir_func void @test_ndrange_2D3D() local_unnamed_addr #0 {
+; CHECK-LABEL: test_ndrange_2D3D
+; CHECK: Begin function test_ndrange_2D3D
+; CHECK: %[[#r18:]] = OpBuildNDRange %[[#r10:]] %[[#r11:]] %[[#r12:]] %[[#r13:]]
+; CHECK-NOT: OpStore %[[#r19:]] %[[#r18]]
+entry:
+ %tmp = alloca %struct.ndrange_t, align 8
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp) #3
+ call spir_func %struct.ndrange_t @_Z10ndrange_1Dm(i64 noundef 1) #4
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp) #3
+ ret void
+}
+
+declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1
+
+declare spir_func %struct.ndrange_t @_Z10ndrange_1Dm(i64 noundef) local_unnamed_addr #2
+
+; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1
>From 231dd9ab7308a3e34a7017c16f3d432b71143646 Mon Sep 17 00:00:00 2001
From: idubinov <igor.dubinov at amd.com>
Date: Tue, 17 Mar 2026 11:24:39 -0500
Subject: [PATCH 5/8] code format
---
llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp | 53 +++++++++++++++----------
1 file changed, 31 insertions(+), 22 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index a28ba27365b2f..a885da7118b82 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -2624,16 +2624,21 @@ static bool buildNDRange(const SPIRV::IncomingCall *Call,
// variants, accepting 1 to 3 arguments:
// (global_work_size)
// (global_work_size, local_work_size)
- // (global_work_offset, global_work_size, local_work_size) -- note the
- // argument reordering when max arguments presented
- // The function can return data throught sret argument on position 0, while function return value is void - in that case other argument indexes should be adjusted accordingly.
+ // (global_work_offset, global_work_size, local_work_size)
+ // Note: When all three arguments are provided, they are reordered compared
+ // to the one- or two-argument form.
//
- // SPIR-V's OpBuildNDRange takes all three arguments (GlobalWorkSize,
- // LocalWorkSize, GlobalWorkOffset). For 1D kernels the values are scalars;
- // for 2D/3D they are arrays of 2 or 3 elements. Any missing argument is
- // set to zero.
- //
- // Lets calculate argument indexes based on that info:
+ // The function may return data through an sret argument at position 0 (with
+ // a void function return type). When present, all other argument indices are
+ // adjusted accordingly.
+ //
+ // SPIR-V's OpBuildNDRange requires all three arguments (GlobalWorkSize,
+ // LocalWorkSize, GlobalWorkOffset). For 1D kernels, the values are scalars;
+ // for 2D/3D kernels, they are arrays of 2 or 3 elements. Missing arguments
+ // default to zero.
+ //
+ // Calculate argument indices based on the number of arguments and presence
+ // of sret:
unsigned NumArgs = Call->Arguments.size();
const unsigned maxArgs = Call->Builtin->MaxNumArgs;
const unsigned IncorrectArgIdx = maxArgs + 1;
@@ -2643,10 +2648,14 @@ static bool buildNDRange(const SPIRV::IncomingCall *Call,
const unsigned SRetArgIdx = hasSRetArg ? 0 : IncorrectArgIdx;
const unsigned ArgBase = hasSRetArg ? 1 : 0;
- const unsigned GlobalWorkSizeArgIdx = NumArgs < maxArgs ? ArgBase : ArgBase + 1;
+ const unsigned GlobalWorkSizeArgIdx =
+ NumArgs < maxArgs ? ArgBase : ArgBase + 1;
const unsigned LocalWorkSizeArgIdx =
- (NumArgs - ArgBase == 1) ? IncorrectArgIdx : (NumArgs == maxArgs ? ArgBase + 2 : ArgBase + 1);
- const unsigned GlobalWorkOffsetArgIdx = NumArgs == maxArgs ? ArgBase : IncorrectArgIdx;
+ (NumArgs - ArgBase == 1)
+ ? IncorrectArgIdx
+ : (NumArgs == maxArgs ? ArgBase + 2 : ArgBase + 1);
+ const unsigned GlobalWorkOffsetArgIdx =
+ NumArgs == maxArgs ? ArgBase : IncorrectArgIdx;
// Each nd_range field is an array of <Dimension> integers matching the
// address model width (32 or 64 bits).
@@ -2658,8 +2667,8 @@ static bool buildNDRange(const SPIRV::IncomingCall *Call,
unsigned Dimension = atoi(Call->Builtin->Name.substr(8, 1).data());
assert(Dimension <= 3 && Dimension >= 1);
- // Get work size type; When fewer than 4 arguments are provided, build a zero
- // constant for the missing one.
+ // Determine the work size type based on the dimension. For missing arguments,
+ // create a zero constant of the appropriate type.
MachineFunction &MF = MIRBuilder.getMF();
SPIRVTypeInst SpvFieldTy;
Register ConstZero;
@@ -2718,17 +2727,17 @@ static bool buildNDRange(const SPIRV::IncomingCall *Call,
if (!hasSRetArg) {
return MIRBuilder.buildInstr(SPIRV::OpBuildNDRange)
- .addDef(Call->ReturnRegister)
- .addUse(GR->getSPIRVTypeID(Call->ReturnType))
- .addUse(GlobalWorkSize)
- .addUse(LocalWorkSize)
- .addUse(GlobalWorkOffset);
+ .addDef(Call->ReturnRegister)
+ .addUse(GR->getSPIRVTypeID(Call->ReturnType))
+ .addUse(GlobalWorkSize)
+ .addUse(LocalWorkSize)
+ .addUse(GlobalWorkOffset);
}
- // SRet argument presented - return type is the nd_range struct pointed to by the first argument.
+ // When sret is used, store nd_range struct through the pointer in the first
+ // argument.
Register SRetReg = Call->Arguments[SRetArgIdx];
- SPIRVTypeInst SRetPtrType =
- GR->getSPIRVTypeForVReg(SRetReg);
+ SPIRVTypeInst SRetPtrType = GR->getSPIRVTypeForVReg(SRetReg);
SPIRVTypeInst SRetType = GR->getPointeeType(SRetPtrType);
Register TmpReg = MRI->createVirtualRegister(&SPIRV::iIDRegClass);
>From bde1071469c19e4c872f059191388324080adb98 Mon Sep 17 00:00:00 2001
From: idubinov <igor.dubinov at amd.com>
Date: Tue, 17 Mar 2026 11:52:25 -0500
Subject: [PATCH 6/8] update test
---
.../CodeGen/SPIRV/transcoding/BuildNDRange.ll | 737 +++++++++---------
.../SPIRV/transcoding/BuildNDRange_no_sret.ll | 7 -
2 files changed, 368 insertions(+), 376 deletions(-)
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange.ll b/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange.ll
index fac6aebfaa500..68692084bbc4e 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange.ll
@@ -1,4 +1,3 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
;; Test that checks all variants of ndrange and what ndrange_1D, ndrange_2D and ndrange_3D can coexist in the same module
;;
;; bash$ cat BuildNDRange.cl
@@ -75,374 +74,374 @@
define spir_func void @test_ndrange_2D3D() local_unnamed_addr #0 {
; CHECK-LABEL: test_ndrange_2D3D
-; CHECK: %50 = OpFunction %3 None %4 ; -- Begin function test_ndrange_2D3D
-; CHECK-NEXT: %2 = OpLabel
-; CHECK-NEXT: %51 = OpVariable %10 Function
-; CHECK-NEXT: %52 = OpVariable %10 Function
-; CHECK-NEXT: %53 = OpVariable %10 Function
-; CHECK-NEXT: %54 = OpVariable %10 Function
-; CHECK-NEXT: %55 = OpVariable %10 Function
-; CHECK-NEXT: %56 = OpVariable %13 Function
-; CHECK-NEXT: %57 = OpVariable %13 Function
-; CHECK-NEXT: %58 = OpVariable %13 Function
-; CHECK-NEXT: %59 = OpVariable %10 Function
-; CHECK-NEXT: %60 = OpVariable %10 Function
-; CHECK-NEXT: %61 = OpVariable %10 Function
-; CHECK-NEXT: %62 = OpVariable %10 Function
-; CHECK-NEXT: %63 = OpVariable %10 Function
-; CHECK-NEXT: %64 = OpVariable %16 Function
-; CHECK-NEXT: %65 = OpVariable %16 Function
-; CHECK-NEXT: %66 = OpVariable %16 Function
-; CHECK-NEXT: %67 = OpVariable %10 Function
-; CHECK-NEXT: %68 = OpVariable %10 Function
-; CHECK-NEXT: %69 = OpVariable %10 Function
-; CHECK-NEXT: %70 = OpVariable %10 Function
-; CHECK-NEXT: %71 = OpVariable %10 Function
-; CHECK-NEXT: %72 = OpVariable %10 Function
-; CHECK-NEXT: %73 = OpVariable %10 Function
-; CHECK-NEXT: %74 = OpVariable %10 Function
-; CHECK-NEXT: %75 = OpVariable %10 Function
-; CHECK-NEXT: %76 = OpVariable %10 Function
-; CHECK-NEXT: %77 = OpVariable %13 Function
-; CHECK-NEXT: %78 = OpVariable %13 Function
-; CHECK-NEXT: %79 = OpVariable %13 Function
-; CHECK-NEXT: %80 = OpVariable %10 Function
-; CHECK-NEXT: %81 = OpVariable %10 Function
-; CHECK-NEXT: %82 = OpVariable %10 Function
-; CHECK-NEXT: %83 = OpVariable %10 Function
-; CHECK-NEXT: %84 = OpVariable %10 Function
-; CHECK-NEXT: %85 = OpVariable %16 Function
-; CHECK-NEXT: %86 = OpVariable %16 Function
-; CHECK-NEXT: %87 = OpVariable %16 Function
-; CHECK-NEXT: %88 = OpVariable %10 Function
-; CHECK-NEXT: %89 = OpVariable %10 Function
-; CHECK-NEXT: %90 = OpVariable %10 Function
-; CHECK-NEXT: %91 = OpVariable %10 Function
-; CHECK-NEXT: %92 = OpVariable %10 Function
-; CHECK-NEXT: %93 = OpBitcast %27 %51
-; CHECK-NEXT: OpLifetimeStart %93 80
-; CHECK-NEXT: %94 = OpBuildNDRange %9 %24 %25 %25
-; CHECK-NEXT: OpStore %51 %94
-; CHECK-NEXT: %95 = OpBitcast %27 %51
-; CHECK-NEXT: OpLifetimeStop %95 80
-; CHECK-NEXT: %96 = OpBitcast %27 %52
-; CHECK-NEXT: OpLifetimeStart %96 80
-; CHECK-NEXT: %97 = OpBuildNDRange %9 %24 %23 %25
-; CHECK-NEXT: OpStore %52 %97
-; CHECK-NEXT: %98 = OpBitcast %27 %52
-; CHECK-NEXT: OpLifetimeStop %98 80
-; CHECK-NEXT: %99 = OpBitcast %27 %53
-; CHECK-NEXT: OpLifetimeStart %99 80
-; CHECK-NEXT: %100 = OpBuildNDRange %9 %24 %23 %22
-; CHECK-NEXT: OpStore %53 %100
-; CHECK-NEXT: %101 = OpBitcast %27 %53
-; CHECK-NEXT: OpLifetimeStop %101 80
-; CHECK-NEXT: %102 = OpBitcast %27 %54
-; CHECK-NEXT: OpLifetimeStart %102 80
-; CHECK-NEXT: %103 = OpBuildNDRange %9 %24 %24 %25
-; CHECK-NEXT: OpStore %54 %103
-; CHECK-NEXT: %104 = OpBitcast %27 %54
-; CHECK-NEXT: OpLifetimeStop %104 80
-; CHECK-NEXT: %105 = OpBitcast %27 %55
-; CHECK-NEXT: OpLifetimeStart %105 80
-; CHECK-NEXT: %106 = OpBuildNDRange %9 %24 %24 %24
-; CHECK-NEXT: OpStore %55 %106
-; CHECK-NEXT: %107 = OpBitcast %27 %55
-; CHECK-NEXT: OpLifetimeStop %107 80
-; CHECK-NEXT: %108 = OpBitcast %27 %56
-; CHECK-NEXT: OpLifetimeStart %108 16
-; CHECK-NEXT: OpCopyMemorySized %56 %29 %21 Aligned 8
-; CHECK-NEXT: %109 = OpBitcast %27 %57
-; CHECK-NEXT: OpLifetimeStart %109 16
-; CHECK-NEXT: OpCopyMemorySized %57 %31 %21 Aligned 8
-; CHECK-NEXT: %110 = OpBitcast %27 %58
-; CHECK-NEXT: OpLifetimeStart %110 16
-; CHECK-NEXT: OpCopyMemorySized %58 %33 %21 Aligned 8
-; CHECK-NEXT: %111 = OpBitcast %27 %59
-; CHECK-NEXT: OpLifetimeStart %111 80
-; CHECK-NEXT: %112 = OpLoad %12 %56
-; CHECK-NEXT: %113 = OpBuildNDRange %9 %112 %14 %14
-; CHECK-NEXT: OpStore %59 %113
-; CHECK-NEXT: %114 = OpBitcast %27 %59
-; CHECK-NEXT: OpLifetimeStop %114 80
-; CHECK-NEXT: %115 = OpBitcast %27 %60
-; CHECK-NEXT: OpLifetimeStart %115 80
-; CHECK-NEXT: %116 = OpBitcast %15 %56
-; CHECK-NEXT: %117 = OpBitcast %13 %116
-; CHECK-NEXT: %118 = OpLoad %12 %117
-; CHECK-NEXT: %119 = OpLoad %12 %57
-; CHECK-NEXT: %120 = OpBuildNDRange %9 %118 %119 %14
-; CHECK-NEXT: OpStore %60 %120
-; CHECK-NEXT: %121 = OpBitcast %27 %60
-; CHECK-NEXT: OpLifetimeStop %121 80
-; CHECK-NEXT: %122 = OpBitcast %27 %61
-; CHECK-NEXT: OpLifetimeStart %122 80
-; CHECK-NEXT: %123 = OpBitcast %15 %58
-; CHECK-NEXT: %124 = OpBitcast %13 %116
-; CHECK-NEXT: %125 = OpLoad %12 %124
-; CHECK-NEXT: %126 = OpLoad %12 %57
-; CHECK-NEXT: %127 = OpBitcast %13 %123
-; CHECK-NEXT: %128 = OpLoad %12 %127
-; CHECK-NEXT: %129 = OpBuildNDRange %9 %125 %126 %128
-; CHECK-NEXT: OpStore %61 %129
-; CHECK-NEXT: %130 = OpBitcast %27 %61
-; CHECK-NEXT: OpLifetimeStop %130 80
-; CHECK-NEXT: %131 = OpBitcast %27 %62
-; CHECK-NEXT: OpLifetimeStart %131 80
-; CHECK-NEXT: %132 = OpBitcast %13 %116
-; CHECK-NEXT: %133 = OpLoad %12 %132
-; CHECK-NEXT: %134 = OpLoad %12 %56
-; CHECK-NEXT: %135 = OpBuildNDRange %9 %133 %134 %14
-; CHECK-NEXT: OpStore %62 %135
-; CHECK-NEXT: %136 = OpBitcast %27 %62
-; CHECK-NEXT: OpLifetimeStop %136 80
-; CHECK-NEXT: %137 = OpBitcast %27 %63
-; CHECK-NEXT: OpLifetimeStart %137 80
-; CHECK-NEXT: %138 = OpBitcast %13 %116
-; CHECK-NEXT: %139 = OpLoad %12 %138
-; CHECK-NEXT: %140 = OpLoad %12 %56
-; CHECK-NEXT: %141 = OpBitcast %13 %116
-; CHECK-NEXT: %142 = OpLoad %12 %141
-; CHECK-NEXT: %143 = OpBuildNDRange %9 %139 %140 %142
-; CHECK-NEXT: OpStore %63 %143
-; CHECK-NEXT: %144 = OpBitcast %27 %63
-; CHECK-NEXT: OpLifetimeStop %144 80
-; CHECK-NEXT: %145 = OpBitcast %27 %64
-; CHECK-NEXT: OpLifetimeStart %145 24
-; CHECK-NEXT: OpCopyMemorySized %64 %35 %20 Aligned 8
-; CHECK-NEXT: %146 = OpBitcast %27 %65
-; CHECK-NEXT: OpLifetimeStart %146 24
-; CHECK-NEXT: OpCopyMemorySized %65 %37 %20 Aligned 8
-; CHECK-NEXT: %147 = OpBitcast %27 %66
-; CHECK-NEXT: OpLifetimeStart %147 24
-; CHECK-NEXT: OpCopyMemorySized %66 %39 %20 Aligned 8
-; CHECK-NEXT: %148 = OpBitcast %27 %67
-; CHECK-NEXT: OpLifetimeStart %148 80
-; CHECK-NEXT: %149 = OpLoad %8 %64
-; CHECK-NEXT: %150 = OpBuildNDRange %9 %149 %17 %17
-; CHECK-NEXT: OpStore %67 %150
-; CHECK-NEXT: %151 = OpBitcast %27 %67
-; CHECK-NEXT: OpLifetimeStop %151 80
-; CHECK-NEXT: %152 = OpBitcast %27 %68
-; CHECK-NEXT: OpLifetimeStart %152 80
-; CHECK-NEXT: %153 = OpBitcast %15 %64
-; CHECK-NEXT: %154 = OpBitcast %13 %153
-; CHECK-NEXT: %155 = OpLoad %12 %154
-; CHECK-NEXT: %156 = OpBitcast %13 %65
-; CHECK-NEXT: %157 = OpLoad %12 %156
-; CHECK-NEXT: %158 = OpBuildNDRange %9 %155 %157 %14
-; CHECK-NEXT: OpStore %68 %158
-; CHECK-NEXT: %159 = OpBitcast %27 %68
-; CHECK-NEXT: OpLifetimeStop %159 80
-; CHECK-NEXT: %160 = OpBitcast %27 %69
-; CHECK-NEXT: OpLifetimeStart %160 80
-; CHECK-NEXT: %161 = OpBitcast %15 %66
-; CHECK-NEXT: %162 = OpBitcast %13 %153
-; CHECK-NEXT: %163 = OpLoad %12 %162
-; CHECK-NEXT: %164 = OpBitcast %13 %65
-; CHECK-NEXT: %165 = OpLoad %12 %164
-; CHECK-NEXT: %166 = OpBitcast %13 %161
-; CHECK-NEXT: %167 = OpLoad %12 %166
-; CHECK-NEXT: %168 = OpBuildNDRange %9 %163 %165 %167
-; CHECK-NEXT: OpStore %69 %168
-; CHECK-NEXT: %169 = OpBitcast %27 %69
-; CHECK-NEXT: OpLifetimeStop %169 80
-; CHECK-NEXT: %170 = OpBitcast %27 %70
-; CHECK-NEXT: OpLifetimeStart %170 80
-; CHECK-NEXT: %171 = OpBitcast %13 %153
-; CHECK-NEXT: %172 = OpLoad %12 %171
-; CHECK-NEXT: %173 = OpBitcast %13 %64
-; CHECK-NEXT: %174 = OpLoad %12 %173
-; CHECK-NEXT: %175 = OpBuildNDRange %9 %172 %174 %14
-; CHECK-NEXT: OpStore %70 %175
-; CHECK-NEXT: %176 = OpBitcast %27 %70
-; CHECK-NEXT: OpLifetimeStop %176 80
-; CHECK-NEXT: %177 = OpBitcast %27 %71
-; CHECK-NEXT: OpLifetimeStart %177 80
-; CHECK-NEXT: %178 = OpBitcast %13 %153
-; CHECK-NEXT: %179 = OpLoad %12 %178
-; CHECK-NEXT: %180 = OpBitcast %13 %64
-; CHECK-NEXT: %181 = OpLoad %12 %180
-; CHECK-NEXT: %182 = OpBitcast %13 %153
-; CHECK-NEXT: %183 = OpLoad %12 %182
-; CHECK-NEXT: %184 = OpBuildNDRange %9 %179 %181 %183
-; CHECK-NEXT: OpStore %71 %184
-; CHECK-NEXT: %185 = OpBitcast %27 %71
-; CHECK-NEXT: OpLifetimeStop %185 80
-; CHECK-NEXT: %186 = OpBitcast %27 %72
-; CHECK-NEXT: OpLifetimeStart %186 80
-; CHECK-NEXT: %187 = OpBuildNDRange %9 %24 %25 %25
-; CHECK-NEXT: OpStore %72 %187
-; CHECK-NEXT: %188 = OpBitcast %27 %72
-; CHECK-NEXT: OpLifetimeStop %188 80
-; CHECK-NEXT: %189 = OpBitcast %27 %73
-; CHECK-NEXT: OpLifetimeStart %189 80
-; CHECK-NEXT: %190 = OpBuildNDRange %9 %24 %23 %25
-; CHECK-NEXT: OpStore %73 %190
-; CHECK-NEXT: %191 = OpBitcast %27 %73
-; CHECK-NEXT: OpLifetimeStop %191 80
-; CHECK-NEXT: %192 = OpBitcast %27 %74
-; CHECK-NEXT: OpLifetimeStart %192 80
-; CHECK-NEXT: %193 = OpBuildNDRange %9 %24 %23 %22
-; CHECK-NEXT: OpStore %74 %193
-; CHECK-NEXT: %194 = OpBitcast %27 %74
-; CHECK-NEXT: OpLifetimeStop %194 80
-; CHECK-NEXT: %195 = OpBitcast %27 %75
-; CHECK-NEXT: OpLifetimeStart %195 80
-; CHECK-NEXT: %196 = OpBuildNDRange %9 %24 %24 %25
-; CHECK-NEXT: OpStore %75 %196
-; CHECK-NEXT: %197 = OpBitcast %27 %75
-; CHECK-NEXT: OpLifetimeStop %197 80
-; CHECK-NEXT: %198 = OpBitcast %27 %76
-; CHECK-NEXT: OpLifetimeStart %198 80
-; CHECK-NEXT: %199 = OpBuildNDRange %9 %24 %24 %24
-; CHECK-NEXT: OpStore %76 %199
-; CHECK-NEXT: %200 = OpBitcast %27 %76
-; CHECK-NEXT: OpLifetimeStop %200 80
-; CHECK-NEXT: %201 = OpBitcast %27 %77
-; CHECK-NEXT: OpLifetimeStart %201 16
-; CHECK-NEXT: OpCopyMemorySized %77 %40 %21 Aligned 8
-; CHECK-NEXT: %202 = OpBitcast %27 %78
-; CHECK-NEXT: OpLifetimeStart %202 16
-; CHECK-NEXT: OpCopyMemorySized %78 %42 %21 Aligned 8
-; CHECK-NEXT: %203 = OpBitcast %27 %79
-; CHECK-NEXT: OpLifetimeStart %203 16
-; CHECK-NEXT: OpCopyMemorySized %79 %44 %21 Aligned 8
-; CHECK-NEXT: %204 = OpBitcast %27 %80
-; CHECK-NEXT: OpLifetimeStart %204 80
-; CHECK-NEXT: %205 = OpLoad %12 %77
-; CHECK-NEXT: %206 = OpBuildNDRange %9 %205 %14 %14
-; CHECK-NEXT: OpStore %80 %206
-; CHECK-NEXT: %207 = OpBitcast %27 %80
-; CHECK-NEXT: OpLifetimeStop %207 80
-; CHECK-NEXT: %208 = OpBitcast %27 %81
-; CHECK-NEXT: OpLifetimeStart %208 80
-; CHECK-NEXT: %209 = OpBitcast %15 %77
-; CHECK-NEXT: %210 = OpBitcast %13 %209
-; CHECK-NEXT: %211 = OpLoad %12 %210
-; CHECK-NEXT: %212 = OpLoad %12 %78
-; CHECK-NEXT: %213 = OpBuildNDRange %9 %211 %212 %14
-; CHECK-NEXT: OpStore %81 %213
-; CHECK-NEXT: %214 = OpBitcast %27 %81
-; CHECK-NEXT: OpLifetimeStop %214 80
-; CHECK-NEXT: %215 = OpBitcast %27 %82
-; CHECK-NEXT: OpLifetimeStart %215 80
-; CHECK-NEXT: %216 = OpBitcast %15 %79
-; CHECK-NEXT: %217 = OpBitcast %13 %209
-; CHECK-NEXT: %218 = OpLoad %12 %217
-; CHECK-NEXT: %219 = OpLoad %12 %78
-; CHECK-NEXT: %220 = OpBitcast %13 %216
-; CHECK-NEXT: %221 = OpLoad %12 %220
-; CHECK-NEXT: %222 = OpBuildNDRange %9 %218 %219 %221
-; CHECK-NEXT: OpStore %82 %222
-; CHECK-NEXT: %223 = OpBitcast %27 %82
-; CHECK-NEXT: OpLifetimeStop %223 80
-; CHECK-NEXT: %224 = OpBitcast %27 %83
-; CHECK-NEXT: OpLifetimeStart %224 80
-; CHECK-NEXT: %225 = OpBitcast %13 %209
-; CHECK-NEXT: %226 = OpLoad %12 %225
-; CHECK-NEXT: %227 = OpLoad %12 %77
-; CHECK-NEXT: %228 = OpBuildNDRange %9 %226 %227 %14
-; CHECK-NEXT: OpStore %83 %228
-; CHECK-NEXT: %229 = OpBitcast %27 %83
-; CHECK-NEXT: OpLifetimeStop %229 80
-; CHECK-NEXT: %230 = OpBitcast %27 %84
-; CHECK-NEXT: OpLifetimeStart %230 80
-; CHECK-NEXT: %231 = OpBitcast %13 %209
-; CHECK-NEXT: %232 = OpLoad %12 %231
-; CHECK-NEXT: %233 = OpLoad %12 %77
-; CHECK-NEXT: %234 = OpBitcast %13 %209
-; CHECK-NEXT: %235 = OpLoad %12 %234
-; CHECK-NEXT: %236 = OpBuildNDRange %9 %232 %233 %235
-; CHECK-NEXT: OpStore %84 %236
-; CHECK-NEXT: %237 = OpBitcast %27 %84
-; CHECK-NEXT: OpLifetimeStop %237 80
-; CHECK-NEXT: %238 = OpBitcast %27 %85
-; CHECK-NEXT: OpLifetimeStart %238 24
-; CHECK-NEXT: OpCopyMemorySized %85 %45 %20 Aligned 8
-; CHECK-NEXT: %239 = OpBitcast %27 %86
-; CHECK-NEXT: OpLifetimeStart %239 24
-; CHECK-NEXT: OpCopyMemorySized %86 %47 %20 Aligned 8
-; CHECK-NEXT: %240 = OpBitcast %27 %87
-; CHECK-NEXT: OpLifetimeStart %240 24
-; CHECK-NEXT: OpCopyMemorySized %87 %49 %20 Aligned 8
-; CHECK-NEXT: %241 = OpBitcast %27 %88
-; CHECK-NEXT: OpLifetimeStart %241 80
-; CHECK-NEXT: %242 = OpLoad %8 %85
-; CHECK-NEXT: %243 = OpBuildNDRange %9 %242 %17 %17
-; CHECK-NEXT: OpStore %88 %243
-; CHECK-NEXT: %244 = OpBitcast %27 %88
-; CHECK-NEXT: OpLifetimeStop %244 80
-; CHECK-NEXT: %245 = OpBitcast %27 %89
-; CHECK-NEXT: OpLifetimeStart %245 80
-; CHECK-NEXT: %246 = OpBitcast %15 %85
-; CHECK-NEXT: %247 = OpBitcast %13 %246
-; CHECK-NEXT: %248 = OpLoad %12 %247
-; CHECK-NEXT: %249 = OpBitcast %13 %86
-; CHECK-NEXT: %250 = OpLoad %12 %249
-; CHECK-NEXT: %251 = OpBuildNDRange %9 %248 %250 %14
-; CHECK-NEXT: OpStore %89 %251
-; CHECK-NEXT: %252 = OpBitcast %27 %89
-; CHECK-NEXT: OpLifetimeStop %252 80
-; CHECK-NEXT: %253 = OpBitcast %27 %90
-; CHECK-NEXT: OpLifetimeStart %253 80
-; CHECK-NEXT: %254 = OpBitcast %15 %87
-; CHECK-NEXT: %255 = OpBitcast %13 %246
-; CHECK-NEXT: %256 = OpLoad %12 %255
-; CHECK-NEXT: %257 = OpBitcast %13 %86
-; CHECK-NEXT: %258 = OpLoad %12 %257
-; CHECK-NEXT: %259 = OpBitcast %13 %254
-; CHECK-NEXT: %260 = OpLoad %12 %259
-; CHECK-NEXT: %261 = OpBuildNDRange %9 %256 %258 %260
-; CHECK-NEXT: OpStore %90 %261
-; CHECK-NEXT: %262 = OpBitcast %27 %90
-; CHECK-NEXT: OpLifetimeStop %262 80
-; CHECK-NEXT: %263 = OpBitcast %27 %91
-; CHECK-NEXT: OpLifetimeStart %263 80
-; CHECK-NEXT: %264 = OpBitcast %13 %246
-; CHECK-NEXT: %265 = OpLoad %12 %264
-; CHECK-NEXT: %266 = OpBitcast %13 %85
-; CHECK-NEXT: %267 = OpLoad %12 %266
-; CHECK-NEXT: %268 = OpBuildNDRange %9 %265 %267 %14
-; CHECK-NEXT: OpStore %91 %268
-; CHECK-NEXT: %269 = OpBitcast %27 %91
-; CHECK-NEXT: OpLifetimeStop %269 80
-; CHECK-NEXT: %270 = OpBitcast %27 %92
-; CHECK-NEXT: OpLifetimeStart %270 80
-; CHECK-NEXT: %271 = OpBitcast %13 %246
-; CHECK-NEXT: %272 = OpLoad %12 %271
-; CHECK-NEXT: %273 = OpBitcast %13 %85
-; CHECK-NEXT: %274 = OpLoad %12 %273
-; CHECK-NEXT: %275 = OpBitcast %13 %246
-; CHECK-NEXT: %276 = OpLoad %12 %275
-; CHECK-NEXT: %277 = OpBuildNDRange %9 %272 %274 %276
-; CHECK-NEXT: OpStore %92 %277
-; CHECK-NEXT: %278 = OpBitcast %27 %92
-; CHECK-NEXT: OpLifetimeStop %278 80
-; CHECK-NEXT: %279 = OpBitcast %27 %87
-; CHECK-NEXT: OpLifetimeStop %279 24
-; CHECK-NEXT: %280 = OpBitcast %27 %86
-; CHECK-NEXT: OpLifetimeStop %280 24
-; CHECK-NEXT: %281 = OpBitcast %27 %85
-; CHECK-NEXT: OpLifetimeStop %281 24
-; CHECK-NEXT: %282 = OpBitcast %27 %79
-; CHECK-NEXT: OpLifetimeStop %282 16
-; CHECK-NEXT: %283 = OpBitcast %27 %78
-; CHECK-NEXT: OpLifetimeStop %283 16
-; CHECK-NEXT: %284 = OpBitcast %27 %77
-; CHECK-NEXT: OpLifetimeStop %284 16
-; CHECK-NEXT: %285 = OpBitcast %27 %66
-; CHECK-NEXT: OpLifetimeStop %285 24
-; CHECK-NEXT: %286 = OpBitcast %27 %65
-; CHECK-NEXT: OpLifetimeStop %286 24
-; CHECK-NEXT: %287 = OpBitcast %27 %64
-; CHECK-NEXT: OpLifetimeStop %287 24
-; CHECK-NEXT: %288 = OpBitcast %27 %58
-; CHECK-NEXT: OpLifetimeStop %288 16
-; CHECK-NEXT: %289 = OpBitcast %27 %57
-; CHECK-NEXT: OpLifetimeStop %289 16
-; CHECK-NEXT: %290 = OpBitcast %27 %56
-; CHECK-NEXT: OpLifetimeStop %290 16
+; CHECK: %[[#r50:]] = OpFunction %[[#r3:]] None %[[#r4:]] ; -- Begin function test_ndrange_2D3D
+; CHECK-NEXT: %[[#r2:]] = OpLabel
+; CHECK-NEXT: %[[#r51:]] = OpVariable %[[#r10:]] Function
+; CHECK-NEXT: %[[#r52:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r53:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r54:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r55:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r56:]] = OpVariable %[[#r13:]] Function
+; CHECK-NEXT: %[[#r57:]] = OpVariable %[[#r13]] Function
+; CHECK-NEXT: %[[#r58:]] = OpVariable %[[#r13]] Function
+; CHECK-NEXT: %[[#r59:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r60:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r61:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r62:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r63:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r64:]] = OpVariable %[[#r16:]] Function
+; CHECK-NEXT: %[[#r65:]] = OpVariable %[[#r16]] Function
+; CHECK-NEXT: %[[#r66:]] = OpVariable %[[#r16]] Function
+; CHECK-NEXT: %[[#r67:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r68:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r69:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r70:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r71:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r72:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r73:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r74:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r75:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r76:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r77:]] = OpVariable %[[#r13]] Function
+; CHECK-NEXT: %[[#r78:]] = OpVariable %[[#r13]] Function
+; CHECK-NEXT: %[[#r79:]] = OpVariable %[[#r13]] Function
+; CHECK-NEXT: %[[#r80:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r81:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r82:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r83:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r84:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r85:]] = OpVariable %[[#r16]] Function
+; CHECK-NEXT: %[[#r86:]] = OpVariable %[[#r16]] Function
+; CHECK-NEXT: %[[#r87:]] = OpVariable %[[#r16]] Function
+; CHECK-NEXT: %[[#r88:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r89:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r90:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r91:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r92:]] = OpVariable %[[#r10]] Function
+; CHECK-NEXT: %[[#r93:]] = OpBitcast %[[#r27:]] %[[#r51]]
+; CHECK-NEXT: OpLifetimeStart %[[#r93]] 80
+; CHECK-NEXT: %[[#r94:]] = OpBuildNDRange %[[#r9:]] %[[#r24:]] %[[#r25:]] %[[#r25:]]
+; CHECK-NEXT: OpStore %[[#r51]] %[[#r94]]
+; CHECK-NEXT: %[[#r95:]] = OpBitcast %[[#r27:]] %[[#r51]]
+; CHECK-NEXT: OpLifetimeStop %[[#r95]] 80
+; CHECK-NEXT: %[[#r96:]] = OpBitcast %[[#r27]] %[[#r52]]
+; CHECK-NEXT: OpLifetimeStart %[[#r96]] 80
+; CHECK-NEXT: %[[#r97:]] = OpBuildNDRange %[[#r9]] %[[#r24:]] %[[#r23:]] %[[#r25]]
+; CHECK-NEXT: OpStore %[[#r52]] %[[#r97]]
+; CHECK-NEXT: %[[#r98:]] = OpBitcast %[[#r27]] %[[#r52]]
+; CHECK-NEXT: OpLifetimeStop %[[#r98]] 80
+; CHECK-NEXT: %[[#r99:]] = OpBitcast %[[#r27]] %[[#r53]]
+; CHECK-NEXT: OpLifetimeStart %[[#r99]] 80
+; CHECK-NEXT: %[[#r100:]] = OpBuildNDRange %[[#r9]] %[[#r24]] %[[#r23:]] %[[#r22:]]
+; CHECK-NEXT: OpStore %[[#r53]] %[[#r100]]
+; CHECK-NEXT: %[[#r101:]] = OpBitcast %[[#r27]] %[[#r53]]
+; CHECK-NEXT: OpLifetimeStop %[[#r101]] 80
+; CHECK-NEXT: %[[#r102:]] = OpBitcast %[[#r27]] %[[#r54]]
+; CHECK-NEXT: OpLifetimeStart %[[#r102]] 80
+; CHECK-NEXT: %[[#r103:]] = OpBuildNDRange %[[#r9]] %[[#r24]] %[[#r24]] %[[#r25]]
+; CHECK-NEXT: OpStore %[[#r54]] %[[#r103]]
+; CHECK-NEXT: %[[#r104:]] = OpBitcast %[[#r27]] %[[#r54]]
+; CHECK-NEXT: OpLifetimeStop %[[#r104]] 80
+; CHECK-NEXT: %[[#r105:]] = OpBitcast %[[#r27]] %[[#r55]]
+; CHECK-NEXT: OpLifetimeStart %[[#r105]] 80
+; CHECK-NEXT: %[[#r106:]] = OpBuildNDRange %[[#r9]] %[[#r24]] %[[#r24]] %[[#r24]]
+; CHECK-NEXT: OpStore %[[#r55]] %[[#r106]]
+; CHECK-NEXT: %[[#r107:]] = OpBitcast %[[#r27]] %[[#r55]]
+; CHECK-NEXT: OpLifetimeStop %[[#r107]] 80
+; CHECK-NEXT: %[[#r108:]] = OpBitcast %[[#r27]] %[[#r56]]
+; CHECK-NEXT: OpLifetimeStart %[[#r108]] 16
+; CHECK-NEXT: OpCopyMemorySized %[[#r56]] %[[#r29:]] %[[#r21:]] Aligned 8
+; CHECK-NEXT: %[[#r109:]] = OpBitcast %[[#r27]] %[[#r57]]
+; CHECK-NEXT: OpLifetimeStart %[[#r109]] 16
+; CHECK-NEXT: OpCopyMemorySized %[[#r57]] %[[#r31:]] %[[#r21]] Aligned 8
+; CHECK-NEXT: %[[#r110:]] = OpBitcast %[[#r27]] %[[#r58]]
+; CHECK-NEXT: OpLifetimeStart %[[#r110]] 16
+; CHECK-NEXT: OpCopyMemorySized %[[#r58]] %[[#r33:]] %[[#r21]] Aligned 8
+; CHECK-NEXT: %[[#r111:]] = OpBitcast %[[#r27]] %[[#r59]]
+; CHECK-NEXT: OpLifetimeStart %[[#r111]] 80
+; CHECK-NEXT: %[[#r112:]] = OpLoad %[[#r12:]] %[[#r56]]
+; CHECK-NEXT: %[[#r113:]] = OpBuildNDRange %[[#r9]] %[[#r112]] %[[#r14:]] %[[#r14:]]
+; CHECK-NEXT: OpStore %[[#r59]] %[[#r113]]
+; CHECK-NEXT: %[[#r114:]] = OpBitcast %[[#r27]] %[[#r59]]
+; CHECK-NEXT: OpLifetimeStop %[[#r114]] 80
+; CHECK-NEXT: %[[#r115:]] = OpBitcast %[[#r27]] %[[#r60]]
+; CHECK-NEXT: OpLifetimeStart %[[#r115]] 80
+; CHECK-NEXT: %[[#r116:]] = OpBitcast %[[#r15:]] %[[#r56]]
+; CHECK-NEXT: %[[#r117:]] = OpBitcast %[[#r13]] %[[#r116]]
+; CHECK-NEXT: %[[#r118:]] = OpLoad %[[#r12]] %[[#r117]]
+; CHECK-NEXT: %[[#r119:]] = OpLoad %[[#r12]] %[[#r57]]
+; CHECK-NEXT: %[[#r120:]] = OpBuildNDRange %[[#r9]] %[[#r118]] %[[#r119]] %[[#r14]]
+; CHECK-NEXT: OpStore %[[#r60]] %[[#r120]]
+; CHECK-NEXT: %[[#r121:]] = OpBitcast %[[#r27]] %[[#r60]]
+; CHECK-NEXT: OpLifetimeStop %[[#r121]] 80
+; CHECK-NEXT: %[[#r122:]] = OpBitcast %[[#r27]] %[[#r61]]
+; CHECK-NEXT: OpLifetimeStart %[[#r122]] 80
+; CHECK-NEXT: %[[#r123:]] = OpBitcast %[[#r15]] %[[#r58]]
+; CHECK-NEXT: %[[#r124:]] = OpBitcast %[[#r13]] %[[#r116]]
+; CHECK-NEXT: %[[#r125:]] = OpLoad %[[#r12]] %[[#r124]]
+; CHECK-NEXT: %[[#r126:]] = OpLoad %[[#r12]] %[[#r57]]
+; CHECK-NEXT: %[[#r127:]] = OpBitcast %[[#r13]] %[[#r123]]
+; CHECK-NEXT: %[[#r128:]] = OpLoad %[[#r12]] %[[#r127]]
+; CHECK-NEXT: %[[#r129:]] = OpBuildNDRange %[[#r9]] %[[#r125]] %[[#r126]] %[[#r128]]
+; CHECK-NEXT: OpStore %[[#r61]] %[[#r129]]
+; CHECK-NEXT: %[[#r130:]] = OpBitcast %[[#r27]] %[[#r61]]
+; CHECK-NEXT: OpLifetimeStop %[[#r130]] 80
+; CHECK-NEXT: %[[#r131:]] = OpBitcast %[[#r27]] %[[#r62]]
+; CHECK-NEXT: OpLifetimeStart %[[#r131]] 80
+; CHECK-NEXT: %[[#r132:]] = OpBitcast %[[#r13]] %[[#r116]]
+; CHECK-NEXT: %[[#r133:]] = OpLoad %[[#r12]] %[[#r132]]
+; CHECK-NEXT: %[[#r134:]] = OpLoad %[[#r12]] %[[#r56]]
+; CHECK-NEXT: %[[#r135:]] = OpBuildNDRange %[[#r9]] %[[#r133]] %[[#r134]] %[[#r14]]
+; CHECK-NEXT: OpStore %[[#r62]] %[[#r135]]
+; CHECK-NEXT: %[[#r136:]] = OpBitcast %[[#r27]] %[[#r62]]
+; CHECK-NEXT: OpLifetimeStop %[[#r136]] 80
+; CHECK-NEXT: %[[#r137:]] = OpBitcast %[[#r27]] %[[#r63]]
+; CHECK-NEXT: OpLifetimeStart %[[#r137]] 80
+; CHECK-NEXT: %[[#r138:]] = OpBitcast %[[#r13]] %[[#r116]]
+; CHECK-NEXT: %[[#r139:]] = OpLoad %[[#r12]] %[[#r138]]
+; CHECK-NEXT: %[[#r140:]] = OpLoad %[[#r12]] %[[#r56]]
+; CHECK-NEXT: %[[#r141:]] = OpBitcast %[[#r13]] %[[#r116]]
+; CHECK-NEXT: %[[#r142:]] = OpLoad %[[#r12]] %[[#r141]]
+; CHECK-NEXT: %[[#r143:]] = OpBuildNDRange %[[#r9]] %[[#r139]] %[[#r140]] %[[#r142]]
+; CHECK-NEXT: OpStore %[[#r63]] %[[#r143]]
+; CHECK-NEXT: %[[#r144:]] = OpBitcast %[[#r27]] %[[#r63]]
+; CHECK-NEXT: OpLifetimeStop %[[#r144]] 80
+; CHECK-NEXT: %[[#r145:]] = OpBitcast %[[#r27]] %[[#r64]]
+; CHECK-NEXT: OpLifetimeStart %[[#r145]] 24
+; CHECK-NEXT: OpCopyMemorySized %[[#r64]] %[[#r35:]] %[[#r20:]] Aligned 8
+; CHECK-NEXT: %[[#r146:]] = OpBitcast %[[#r27]] %[[#r65]]
+; CHECK-NEXT: OpLifetimeStart %[[#r146]] 24
+; CHECK-NEXT: OpCopyMemorySized %[[#r65]] %[[#r37:]] %[[#r20]] Aligned 8
+; CHECK-NEXT: %[[#r147:]] = OpBitcast %[[#r27]] %[[#r66]]
+; CHECK-NEXT: OpLifetimeStart %[[#r147]] 24
+; CHECK-NEXT: OpCopyMemorySized %[[#r66]] %[[#r39:]] %[[#r20]] Aligned 8
+; CHECK-NEXT: %[[#r148:]] = OpBitcast %[[#r27]] %[[#r67]]
+; CHECK-NEXT: OpLifetimeStart %[[#r148]] 80
+; CHECK-NEXT: %[[#r149:]] = OpLoad %[[#r8:]] %[[#r64]]
+; CHECK-NEXT: %[[#r150:]] = OpBuildNDRange %[[#r9]] %[[#r149]] %[[#r17:]] %[[#r17:]]
+; CHECK-NEXT: OpStore %[[#r67]] %[[#r150]]
+; CHECK-NEXT: %[[#r151:]] = OpBitcast %[[#r27]] %[[#r67]]
+; CHECK-NEXT: OpLifetimeStop %[[#r151]] 80
+; CHECK-NEXT: %[[#r152:]] = OpBitcast %[[#r27]] %[[#r68]]
+; CHECK-NEXT: OpLifetimeStart %[[#r152]] 80
+; CHECK-NEXT: %[[#r153:]] = OpBitcast %[[#r15]] %[[#r64]]
+; CHECK-NEXT: %[[#r154:]] = OpBitcast %[[#r13]] %[[#r153]]
+; CHECK-NEXT: %[[#r155:]] = OpLoad %[[#r12]] %[[#r154]]
+; CHECK-NEXT: %[[#r156:]] = OpBitcast %[[#r13]] %[[#r65]]
+; CHECK-NEXT: %[[#r157:]] = OpLoad %[[#r12]] %[[#r156]]
+; CHECK-NEXT: %[[#r158:]] = OpBuildNDRange %[[#r9]] %[[#r155]] %[[#r157]] %[[#r14]]
+; CHECK-NEXT: OpStore %[[#r68]] %[[#r158]]
+; CHECK-NEXT: %[[#r159:]] = OpBitcast %[[#r27]] %[[#r68]]
+; CHECK-NEXT: OpLifetimeStop %[[#r159]] 80
+; CHECK-NEXT: %[[#r160:]] = OpBitcast %[[#r27]] %[[#r69]]
+; CHECK-NEXT: OpLifetimeStart %[[#r160]] 80
+; CHECK-NEXT: %[[#r161:]] = OpBitcast %[[#r15]] %[[#r66]]
+; CHECK-NEXT: %[[#r162:]] = OpBitcast %[[#r13]] %[[#r153]]
+; CHECK-NEXT: %[[#r163:]] = OpLoad %[[#r12]] %[[#r162]]
+; CHECK-NEXT: %[[#r164:]] = OpBitcast %[[#r13]] %[[#r65]]
+; CHECK-NEXT: %[[#r165:]] = OpLoad %[[#r12]] %[[#r164]]
+; CHECK-NEXT: %[[#r166:]] = OpBitcast %[[#r13]] %[[#r161]]
+; CHECK-NEXT: %[[#r167:]] = OpLoad %[[#r12]] %[[#r166]]
+; CHECK-NEXT: %[[#r168:]] = OpBuildNDRange %[[#r9]] %[[#r163]] %[[#r165]] %[[#r167]]
+; CHECK-NEXT: OpStore %[[#r69]] %[[#r168]]
+; CHECK-NEXT: %[[#r169:]] = OpBitcast %[[#r27]] %[[#r69]]
+; CHECK-NEXT: OpLifetimeStop %[[#r169]] 80
+; CHECK-NEXT: %[[#r170:]] = OpBitcast %[[#r27]] %[[#r70]]
+; CHECK-NEXT: OpLifetimeStart %[[#r170]] 80
+; CHECK-NEXT: %[[#r171:]] = OpBitcast %[[#r13]] %[[#r153]]
+; CHECK-NEXT: %[[#r172:]] = OpLoad %[[#r12]] %[[#r171]]
+; CHECK-NEXT: %[[#r173:]] = OpBitcast %[[#r13]] %[[#r64]]
+; CHECK-NEXT: %[[#r174:]] = OpLoad %[[#r12]] %[[#r173]]
+; CHECK-NEXT: %[[#r175:]] = OpBuildNDRange %[[#r9]] %[[#r172]] %[[#r174]] %[[#r14]]
+; CHECK-NEXT: OpStore %[[#r70]] %[[#r175]]
+; CHECK-NEXT: %[[#r176:]] = OpBitcast %[[#r27]] %[[#r70]]
+; CHECK-NEXT: OpLifetimeStop %[[#r176]] 80
+; CHECK-NEXT: %[[#r177:]] = OpBitcast %[[#r27]] %[[#r71]]
+; CHECK-NEXT: OpLifetimeStart %[[#r177]] 80
+; CHECK-NEXT: %[[#r178:]] = OpBitcast %[[#r13]] %[[#r153]]
+; CHECK-NEXT: %[[#r179:]] = OpLoad %[[#r12]] %[[#r178]]
+; CHECK-NEXT: %[[#r180:]] = OpBitcast %[[#r13]] %[[#r64]]
+; CHECK-NEXT: %[[#r181:]] = OpLoad %[[#r12]] %[[#r180]]
+; CHECK-NEXT: %[[#r182:]] = OpBitcast %[[#r13]] %[[#r153]]
+; CHECK-NEXT: %[[#r183:]] = OpLoad %[[#r12]] %[[#r182]]
+; CHECK-NEXT: %[[#r184:]] = OpBuildNDRange %[[#r9]] %[[#r179]] %[[#r181]] %[[#r183]]
+; CHECK-NEXT: OpStore %[[#r71]] %[[#r184]]
+; CHECK-NEXT: %[[#r185:]] = OpBitcast %[[#r27]] %[[#r71]]
+; CHECK-NEXT: OpLifetimeStop %[[#r185]] 80
+; CHECK-NEXT: %[[#r186:]] = OpBitcast %[[#r27]] %[[#r72]]
+; CHECK-NEXT: OpLifetimeStart %[[#r186]] 80
+; CHECK-NEXT: %[[#r187:]] = OpBuildNDRange %[[#r9]] %[[#r24]] %[[#r25]] %[[#r25]]
+; CHECK-NEXT: OpStore %[[#r72]] %[[#r187]]
+; CHECK-NEXT: %[[#r188:]] = OpBitcast %[[#r27]] %[[#r72]]
+; CHECK-NEXT: OpLifetimeStop %[[#r188]] 80
+; CHECK-NEXT: %[[#r189:]] = OpBitcast %[[#r27]] %[[#r73]]
+; CHECK-NEXT: OpLifetimeStart %[[#r189]] 80
+; CHECK-NEXT: %[[#r190:]] = OpBuildNDRange %[[#r9]] %[[#r24]] %[[#r23]] %[[#r25]]
+; CHECK-NEXT: OpStore %[[#r73]] %[[#r190]]
+; CHECK-NEXT: %[[#r191:]] = OpBitcast %[[#r27]] %[[#r73]]
+; CHECK-NEXT: OpLifetimeStop %[[#r191]] 80
+; CHECK-NEXT: %[[#r192:]] = OpBitcast %[[#r27]] %[[#r74]]
+; CHECK-NEXT: OpLifetimeStart %[[#r192]] 80
+; CHECK-NEXT: %[[#r193:]] = OpBuildNDRange %[[#r9]] %[[#r24]] %[[#r23]] %[[#r22]]
+; CHECK-NEXT: OpStore %[[#r74]] %[[#r193]]
+; CHECK-NEXT: %[[#r194:]] = OpBitcast %[[#r27]] %[[#r74]]
+; CHECK-NEXT: OpLifetimeStop %[[#r194]] 80
+; CHECK-NEXT: %[[#r195:]] = OpBitcast %[[#r27]] %[[#r75]]
+; CHECK-NEXT: OpLifetimeStart %[[#r195]] 80
+; CHECK-NEXT: %[[#r196:]] = OpBuildNDRange %[[#r9]] %[[#r24]] %[[#r24]] %[[#r25]]
+; CHECK-NEXT: OpStore %[[#r75]] %[[#r196]]
+; CHECK-NEXT: %[[#r197:]] = OpBitcast %[[#r27]] %[[#r75]]
+; CHECK-NEXT: OpLifetimeStop %[[#r197]] 80
+; CHECK-NEXT: %[[#r198:]] = OpBitcast %[[#r27]] %[[#r76]]
+; CHECK-NEXT: OpLifetimeStart %[[#r198]] 80
+; CHECK-NEXT: %[[#r199:]] = OpBuildNDRange %[[#r9]] %[[#r24]] %[[#r24]] %[[#r24]]
+; CHECK-NEXT: OpStore %[[#r76]] %[[#r199]]
+; CHECK-NEXT: %[[#r200:]] = OpBitcast %[[#r27]] %[[#r76]]
+; CHECK-NEXT: OpLifetimeStop %[[#r200]] 80
+; CHECK-NEXT: %[[#r201:]] = OpBitcast %[[#r27]] %[[#r77]]
+; CHECK-NEXT: OpLifetimeStart %[[#r201]] 16
+; CHECK-NEXT: OpCopyMemorySized %[[#r77]] %[[#r40:]] %[[#r21:]] Aligned 8
+; CHECK-NEXT: %[[#r202:]] = OpBitcast %[[#r27]] %[[#r78]]
+; CHECK-NEXT: OpLifetimeStart %[[#r202]] 16
+; CHECK-NEXT: OpCopyMemorySized %[[#r78]] %[[#r42:]] %[[#r21]] Aligned 8
+; CHECK-NEXT: %[[#r203:]] = OpBitcast %[[#r27]] %[[#r79]]
+; CHECK-NEXT: OpLifetimeStart %[[#r203]] 16
+; CHECK-NEXT: OpCopyMemorySized %[[#r79]] %[[#r44:]] %[[#r21]] Aligned 8
+; CHECK-NEXT: %[[#r204:]] = OpBitcast %[[#r27]] %[[#r80]]
+; CHECK-NEXT: OpLifetimeStart %[[#r204]] 80
+; CHECK-NEXT: %[[#r205:]] = OpLoad %[[#r12]] %[[#r77]]
+; CHECK-NEXT: %[[#r206:]] = OpBuildNDRange %[[#r9]] %[[#r205]] %[[#r14]] %[[#r14]]
+; CHECK-NEXT: OpStore %[[#r80]] %[[#r206]]
+; CHECK-NEXT: %[[#r207:]] = OpBitcast %[[#r27]] %[[#r80]]
+; CHECK-NEXT: OpLifetimeStop %[[#r207]] 80
+; CHECK-NEXT: %[[#r208:]] = OpBitcast %[[#r27]] %[[#r81]]
+; CHECK-NEXT: OpLifetimeStart %[[#r208]] 80
+; CHECK-NEXT: %[[#r209:]] = OpBitcast %[[#r15]] %[[#r77]]
+; CHECK-NEXT: %[[#r210:]] = OpBitcast %[[#r13]] %[[#r209]]
+; CHECK-NEXT: %[[#r211:]] = OpLoad %[[#r12]] %[[#r210]]
+; CHECK-NEXT: %[[#r212:]] = OpLoad %[[#r12]] %[[#r78]]
+; CHECK-NEXT: %[[#r213:]] = OpBuildNDRange %[[#r9]] %[[#r211]] %[[#r212]] %[[#r14]]
+; CHECK-NEXT: OpStore %[[#r81]] %[[#r213]]
+; CHECK-NEXT: %[[#r214:]] = OpBitcast %[[#r27]] %[[#r81]]
+; CHECK-NEXT: OpLifetimeStop %[[#r214]] 80
+; CHECK-NEXT: %[[#r215:]] = OpBitcast %[[#r27]] %[[#r82]]
+; CHECK-NEXT: OpLifetimeStart %[[#r215]] 80
+; CHECK-NEXT: %[[#r216:]] = OpBitcast %[[#r15]] %[[#r79]]
+; CHECK-NEXT: %[[#r217:]] = OpBitcast %[[#r13]] %[[#r209]]
+; CHECK-NEXT: %[[#r218:]] = OpLoad %[[#r12]] %[[#r217]]
+; CHECK-NEXT: %[[#r219:]] = OpLoad %[[#r12]] %[[#r78]]
+; CHECK-NEXT: %[[#r220:]] = OpBitcast %[[#r13]] %[[#r216]]
+; CHECK-NEXT: %[[#r221:]] = OpLoad %[[#r12]] %[[#r220]]
+; CHECK-NEXT: %[[#r222:]] = OpBuildNDRange %[[#r9]] %[[#r218]] %[[#r219]] %[[#r221]]
+; CHECK-NEXT: OpStore %[[#r82]] %[[#r222]]
+; CHECK-NEXT: %[[#r223:]] = OpBitcast %[[#r27]] %[[#r82]]
+; CHECK-NEXT: OpLifetimeStop %[[#r223]] 80
+; CHECK-NEXT: %[[#r224:]] = OpBitcast %[[#r27]] %[[#r83]]
+; CHECK-NEXT: OpLifetimeStart %[[#r224]] 80
+; CHECK-NEXT: %[[#r225:]] = OpBitcast %[[#r13]] %[[#r209]]
+; CHECK-NEXT: %[[#r226:]] = OpLoad %[[#r12]] %[[#r225]]
+; CHECK-NEXT: %[[#r227:]] = OpLoad %[[#r12]] %[[#r77]]
+; CHECK-NEXT: %[[#r228:]] = OpBuildNDRange %[[#r9]] %[[#r226]] %[[#r227]] %[[#r14]]
+; CHECK-NEXT: OpStore %[[#r83]] %[[#r228]]
+; CHECK-NEXT: %[[#r229:]] = OpBitcast %[[#r27]] %[[#r83]]
+; CHECK-NEXT: OpLifetimeStop %[[#r229]] 80
+; CHECK-NEXT: %[[#r230:]] = OpBitcast %[[#r27]] %[[#r84]]
+; CHECK-NEXT: OpLifetimeStart %[[#r230]] 80
+; CHECK-NEXT: %[[#r231:]] = OpBitcast %[[#r13]] %[[#r209]]
+; CHECK-NEXT: %[[#r232:]] = OpLoad %[[#r12]] %[[#r231]]
+; CHECK-NEXT: %[[#r233:]] = OpLoad %[[#r12]] %[[#r77]]
+; CHECK-NEXT: %[[#r234:]] = OpBitcast %[[#r13]] %[[#r209]]
+; CHECK-NEXT: %[[#r235:]] = OpLoad %[[#r12]] %[[#r234]]
+; CHECK-NEXT: %[[#r236:]] = OpBuildNDRange %[[#r9]] %[[#r232]] %[[#r233]] %[[#r235]]
+; CHECK-NEXT: OpStore %[[#r84]] %[[#r236]]
+; CHECK-NEXT: %[[#r237:]] = OpBitcast %[[#r27]] %[[#r84]]
+; CHECK-NEXT: OpLifetimeStop %[[#r237]] 80
+; CHECK-NEXT: %[[#r238:]] = OpBitcast %[[#r27]] %[[#r85]]
+; CHECK-NEXT: OpLifetimeStart %[[#r238]] 24
+; CHECK-NEXT: OpCopyMemorySized %[[#r85]] %[[#r45:]] %[[#r20]] Aligned 8
+; CHECK-NEXT: %[[#r239:]] = OpBitcast %[[#r27]] %[[#r86]]
+; CHECK-NEXT: OpLifetimeStart %[[#r239]] 24
+; CHECK-NEXT: OpCopyMemorySized %[[#r86]] %[[#r47:]] %[[#r20]] Aligned 8
+; CHECK-NEXT: %[[#r240:]] = OpBitcast %[[#r27]] %[[#r87]]
+; CHECK-NEXT: OpLifetimeStart %[[#r240]] 24
+; CHECK-NEXT: OpCopyMemorySized %[[#r87]] %[[#r49:]] %[[#r20]] Aligned 8
+; CHECK-NEXT: %[[#r241:]] = OpBitcast %[[#r27]] %[[#r88]]
+; CHECK-NEXT: OpLifetimeStart %[[#r241]] 80
+; CHECK-NEXT: %[[#r242:]] = OpLoad %[[#r8]] %[[#r85]]
+; CHECK-NEXT: %[[#r243:]] = OpBuildNDRange %[[#r9]] %[[#r242]] %[[#r17]] %[[#r17]]
+; CHECK-NEXT: OpStore %[[#r88]] %[[#r243]]
+; CHECK-NEXT: %[[#r244:]] = OpBitcast %[[#r27]] %[[#r88]]
+; CHECK-NEXT: OpLifetimeStop %[[#r244]] 80
+; CHECK-NEXT: %[[#r245:]] = OpBitcast %[[#r27]] %[[#r89]]
+; CHECK-NEXT: OpLifetimeStart %[[#r245]] 80
+; CHECK-NEXT: %[[#r246:]] = OpBitcast %[[#r15]] %[[#r85]]
+; CHECK-NEXT: %[[#r247:]] = OpBitcast %[[#r13]] %[[#r246]]
+; CHECK-NEXT: %[[#r248:]] = OpLoad %[[#r12]] %[[#r247]]
+; CHECK-NEXT: %[[#r249:]] = OpBitcast %[[#r13]] %[[#r86]]
+; CHECK-NEXT: %[[#r250:]] = OpLoad %[[#r12]] %[[#r249]]
+; CHECK-NEXT: %[[#r251:]] = OpBuildNDRange %[[#r9]] %[[#r248]] %[[#r250]] %[[#r14]]
+; CHECK-NEXT: OpStore %[[#r89]] %[[#r251]]
+; CHECK-NEXT: %[[#r252:]] = OpBitcast %[[#r27]] %[[#r89]]
+; CHECK-NEXT: OpLifetimeStop %[[#r252]] 80
+; CHECK-NEXT: %[[#r253:]] = OpBitcast %[[#r27]] %[[#r90]]
+; CHECK-NEXT: OpLifetimeStart %[[#r253]] 80
+; CHECK-NEXT: %[[#r254:]] = OpBitcast %[[#r15]] %[[#r87]]
+; CHECK-NEXT: %[[#r255:]] = OpBitcast %[[#r13]] %[[#r246]]
+; CHECK-NEXT: %[[#r256:]] = OpLoad %[[#r12]] %[[#r255]]
+; CHECK-NEXT: %[[#r257:]] = OpBitcast %[[#r13]] %[[#r86]]
+; CHECK-NEXT: %[[#r258:]] = OpLoad %[[#r12]] %[[#r257]]
+; CHECK-NEXT: %[[#r259:]] = OpBitcast %[[#r13]] %[[#r254]]
+; CHECK-NEXT: %[[#r260:]] = OpLoad %[[#r12]] %[[#r259]]
+; CHECK-NEXT: %[[#r261:]] = OpBuildNDRange %[[#r9]] %[[#r256]] %[[#r258]] %[[#r260]]
+; CHECK-NEXT: OpStore %[[#r90]] %[[#r261]]
+; CHECK-NEXT: %[[#r262:]] = OpBitcast %[[#r27]] %[[#r90]]
+; CHECK-NEXT: OpLifetimeStop %[[#r262]] 80
+; CHECK-NEXT: %[[#r263:]] = OpBitcast %[[#r27]] %[[#r91]]
+; CHECK-NEXT: OpLifetimeStart %[[#r263]] 80
+; CHECK-NEXT: %[[#r264:]] = OpBitcast %[[#r13]] %[[#r246]]
+; CHECK-NEXT: %[[#r265:]] = OpLoad %[[#r12]] %[[#r264]]
+; CHECK-NEXT: %[[#r266:]] = OpBitcast %[[#r13]] %[[#r85]]
+; CHECK-NEXT: %[[#r267:]] = OpLoad %[[#r12]] %[[#r266]]
+; CHECK-NEXT: %[[#r268:]] = OpBuildNDRange %[[#r9]] %[[#r265]] %[[#r267]] %[[#r14]]
+; CHECK-NEXT: OpStore %[[#r91]] %[[#r268]]
+; CHECK-NEXT: %[[#r269:]] = OpBitcast %[[#r27]] %[[#r91]]
+; CHECK-NEXT: OpLifetimeStop %[[#r269]] 80
+; CHECK-NEXT: %[[#r270:]] = OpBitcast %[[#r27]] %[[#r92]]
+; CHECK-NEXT: OpLifetimeStart %[[#r270]] 80
+; CHECK-NEXT: %[[#r271:]] = OpBitcast %[[#r13]] %[[#r246]]
+; CHECK-NEXT: %[[#r272:]] = OpLoad %[[#r12]] %[[#r271]]
+; CHECK-NEXT: %[[#r273:]] = OpBitcast %[[#r13]] %[[#r85]]
+; CHECK-NEXT: %[[#r274:]] = OpLoad %[[#r12]] %[[#r273]]
+; CHECK-NEXT: %[[#r275:]] = OpBitcast %[[#r13]] %[[#r246]]
+; CHECK-NEXT: %[[#r276:]] = OpLoad %[[#r12]] %[[#r275]]
+; CHECK-NEXT: %[[#r277:]] = OpBuildNDRange %[[#r9]] %[[#r272]] %[[#r274]] %[[#r276]]
+; CHECK-NEXT: OpStore %[[#r92]] %[[#r277]]
+; CHECK-NEXT: %[[#r278:]] = OpBitcast %[[#r27]] %[[#r92]]
+; CHECK-NEXT: OpLifetimeStop %[[#r278]] 80
+; CHECK-NEXT: %[[#r279:]] = OpBitcast %[[#r27]] %[[#r87]]
+; CHECK-NEXT: OpLifetimeStop %[[#r279]] 24
+; CHECK-NEXT: %[[#r280:]] = OpBitcast %[[#r27]] %[[#r86]]
+; CHECK-NEXT: OpLifetimeStop %[[#r280]] 24
+; CHECK-NEXT: %[[#r281:]] = OpBitcast %[[#r27]] %[[#r85]]
+; CHECK-NEXT: OpLifetimeStop %[[#r281]] 24
+; CHECK-NEXT: %[[#r282:]] = OpBitcast %[[#r27]] %[[#r79]]
+; CHECK-NEXT: OpLifetimeStop %[[#r282]] 16
+; CHECK-NEXT: %[[#r283:]] = OpBitcast %[[#r27]] %[[#r78]]
+; CHECK-NEXT: OpLifetimeStop %[[#r283]] 16
+; CHECK-NEXT: %[[#r284:]] = OpBitcast %[[#r27]] %[[#r77]]
+; CHECK-NEXT: OpLifetimeStop %[[#r284]] 16
+; CHECK-NEXT: %[[#r285:]] = OpBitcast %[[#r27]] %[[#r66]]
+; CHECK-NEXT: OpLifetimeStop %[[#r285]] 24
+; CHECK-NEXT: %[[#r286:]] = OpBitcast %[[#r27]] %[[#r65]]
+; CHECK-NEXT: OpLifetimeStop %[[#r286]] 24
+; CHECK-NEXT: %[[#r287:]] = OpBitcast %[[#r27]] %[[#r64]]
+; CHECK-NEXT: OpLifetimeStop %[[#r287]] 24
+; CHECK-NEXT: %[[#r288:]] = OpBitcast %[[#r27]] %[[#r58]]
+; CHECK-NEXT: OpLifetimeStop %[[#r288]] 16
+; CHECK-NEXT: %[[#r289:]] = OpBitcast %[[#r27]] %[[#r57]]
+; CHECK-NEXT: OpLifetimeStop %[[#r289]] 16
+; CHECK-NEXT: %[[#r290:]] = OpBitcast %[[#r27]] %[[#r56]]
+; CHECK-NEXT: OpLifetimeStop %[[#r290]] 16
; CHECK-NEXT: OpReturn
; CHECK-NEXT: OpFunctionEnd
entry:
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange_no_sret.ll b/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange_no_sret.ll
index d13e7cba6d9bf..2425eb4462b71 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange_no_sret.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange_no_sret.ll
@@ -1,5 +1,3 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
-
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
; %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
@@ -19,9 +17,4 @@ entry:
ret void
}
-declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1
-
declare spir_func %struct.ndrange_t @_Z10ndrange_1Dm(i64 noundef) local_unnamed_addr #2
-
-; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
-declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1
>From 5de9e3aac23c9072d4db755726d91db8c753ee4f Mon Sep 17 00:00:00 2001
From: idubinov <igor.dubinov at amd.com>
Date: Tue, 17 Mar 2026 12:00:01 -0500
Subject: [PATCH 7/8] string2int
---
llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index a885da7118b82..3ba9f1b87f89c 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -2664,7 +2664,8 @@ static bool buildNDRange(const SPIRV::IncomingCall *Call,
// The dimension is encoded in the function name as "ndrange_XD" where X is
// 1, 2, or 3.
- unsigned Dimension = atoi(Call->Builtin->Name.substr(8, 1).data());
+ unsigned Dimension = 0;
+ Call->Builtin->Name.substr(8, 1).getAsInteger(10, Dimension);
assert(Dimension <= 3 && Dimension >= 1);
// Determine the work size type based on the dimension. For missing arguments,
>From f571ec2255e7b0f65b69abc03120730f6f2f87a1 Mon Sep 17 00:00:00 2001
From: idubinov <igor.dubinov at amd.com>
Date: Wed, 18 Mar 2026 09:08:23 -0500
Subject: [PATCH 8/8] simplify test
---
.../CodeGen/SPIRV/transcoding/BuildNDRange.ll | 714 +++---------------
1 file changed, 117 insertions(+), 597 deletions(-)
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange.ll b/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange.ll
index 68692084bbc4e..dcb69a9a4b2eb 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/BuildNDRange.ll
@@ -1,628 +1,148 @@
-;; Test that checks all variants of ndrange and what ndrange_1D, ndrange_2D and ndrange_3D can coexist in the same module
+;; Test that checks all variants of ndrange and what ndrange_2D and ndrange_3D can coexist in the same module
;;
-;; bash$ cat BuildNDRange.cl
-;; void test_ndrange_2D3D() {
-;; size_t GS1 = 1;
-;; size_t LS1 = 2;
-;; size_t WO1 = 3;
-;; ndrange_1D(GS1);
-;; ndrange_1D(GS1, LS1);
-;; ndrange_1D(WO1, GS1, LS1);
-;; ndrange_1D(GS1, GS1);
-;; ndrange_1D(GS1, GS1, GS1);
-;; size_t GS2[2] = {1, 1};
-;; size_t LS2[2] = {2, 2};
-;; size_t WO2[2] = {3, 3};
-;; ndrange_2D(GS2);
-;; ndrange_2D(GS2, LS2);
-;; ndrange_2D(WO2, GS2, LS2);
-;; ndrange_2D(GS2, GS2);
-;; ndrange_2D(GS2, GS2, GS2);
-;; size_t GS3[3] = {1, 1, 1};
-;; size_t LS3[3] = {1, 2, 1};
-;; size_t WO3[3] = {1, 3, 1};
-;; ndrange_3D(GS3);
-;; ndrange_2D(GS3, LS3);
-;; ndrange_2D(WO3, GS3, LS3);
-;; ndrange_2D(GS3, GS3);
-;; ndrange_2D(GS3, GS3, GS3);
-;; const size_t GS1c = 1;
-;; const size_t LS1c = 2;
-;; const size_t WO1c = 3;
-;; ndrange_1D(GS1c);
-;; ndrange_1D(GS1c, LS1c);
-;; ndrange_1D(WO1c, GS1c, LS1c);
-;; ndrange_1D(GS1c, GS1c);
-;; ndrange_1D(GS1c, GS1c, GS1c);
-;; const size_t GS2c[2] = {1, 1};
-;; const size_t LS2c[2] = {1, 2};
-;; const size_t WO2c[2] = {1, 3};
-;; ndrange_2D(GS2c);
-;; ndrange_2D(GS2c, LS2c);
-;; ndrange_2D(WO2c, GS2c, LS2c);
-;; ndrange_2D(GS2c, GS2c);
-;; ndrange_2D(GS2c, GS2c, GS2c);
-;; const size_t GS3c[3] = {1, 1, 1};
-;; const size_t LS3c[3] = {1, 1, 2};
-;; const size_t WO3c[3] = {1, 1, 3};
-;; ndrange_3D(GS3c);
-;; ndrange_2D(GS3c, LS3c);
-;; ndrange_2D(WO3c, GS3c, LS3c);
-;; ndrange_2D(GS3c, GS3c);
-;; ndrange_2D(GS3c, GS3c, GS3c);
-;; }
-;; bash$ clang -cc1 -cl-std=CL2.0 -triple spirv64-unknown-unknown -emit-llvm -finclude-default-header -cl-single-precision-constant BuildNDRange.cl -o BuildNDRange.ll
-
+;;void test_ndrange_1D(size_t GS1 , size_t LS1 , size_t WO1) {
+;; ndrange_1D(GS1);
+;; ndrange_1D(GS1, LS1);
+;; ndrange_1D(WO1, GS1, LS1);
+;; // test const argument
+;; const size_t GS1c = 1;
+;; ndrange_1D(GS1c);
+;;}
+;;
+;;void test_ndrange_2D(size_t GS2[2], size_t LS2[2], size_t WO2[2]) {
+;; ndrange_2D(GS2);
+;; ndrange_2D(GS2, LS2);
+;; ndrange_2D(WO2, GS2, LS2);
+;;}
+;;
+;;void test_ndrange_3D(size_t GS3[3], size_t LS3[3], size_t WO3[3], size_t GS2[2]) {
+;; ndrange_3D(GS3);
+;; ndrange_3D(GS3, LS3);
+;; ndrange_3D(WO3, GS3, LS3);
+;; // test same argument
+;; ndrange_3D(GS3, GS3);
+;; ndrange_3D(GS3, GS3, GS3);
+;; // test const argument
+;; const size_t GS3c[3] = {1, 4, 7};
+;; ndrange_3D(GS3c);
+;; // test 2D and 3D can coexist in one funciton
+;; ndrange_2D(GS2);
+;;}
+;;
+;; bash$ clang -cc1 -cl-std=CL2.0 -triple spirv64-unknown-unknown -emit-llvm -finclude-default-header -cl-single-precision-constant BuildNDRange.cl -o BuildNDRange.ll
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
; %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
%struct.ndrange_t = type { i32, [3 x i64], [3 x i64], [3 x i64] }
- at __const.test_ndrange_2D3D.GS2 = private unnamed_addr addrspace(2) constant [2 x i64] [i64 1, i64 1], align 8
- at __const.test_ndrange_2D3D.LS2 = private unnamed_addr addrspace(2) constant [2 x i64] [i64 2, i64 2], align 8
- at __const.test_ndrange_2D3D.WO2 = private unnamed_addr addrspace(2) constant [2 x i64] [i64 3, i64 3], align 8
- at __const.test_ndrange_2D3D.GS3 = private unnamed_addr addrspace(2) constant [3 x i64] [i64 1, i64 1, i64 1], align 8
- at __const.test_ndrange_2D3D.LS3 = private unnamed_addr addrspace(2) constant [3 x i64] [i64 1, i64 2, i64 1], align 8
- at __const.test_ndrange_2D3D.WO3 = private unnamed_addr addrspace(2) constant [3 x i64] [i64 1, i64 3, i64 1], align 8
- at __const.test_ndrange_2D3D.GS2c = private unnamed_addr addrspace(2) constant [2 x i64] [i64 1, i64 1], align 8
- at __const.test_ndrange_2D3D.LS2c = private unnamed_addr addrspace(2) constant [2 x i64] [i64 1, i64 2], align 8
- at __const.test_ndrange_2D3D.WO2c = private unnamed_addr addrspace(2) constant [2 x i64] [i64 1, i64 3], align 8
- at __const.test_ndrange_2D3D.GS3c = private unnamed_addr addrspace(2) constant [3 x i64] [i64 1, i64 1, i64 1], align 8
- at __const.test_ndrange_2D3D.LS3c = private unnamed_addr addrspace(2) constant [3 x i64] [i64 1, i64 1, i64 2], align 8
- at __const.test_ndrange_2D3D.WO3c = private unnamed_addr addrspace(2) constant [3 x i64] [i64 1, i64 1, i64 3], align 8
+ at __const.test_ndrange_3D.GS3c = private unnamed_addr addrspace(2) constant [3 x i64] [i64 1, i64 4, i64 7], align 8
-define spir_func void @test_ndrange_2D3D() local_unnamed_addr #0 {
-; CHECK-LABEL: test_ndrange_2D3D
-; CHECK: %[[#r50:]] = OpFunction %[[#r3:]] None %[[#r4:]] ; -- Begin function test_ndrange_2D3D
-; CHECK-NEXT: %[[#r2:]] = OpLabel
-; CHECK-NEXT: %[[#r51:]] = OpVariable %[[#r10:]] Function
-; CHECK-NEXT: %[[#r52:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r53:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r54:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r55:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r56:]] = OpVariable %[[#r13:]] Function
-; CHECK-NEXT: %[[#r57:]] = OpVariable %[[#r13]] Function
-; CHECK-NEXT: %[[#r58:]] = OpVariable %[[#r13]] Function
-; CHECK-NEXT: %[[#r59:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r60:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r61:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r62:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r63:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r64:]] = OpVariable %[[#r16:]] Function
-; CHECK-NEXT: %[[#r65:]] = OpVariable %[[#r16]] Function
-; CHECK-NEXT: %[[#r66:]] = OpVariable %[[#r16]] Function
-; CHECK-NEXT: %[[#r67:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r68:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r69:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r70:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r71:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r72:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r73:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r74:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r75:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r76:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r77:]] = OpVariable %[[#r13]] Function
-; CHECK-NEXT: %[[#r78:]] = OpVariable %[[#r13]] Function
-; CHECK-NEXT: %[[#r79:]] = OpVariable %[[#r13]] Function
-; CHECK-NEXT: %[[#r80:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r81:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r82:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r83:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r84:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r85:]] = OpVariable %[[#r16]] Function
-; CHECK-NEXT: %[[#r86:]] = OpVariable %[[#r16]] Function
-; CHECK-NEXT: %[[#r87:]] = OpVariable %[[#r16]] Function
-; CHECK-NEXT: %[[#r88:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r89:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r90:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r91:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r92:]] = OpVariable %[[#r10]] Function
-; CHECK-NEXT: %[[#r93:]] = OpBitcast %[[#r27:]] %[[#r51]]
-; CHECK-NEXT: OpLifetimeStart %[[#r93]] 80
-; CHECK-NEXT: %[[#r94:]] = OpBuildNDRange %[[#r9:]] %[[#r24:]] %[[#r25:]] %[[#r25:]]
-; CHECK-NEXT: OpStore %[[#r51]] %[[#r94]]
-; CHECK-NEXT: %[[#r95:]] = OpBitcast %[[#r27:]] %[[#r51]]
-; CHECK-NEXT: OpLifetimeStop %[[#r95]] 80
-; CHECK-NEXT: %[[#r96:]] = OpBitcast %[[#r27]] %[[#r52]]
-; CHECK-NEXT: OpLifetimeStart %[[#r96]] 80
-; CHECK-NEXT: %[[#r97:]] = OpBuildNDRange %[[#r9]] %[[#r24:]] %[[#r23:]] %[[#r25]]
-; CHECK-NEXT: OpStore %[[#r52]] %[[#r97]]
-; CHECK-NEXT: %[[#r98:]] = OpBitcast %[[#r27]] %[[#r52]]
-; CHECK-NEXT: OpLifetimeStop %[[#r98]] 80
-; CHECK-NEXT: %[[#r99:]] = OpBitcast %[[#r27]] %[[#r53]]
-; CHECK-NEXT: OpLifetimeStart %[[#r99]] 80
-; CHECK-NEXT: %[[#r100:]] = OpBuildNDRange %[[#r9]] %[[#r24]] %[[#r23:]] %[[#r22:]]
-; CHECK-NEXT: OpStore %[[#r53]] %[[#r100]]
-; CHECK-NEXT: %[[#r101:]] = OpBitcast %[[#r27]] %[[#r53]]
-; CHECK-NEXT: OpLifetimeStop %[[#r101]] 80
-; CHECK-NEXT: %[[#r102:]] = OpBitcast %[[#r27]] %[[#r54]]
-; CHECK-NEXT: OpLifetimeStart %[[#r102]] 80
-; CHECK-NEXT: %[[#r103:]] = OpBuildNDRange %[[#r9]] %[[#r24]] %[[#r24]] %[[#r25]]
-; CHECK-NEXT: OpStore %[[#r54]] %[[#r103]]
-; CHECK-NEXT: %[[#r104:]] = OpBitcast %[[#r27]] %[[#r54]]
-; CHECK-NEXT: OpLifetimeStop %[[#r104]] 80
-; CHECK-NEXT: %[[#r105:]] = OpBitcast %[[#r27]] %[[#r55]]
-; CHECK-NEXT: OpLifetimeStart %[[#r105]] 80
-; CHECK-NEXT: %[[#r106:]] = OpBuildNDRange %[[#r9]] %[[#r24]] %[[#r24]] %[[#r24]]
-; CHECK-NEXT: OpStore %[[#r55]] %[[#r106]]
-; CHECK-NEXT: %[[#r107:]] = OpBitcast %[[#r27]] %[[#r55]]
-; CHECK-NEXT: OpLifetimeStop %[[#r107]] 80
-; CHECK-NEXT: %[[#r108:]] = OpBitcast %[[#r27]] %[[#r56]]
-; CHECK-NEXT: OpLifetimeStart %[[#r108]] 16
-; CHECK-NEXT: OpCopyMemorySized %[[#r56]] %[[#r29:]] %[[#r21:]] Aligned 8
-; CHECK-NEXT: %[[#r109:]] = OpBitcast %[[#r27]] %[[#r57]]
-; CHECK-NEXT: OpLifetimeStart %[[#r109]] 16
-; CHECK-NEXT: OpCopyMemorySized %[[#r57]] %[[#r31:]] %[[#r21]] Aligned 8
-; CHECK-NEXT: %[[#r110:]] = OpBitcast %[[#r27]] %[[#r58]]
-; CHECK-NEXT: OpLifetimeStart %[[#r110]] 16
-; CHECK-NEXT: OpCopyMemorySized %[[#r58]] %[[#r33:]] %[[#r21]] Aligned 8
-; CHECK-NEXT: %[[#r111:]] = OpBitcast %[[#r27]] %[[#r59]]
-; CHECK-NEXT: OpLifetimeStart %[[#r111]] 80
-; CHECK-NEXT: %[[#r112:]] = OpLoad %[[#r12:]] %[[#r56]]
-; CHECK-NEXT: %[[#r113:]] = OpBuildNDRange %[[#r9]] %[[#r112]] %[[#r14:]] %[[#r14:]]
-; CHECK-NEXT: OpStore %[[#r59]] %[[#r113]]
-; CHECK-NEXT: %[[#r114:]] = OpBitcast %[[#r27]] %[[#r59]]
-; CHECK-NEXT: OpLifetimeStop %[[#r114]] 80
-; CHECK-NEXT: %[[#r115:]] = OpBitcast %[[#r27]] %[[#r60]]
-; CHECK-NEXT: OpLifetimeStart %[[#r115]] 80
-; CHECK-NEXT: %[[#r116:]] = OpBitcast %[[#r15:]] %[[#r56]]
-; CHECK-NEXT: %[[#r117:]] = OpBitcast %[[#r13]] %[[#r116]]
-; CHECK-NEXT: %[[#r118:]] = OpLoad %[[#r12]] %[[#r117]]
-; CHECK-NEXT: %[[#r119:]] = OpLoad %[[#r12]] %[[#r57]]
-; CHECK-NEXT: %[[#r120:]] = OpBuildNDRange %[[#r9]] %[[#r118]] %[[#r119]] %[[#r14]]
-; CHECK-NEXT: OpStore %[[#r60]] %[[#r120]]
-; CHECK-NEXT: %[[#r121:]] = OpBitcast %[[#r27]] %[[#r60]]
-; CHECK-NEXT: OpLifetimeStop %[[#r121]] 80
-; CHECK-NEXT: %[[#r122:]] = OpBitcast %[[#r27]] %[[#r61]]
-; CHECK-NEXT: OpLifetimeStart %[[#r122]] 80
-; CHECK-NEXT: %[[#r123:]] = OpBitcast %[[#r15]] %[[#r58]]
-; CHECK-NEXT: %[[#r124:]] = OpBitcast %[[#r13]] %[[#r116]]
-; CHECK-NEXT: %[[#r125:]] = OpLoad %[[#r12]] %[[#r124]]
-; CHECK-NEXT: %[[#r126:]] = OpLoad %[[#r12]] %[[#r57]]
-; CHECK-NEXT: %[[#r127:]] = OpBitcast %[[#r13]] %[[#r123]]
-; CHECK-NEXT: %[[#r128:]] = OpLoad %[[#r12]] %[[#r127]]
-; CHECK-NEXT: %[[#r129:]] = OpBuildNDRange %[[#r9]] %[[#r125]] %[[#r126]] %[[#r128]]
-; CHECK-NEXT: OpStore %[[#r61]] %[[#r129]]
-; CHECK-NEXT: %[[#r130:]] = OpBitcast %[[#r27]] %[[#r61]]
-; CHECK-NEXT: OpLifetimeStop %[[#r130]] 80
-; CHECK-NEXT: %[[#r131:]] = OpBitcast %[[#r27]] %[[#r62]]
-; CHECK-NEXT: OpLifetimeStart %[[#r131]] 80
-; CHECK-NEXT: %[[#r132:]] = OpBitcast %[[#r13]] %[[#r116]]
-; CHECK-NEXT: %[[#r133:]] = OpLoad %[[#r12]] %[[#r132]]
-; CHECK-NEXT: %[[#r134:]] = OpLoad %[[#r12]] %[[#r56]]
-; CHECK-NEXT: %[[#r135:]] = OpBuildNDRange %[[#r9]] %[[#r133]] %[[#r134]] %[[#r14]]
-; CHECK-NEXT: OpStore %[[#r62]] %[[#r135]]
-; CHECK-NEXT: %[[#r136:]] = OpBitcast %[[#r27]] %[[#r62]]
-; CHECK-NEXT: OpLifetimeStop %[[#r136]] 80
-; CHECK-NEXT: %[[#r137:]] = OpBitcast %[[#r27]] %[[#r63]]
-; CHECK-NEXT: OpLifetimeStart %[[#r137]] 80
-; CHECK-NEXT: %[[#r138:]] = OpBitcast %[[#r13]] %[[#r116]]
-; CHECK-NEXT: %[[#r139:]] = OpLoad %[[#r12]] %[[#r138]]
-; CHECK-NEXT: %[[#r140:]] = OpLoad %[[#r12]] %[[#r56]]
-; CHECK-NEXT: %[[#r141:]] = OpBitcast %[[#r13]] %[[#r116]]
-; CHECK-NEXT: %[[#r142:]] = OpLoad %[[#r12]] %[[#r141]]
-; CHECK-NEXT: %[[#r143:]] = OpBuildNDRange %[[#r9]] %[[#r139]] %[[#r140]] %[[#r142]]
-; CHECK-NEXT: OpStore %[[#r63]] %[[#r143]]
-; CHECK-NEXT: %[[#r144:]] = OpBitcast %[[#r27]] %[[#r63]]
-; CHECK-NEXT: OpLifetimeStop %[[#r144]] 80
-; CHECK-NEXT: %[[#r145:]] = OpBitcast %[[#r27]] %[[#r64]]
-; CHECK-NEXT: OpLifetimeStart %[[#r145]] 24
-; CHECK-NEXT: OpCopyMemorySized %[[#r64]] %[[#r35:]] %[[#r20:]] Aligned 8
-; CHECK-NEXT: %[[#r146:]] = OpBitcast %[[#r27]] %[[#r65]]
-; CHECK-NEXT: OpLifetimeStart %[[#r146]] 24
-; CHECK-NEXT: OpCopyMemorySized %[[#r65]] %[[#r37:]] %[[#r20]] Aligned 8
-; CHECK-NEXT: %[[#r147:]] = OpBitcast %[[#r27]] %[[#r66]]
-; CHECK-NEXT: OpLifetimeStart %[[#r147]] 24
-; CHECK-NEXT: OpCopyMemorySized %[[#r66]] %[[#r39:]] %[[#r20]] Aligned 8
-; CHECK-NEXT: %[[#r148:]] = OpBitcast %[[#r27]] %[[#r67]]
-; CHECK-NEXT: OpLifetimeStart %[[#r148]] 80
-; CHECK-NEXT: %[[#r149:]] = OpLoad %[[#r8:]] %[[#r64]]
-; CHECK-NEXT: %[[#r150:]] = OpBuildNDRange %[[#r9]] %[[#r149]] %[[#r17:]] %[[#r17:]]
-; CHECK-NEXT: OpStore %[[#r67]] %[[#r150]]
-; CHECK-NEXT: %[[#r151:]] = OpBitcast %[[#r27]] %[[#r67]]
-; CHECK-NEXT: OpLifetimeStop %[[#r151]] 80
-; CHECK-NEXT: %[[#r152:]] = OpBitcast %[[#r27]] %[[#r68]]
-; CHECK-NEXT: OpLifetimeStart %[[#r152]] 80
-; CHECK-NEXT: %[[#r153:]] = OpBitcast %[[#r15]] %[[#r64]]
-; CHECK-NEXT: %[[#r154:]] = OpBitcast %[[#r13]] %[[#r153]]
-; CHECK-NEXT: %[[#r155:]] = OpLoad %[[#r12]] %[[#r154]]
-; CHECK-NEXT: %[[#r156:]] = OpBitcast %[[#r13]] %[[#r65]]
-; CHECK-NEXT: %[[#r157:]] = OpLoad %[[#r12]] %[[#r156]]
-; CHECK-NEXT: %[[#r158:]] = OpBuildNDRange %[[#r9]] %[[#r155]] %[[#r157]] %[[#r14]]
-; CHECK-NEXT: OpStore %[[#r68]] %[[#r158]]
-; CHECK-NEXT: %[[#r159:]] = OpBitcast %[[#r27]] %[[#r68]]
-; CHECK-NEXT: OpLifetimeStop %[[#r159]] 80
-; CHECK-NEXT: %[[#r160:]] = OpBitcast %[[#r27]] %[[#r69]]
-; CHECK-NEXT: OpLifetimeStart %[[#r160]] 80
-; CHECK-NEXT: %[[#r161:]] = OpBitcast %[[#r15]] %[[#r66]]
-; CHECK-NEXT: %[[#r162:]] = OpBitcast %[[#r13]] %[[#r153]]
-; CHECK-NEXT: %[[#r163:]] = OpLoad %[[#r12]] %[[#r162]]
-; CHECK-NEXT: %[[#r164:]] = OpBitcast %[[#r13]] %[[#r65]]
-; CHECK-NEXT: %[[#r165:]] = OpLoad %[[#r12]] %[[#r164]]
-; CHECK-NEXT: %[[#r166:]] = OpBitcast %[[#r13]] %[[#r161]]
-; CHECK-NEXT: %[[#r167:]] = OpLoad %[[#r12]] %[[#r166]]
-; CHECK-NEXT: %[[#r168:]] = OpBuildNDRange %[[#r9]] %[[#r163]] %[[#r165]] %[[#r167]]
-; CHECK-NEXT: OpStore %[[#r69]] %[[#r168]]
-; CHECK-NEXT: %[[#r169:]] = OpBitcast %[[#r27]] %[[#r69]]
-; CHECK-NEXT: OpLifetimeStop %[[#r169]] 80
-; CHECK-NEXT: %[[#r170:]] = OpBitcast %[[#r27]] %[[#r70]]
-; CHECK-NEXT: OpLifetimeStart %[[#r170]] 80
-; CHECK-NEXT: %[[#r171:]] = OpBitcast %[[#r13]] %[[#r153]]
-; CHECK-NEXT: %[[#r172:]] = OpLoad %[[#r12]] %[[#r171]]
-; CHECK-NEXT: %[[#r173:]] = OpBitcast %[[#r13]] %[[#r64]]
-; CHECK-NEXT: %[[#r174:]] = OpLoad %[[#r12]] %[[#r173]]
-; CHECK-NEXT: %[[#r175:]] = OpBuildNDRange %[[#r9]] %[[#r172]] %[[#r174]] %[[#r14]]
-; CHECK-NEXT: OpStore %[[#r70]] %[[#r175]]
-; CHECK-NEXT: %[[#r176:]] = OpBitcast %[[#r27]] %[[#r70]]
-; CHECK-NEXT: OpLifetimeStop %[[#r176]] 80
-; CHECK-NEXT: %[[#r177:]] = OpBitcast %[[#r27]] %[[#r71]]
-; CHECK-NEXT: OpLifetimeStart %[[#r177]] 80
-; CHECK-NEXT: %[[#r178:]] = OpBitcast %[[#r13]] %[[#r153]]
-; CHECK-NEXT: %[[#r179:]] = OpLoad %[[#r12]] %[[#r178]]
-; CHECK-NEXT: %[[#r180:]] = OpBitcast %[[#r13]] %[[#r64]]
-; CHECK-NEXT: %[[#r181:]] = OpLoad %[[#r12]] %[[#r180]]
-; CHECK-NEXT: %[[#r182:]] = OpBitcast %[[#r13]] %[[#r153]]
-; CHECK-NEXT: %[[#r183:]] = OpLoad %[[#r12]] %[[#r182]]
-; CHECK-NEXT: %[[#r184:]] = OpBuildNDRange %[[#r9]] %[[#r179]] %[[#r181]] %[[#r183]]
-; CHECK-NEXT: OpStore %[[#r71]] %[[#r184]]
-; CHECK-NEXT: %[[#r185:]] = OpBitcast %[[#r27]] %[[#r71]]
-; CHECK-NEXT: OpLifetimeStop %[[#r185]] 80
-; CHECK-NEXT: %[[#r186:]] = OpBitcast %[[#r27]] %[[#r72]]
-; CHECK-NEXT: OpLifetimeStart %[[#r186]] 80
-; CHECK-NEXT: %[[#r187:]] = OpBuildNDRange %[[#r9]] %[[#r24]] %[[#r25]] %[[#r25]]
-; CHECK-NEXT: OpStore %[[#r72]] %[[#r187]]
-; CHECK-NEXT: %[[#r188:]] = OpBitcast %[[#r27]] %[[#r72]]
-; CHECK-NEXT: OpLifetimeStop %[[#r188]] 80
-; CHECK-NEXT: %[[#r189:]] = OpBitcast %[[#r27]] %[[#r73]]
-; CHECK-NEXT: OpLifetimeStart %[[#r189]] 80
-; CHECK-NEXT: %[[#r190:]] = OpBuildNDRange %[[#r9]] %[[#r24]] %[[#r23]] %[[#r25]]
-; CHECK-NEXT: OpStore %[[#r73]] %[[#r190]]
-; CHECK-NEXT: %[[#r191:]] = OpBitcast %[[#r27]] %[[#r73]]
-; CHECK-NEXT: OpLifetimeStop %[[#r191]] 80
-; CHECK-NEXT: %[[#r192:]] = OpBitcast %[[#r27]] %[[#r74]]
-; CHECK-NEXT: OpLifetimeStart %[[#r192]] 80
-; CHECK-NEXT: %[[#r193:]] = OpBuildNDRange %[[#r9]] %[[#r24]] %[[#r23]] %[[#r22]]
-; CHECK-NEXT: OpStore %[[#r74]] %[[#r193]]
-; CHECK-NEXT: %[[#r194:]] = OpBitcast %[[#r27]] %[[#r74]]
-; CHECK-NEXT: OpLifetimeStop %[[#r194]] 80
-; CHECK-NEXT: %[[#r195:]] = OpBitcast %[[#r27]] %[[#r75]]
-; CHECK-NEXT: OpLifetimeStart %[[#r195]] 80
-; CHECK-NEXT: %[[#r196:]] = OpBuildNDRange %[[#r9]] %[[#r24]] %[[#r24]] %[[#r25]]
-; CHECK-NEXT: OpStore %[[#r75]] %[[#r196]]
-; CHECK-NEXT: %[[#r197:]] = OpBitcast %[[#r27]] %[[#r75]]
-; CHECK-NEXT: OpLifetimeStop %[[#r197]] 80
-; CHECK-NEXT: %[[#r198:]] = OpBitcast %[[#r27]] %[[#r76]]
-; CHECK-NEXT: OpLifetimeStart %[[#r198]] 80
-; CHECK-NEXT: %[[#r199:]] = OpBuildNDRange %[[#r9]] %[[#r24]] %[[#r24]] %[[#r24]]
-; CHECK-NEXT: OpStore %[[#r76]] %[[#r199]]
-; CHECK-NEXT: %[[#r200:]] = OpBitcast %[[#r27]] %[[#r76]]
-; CHECK-NEXT: OpLifetimeStop %[[#r200]] 80
-; CHECK-NEXT: %[[#r201:]] = OpBitcast %[[#r27]] %[[#r77]]
-; CHECK-NEXT: OpLifetimeStart %[[#r201]] 16
-; CHECK-NEXT: OpCopyMemorySized %[[#r77]] %[[#r40:]] %[[#r21:]] Aligned 8
-; CHECK-NEXT: %[[#r202:]] = OpBitcast %[[#r27]] %[[#r78]]
-; CHECK-NEXT: OpLifetimeStart %[[#r202]] 16
-; CHECK-NEXT: OpCopyMemorySized %[[#r78]] %[[#r42:]] %[[#r21]] Aligned 8
-; CHECK-NEXT: %[[#r203:]] = OpBitcast %[[#r27]] %[[#r79]]
-; CHECK-NEXT: OpLifetimeStart %[[#r203]] 16
-; CHECK-NEXT: OpCopyMemorySized %[[#r79]] %[[#r44:]] %[[#r21]] Aligned 8
-; CHECK-NEXT: %[[#r204:]] = OpBitcast %[[#r27]] %[[#r80]]
-; CHECK-NEXT: OpLifetimeStart %[[#r204]] 80
-; CHECK-NEXT: %[[#r205:]] = OpLoad %[[#r12]] %[[#r77]]
-; CHECK-NEXT: %[[#r206:]] = OpBuildNDRange %[[#r9]] %[[#r205]] %[[#r14]] %[[#r14]]
-; CHECK-NEXT: OpStore %[[#r80]] %[[#r206]]
-; CHECK-NEXT: %[[#r207:]] = OpBitcast %[[#r27]] %[[#r80]]
-; CHECK-NEXT: OpLifetimeStop %[[#r207]] 80
-; CHECK-NEXT: %[[#r208:]] = OpBitcast %[[#r27]] %[[#r81]]
-; CHECK-NEXT: OpLifetimeStart %[[#r208]] 80
-; CHECK-NEXT: %[[#r209:]] = OpBitcast %[[#r15]] %[[#r77]]
-; CHECK-NEXT: %[[#r210:]] = OpBitcast %[[#r13]] %[[#r209]]
-; CHECK-NEXT: %[[#r211:]] = OpLoad %[[#r12]] %[[#r210]]
-; CHECK-NEXT: %[[#r212:]] = OpLoad %[[#r12]] %[[#r78]]
-; CHECK-NEXT: %[[#r213:]] = OpBuildNDRange %[[#r9]] %[[#r211]] %[[#r212]] %[[#r14]]
-; CHECK-NEXT: OpStore %[[#r81]] %[[#r213]]
-; CHECK-NEXT: %[[#r214:]] = OpBitcast %[[#r27]] %[[#r81]]
-; CHECK-NEXT: OpLifetimeStop %[[#r214]] 80
-; CHECK-NEXT: %[[#r215:]] = OpBitcast %[[#r27]] %[[#r82]]
-; CHECK-NEXT: OpLifetimeStart %[[#r215]] 80
-; CHECK-NEXT: %[[#r216:]] = OpBitcast %[[#r15]] %[[#r79]]
-; CHECK-NEXT: %[[#r217:]] = OpBitcast %[[#r13]] %[[#r209]]
-; CHECK-NEXT: %[[#r218:]] = OpLoad %[[#r12]] %[[#r217]]
-; CHECK-NEXT: %[[#r219:]] = OpLoad %[[#r12]] %[[#r78]]
-; CHECK-NEXT: %[[#r220:]] = OpBitcast %[[#r13]] %[[#r216]]
-; CHECK-NEXT: %[[#r221:]] = OpLoad %[[#r12]] %[[#r220]]
-; CHECK-NEXT: %[[#r222:]] = OpBuildNDRange %[[#r9]] %[[#r218]] %[[#r219]] %[[#r221]]
-; CHECK-NEXT: OpStore %[[#r82]] %[[#r222]]
-; CHECK-NEXT: %[[#r223:]] = OpBitcast %[[#r27]] %[[#r82]]
-; CHECK-NEXT: OpLifetimeStop %[[#r223]] 80
-; CHECK-NEXT: %[[#r224:]] = OpBitcast %[[#r27]] %[[#r83]]
-; CHECK-NEXT: OpLifetimeStart %[[#r224]] 80
-; CHECK-NEXT: %[[#r225:]] = OpBitcast %[[#r13]] %[[#r209]]
-; CHECK-NEXT: %[[#r226:]] = OpLoad %[[#r12]] %[[#r225]]
-; CHECK-NEXT: %[[#r227:]] = OpLoad %[[#r12]] %[[#r77]]
-; CHECK-NEXT: %[[#r228:]] = OpBuildNDRange %[[#r9]] %[[#r226]] %[[#r227]] %[[#r14]]
-; CHECK-NEXT: OpStore %[[#r83]] %[[#r228]]
-; CHECK-NEXT: %[[#r229:]] = OpBitcast %[[#r27]] %[[#r83]]
-; CHECK-NEXT: OpLifetimeStop %[[#r229]] 80
-; CHECK-NEXT: %[[#r230:]] = OpBitcast %[[#r27]] %[[#r84]]
-; CHECK-NEXT: OpLifetimeStart %[[#r230]] 80
-; CHECK-NEXT: %[[#r231:]] = OpBitcast %[[#r13]] %[[#r209]]
-; CHECK-NEXT: %[[#r232:]] = OpLoad %[[#r12]] %[[#r231]]
-; CHECK-NEXT: %[[#r233:]] = OpLoad %[[#r12]] %[[#r77]]
-; CHECK-NEXT: %[[#r234:]] = OpBitcast %[[#r13]] %[[#r209]]
-; CHECK-NEXT: %[[#r235:]] = OpLoad %[[#r12]] %[[#r234]]
-; CHECK-NEXT: %[[#r236:]] = OpBuildNDRange %[[#r9]] %[[#r232]] %[[#r233]] %[[#r235]]
-; CHECK-NEXT: OpStore %[[#r84]] %[[#r236]]
-; CHECK-NEXT: %[[#r237:]] = OpBitcast %[[#r27]] %[[#r84]]
-; CHECK-NEXT: OpLifetimeStop %[[#r237]] 80
-; CHECK-NEXT: %[[#r238:]] = OpBitcast %[[#r27]] %[[#r85]]
-; CHECK-NEXT: OpLifetimeStart %[[#r238]] 24
-; CHECK-NEXT: OpCopyMemorySized %[[#r85]] %[[#r45:]] %[[#r20]] Aligned 8
-; CHECK-NEXT: %[[#r239:]] = OpBitcast %[[#r27]] %[[#r86]]
-; CHECK-NEXT: OpLifetimeStart %[[#r239]] 24
-; CHECK-NEXT: OpCopyMemorySized %[[#r86]] %[[#r47:]] %[[#r20]] Aligned 8
-; CHECK-NEXT: %[[#r240:]] = OpBitcast %[[#r27]] %[[#r87]]
-; CHECK-NEXT: OpLifetimeStart %[[#r240]] 24
-; CHECK-NEXT: OpCopyMemorySized %[[#r87]] %[[#r49:]] %[[#r20]] Aligned 8
-; CHECK-NEXT: %[[#r241:]] = OpBitcast %[[#r27]] %[[#r88]]
-; CHECK-NEXT: OpLifetimeStart %[[#r241]] 80
-; CHECK-NEXT: %[[#r242:]] = OpLoad %[[#r8]] %[[#r85]]
-; CHECK-NEXT: %[[#r243:]] = OpBuildNDRange %[[#r9]] %[[#r242]] %[[#r17]] %[[#r17]]
-; CHECK-NEXT: OpStore %[[#r88]] %[[#r243]]
-; CHECK-NEXT: %[[#r244:]] = OpBitcast %[[#r27]] %[[#r88]]
-; CHECK-NEXT: OpLifetimeStop %[[#r244]] 80
-; CHECK-NEXT: %[[#r245:]] = OpBitcast %[[#r27]] %[[#r89]]
-; CHECK-NEXT: OpLifetimeStart %[[#r245]] 80
-; CHECK-NEXT: %[[#r246:]] = OpBitcast %[[#r15]] %[[#r85]]
-; CHECK-NEXT: %[[#r247:]] = OpBitcast %[[#r13]] %[[#r246]]
-; CHECK-NEXT: %[[#r248:]] = OpLoad %[[#r12]] %[[#r247]]
-; CHECK-NEXT: %[[#r249:]] = OpBitcast %[[#r13]] %[[#r86]]
-; CHECK-NEXT: %[[#r250:]] = OpLoad %[[#r12]] %[[#r249]]
-; CHECK-NEXT: %[[#r251:]] = OpBuildNDRange %[[#r9]] %[[#r248]] %[[#r250]] %[[#r14]]
-; CHECK-NEXT: OpStore %[[#r89]] %[[#r251]]
-; CHECK-NEXT: %[[#r252:]] = OpBitcast %[[#r27]] %[[#r89]]
-; CHECK-NEXT: OpLifetimeStop %[[#r252]] 80
-; CHECK-NEXT: %[[#r253:]] = OpBitcast %[[#r27]] %[[#r90]]
-; CHECK-NEXT: OpLifetimeStart %[[#r253]] 80
-; CHECK-NEXT: %[[#r254:]] = OpBitcast %[[#r15]] %[[#r87]]
-; CHECK-NEXT: %[[#r255:]] = OpBitcast %[[#r13]] %[[#r246]]
-; CHECK-NEXT: %[[#r256:]] = OpLoad %[[#r12]] %[[#r255]]
-; CHECK-NEXT: %[[#r257:]] = OpBitcast %[[#r13]] %[[#r86]]
-; CHECK-NEXT: %[[#r258:]] = OpLoad %[[#r12]] %[[#r257]]
-; CHECK-NEXT: %[[#r259:]] = OpBitcast %[[#r13]] %[[#r254]]
-; CHECK-NEXT: %[[#r260:]] = OpLoad %[[#r12]] %[[#r259]]
-; CHECK-NEXT: %[[#r261:]] = OpBuildNDRange %[[#r9]] %[[#r256]] %[[#r258]] %[[#r260]]
-; CHECK-NEXT: OpStore %[[#r90]] %[[#r261]]
-; CHECK-NEXT: %[[#r262:]] = OpBitcast %[[#r27]] %[[#r90]]
-; CHECK-NEXT: OpLifetimeStop %[[#r262]] 80
-; CHECK-NEXT: %[[#r263:]] = OpBitcast %[[#r27]] %[[#r91]]
-; CHECK-NEXT: OpLifetimeStart %[[#r263]] 80
-; CHECK-NEXT: %[[#r264:]] = OpBitcast %[[#r13]] %[[#r246]]
-; CHECK-NEXT: %[[#r265:]] = OpLoad %[[#r12]] %[[#r264]]
-; CHECK-NEXT: %[[#r266:]] = OpBitcast %[[#r13]] %[[#r85]]
-; CHECK-NEXT: %[[#r267:]] = OpLoad %[[#r12]] %[[#r266]]
-; CHECK-NEXT: %[[#r268:]] = OpBuildNDRange %[[#r9]] %[[#r265]] %[[#r267]] %[[#r14]]
-; CHECK-NEXT: OpStore %[[#r91]] %[[#r268]]
-; CHECK-NEXT: %[[#r269:]] = OpBitcast %[[#r27]] %[[#r91]]
-; CHECK-NEXT: OpLifetimeStop %[[#r269]] 80
-; CHECK-NEXT: %[[#r270:]] = OpBitcast %[[#r27]] %[[#r92]]
-; CHECK-NEXT: OpLifetimeStart %[[#r270]] 80
-; CHECK-NEXT: %[[#r271:]] = OpBitcast %[[#r13]] %[[#r246]]
-; CHECK-NEXT: %[[#r272:]] = OpLoad %[[#r12]] %[[#r271]]
-; CHECK-NEXT: %[[#r273:]] = OpBitcast %[[#r13]] %[[#r85]]
-; CHECK-NEXT: %[[#r274:]] = OpLoad %[[#r12]] %[[#r273]]
-; CHECK-NEXT: %[[#r275:]] = OpBitcast %[[#r13]] %[[#r246]]
-; CHECK-NEXT: %[[#r276:]] = OpLoad %[[#r12]] %[[#r275]]
-; CHECK-NEXT: %[[#r277:]] = OpBuildNDRange %[[#r9]] %[[#r272]] %[[#r274]] %[[#r276]]
-; CHECK-NEXT: OpStore %[[#r92]] %[[#r277]]
-; CHECK-NEXT: %[[#r278:]] = OpBitcast %[[#r27]] %[[#r92]]
-; CHECK-NEXT: OpLifetimeStop %[[#r278]] 80
-; CHECK-NEXT: %[[#r279:]] = OpBitcast %[[#r27]] %[[#r87]]
-; CHECK-NEXT: OpLifetimeStop %[[#r279]] 24
-; CHECK-NEXT: %[[#r280:]] = OpBitcast %[[#r27]] %[[#r86]]
-; CHECK-NEXT: OpLifetimeStop %[[#r280]] 24
-; CHECK-NEXT: %[[#r281:]] = OpBitcast %[[#r27]] %[[#r85]]
-; CHECK-NEXT: OpLifetimeStop %[[#r281]] 24
-; CHECK-NEXT: %[[#r282:]] = OpBitcast %[[#r27]] %[[#r79]]
-; CHECK-NEXT: OpLifetimeStop %[[#r282]] 16
-; CHECK-NEXT: %[[#r283:]] = OpBitcast %[[#r27]] %[[#r78]]
-; CHECK-NEXT: OpLifetimeStop %[[#r283]] 16
-; CHECK-NEXT: %[[#r284:]] = OpBitcast %[[#r27]] %[[#r77]]
-; CHECK-NEXT: OpLifetimeStop %[[#r284]] 16
-; CHECK-NEXT: %[[#r285:]] = OpBitcast %[[#r27]] %[[#r66]]
-; CHECK-NEXT: OpLifetimeStop %[[#r285]] 24
-; CHECK-NEXT: %[[#r286:]] = OpBitcast %[[#r27]] %[[#r65]]
-; CHECK-NEXT: OpLifetimeStop %[[#r286]] 24
-; CHECK-NEXT: %[[#r287:]] = OpBitcast %[[#r27]] %[[#r64]]
-; CHECK-NEXT: OpLifetimeStop %[[#r287]] 24
-; CHECK-NEXT: %[[#r288:]] = OpBitcast %[[#r27]] %[[#r58]]
-; CHECK-NEXT: OpLifetimeStop %[[#r288]] 16
-; CHECK-NEXT: %[[#r289:]] = OpBitcast %[[#r27]] %[[#r57]]
-; CHECK-NEXT: OpLifetimeStop %[[#r289]] 16
-; CHECK-NEXT: %[[#r290:]] = OpBitcast %[[#r27]] %[[#r56]]
-; CHECK-NEXT: OpLifetimeStop %[[#r290]] 16
-; CHECK-NEXT: OpReturn
-; CHECK-NEXT: OpFunctionEnd
+; CHECK: %[[#typeInt64:]] = OpTypeInt 64 0
+; CHECK: %[[#typeInt32:]] = OpTypeInt 32 0
+; CHECK: %[[#Num3:]] = OpConstant %[[#typeInt32]] 3
+; CHECK: %[[#Array3x64:]] = OpTypeArray %[[#typeInt64:]] %[[#Num3]]
+; CHECK: %[[#TypeNDRangeStruct:]] = OpTypeStruct %[[#typeInt32]] %[[#Array3x64]] %[[#Array3x64]] %[[#Array3x64]]
+define spir_func void @test_ndrange_1D(i64 noundef %GS1, i64 noundef %LS1, i64 noundef %WO1) local_unnamed_addr #0 {
entry:
+; CHECK-LABEL: Begin function test_ndrange_1D
+; CHECK: %[[#ret1D_1:]] = OpBuildNDRange %[[#TypeNDRangeStruct]] %[[#GS1D:]] %[[#Zero1D:]] %[[#Zero1D:]]
+; CHECK: %[[#ret1D_2:]] = OpBuildNDRange %[[#TypeNDRangeStruct]] %[[#GS1D]] %[[#LS1D:]] %[[#Zero1D]]
+; CHECK: %[[#ret1D_3:]] = OpBuildNDRange %[[#TypeNDRangeStruct]] %[[#GS1D]] %[[#LS1D]] %[[#GO1D:]]
+; CHECK: %[[#ret1D_4:]] = OpBuildNDRange %[[#TypeNDRangeStruct]] %[[#GS1Dc:]] %[[#Zero1D]] %[[#Zero1D]]
+; CHECK: OpFunctionEnd
+ %tmp = alloca %struct.ndrange_t, align 8
+ %tmp1 = alloca %struct.ndrange_t, align 8
+ %tmp2 = alloca %struct.ndrange_t, align 8
+ %tmp3 = alloca %struct.ndrange_t, align 8
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp) #4
+ call spir_func void @_Z10ndrange_1Dm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp, i64 noundef %GS1) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp1) #4
+ call spir_func void @_Z10ndrange_1Dmm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp1, i64 noundef %GS1, i64 noundef %LS1) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp1) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp2) #4
+ call spir_func void @_Z10ndrange_1Dmmm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp2, i64 noundef %WO1, i64 noundef %GS1, i64 noundef %LS1) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp2) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp3) #4
+ call spir_func void @_Z10ndrange_1Dm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp3, i64 noundef 1) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp3) #4
+ ret void
+}
+
+declare spir_func void @_Z10ndrange_1Dm(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, i64 noundef) local_unnamed_addr #1
+declare spir_func void @_Z10ndrange_1Dmm(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, i64 noundef, i64 noundef) local_unnamed_addr #1
+declare spir_func void @_Z10ndrange_1Dmmm(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, i64 noundef, i64 noundef, i64 noundef) local_unnamed_addr #1
+
+define spir_func void @test_ndrange_2D(ptr noundef %GS2, ptr noundef %LS2, ptr noundef %WO2) local_unnamed_addr #0 {
+entry:
+; CHECK-LABEL: Begin function test_ndrange_2D
+; CHECK: %[[#ret2D_1:]] = OpBuildNDRange %[[#TypeNDRangeStruct]] %[[#GS2D_1:]] %[[#Zero2D:]] %[[#Zero2D:]]
+; CHECK: %[[#ret2D_2:]] = OpBuildNDRange %[[#TypeNDRangeStruct]] %[[#GS2D_2:]] %[[#LS2D_2:]] %[[#Zero2D]]
+; CHECK: %[[#ret2D_3:]] = OpBuildNDRange %[[#TypeNDRangeStruct]] %[[#GS2D_3:]] %[[#LS2D_3:]] %[[#GO2D_3:]]
+ %tmp = alloca %struct.ndrange_t, align 8
+ %tmp1 = alloca %struct.ndrange_t, align 8
+ %tmp2 = alloca %struct.ndrange_t, align 8
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp) #4
+ call spir_func void @_Z10ndrange_2DPKm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp, ptr noundef %GS2) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp1) #4
+ call spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp1, ptr noundef %GS2, ptr noundef %LS2) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp1) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp2) #4
+ call spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp2, ptr noundef %WO2, ptr noundef %GS2, ptr noundef %LS2) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp2) #4
+ ret void
+}
+
+declare spir_func void @_Z10ndrange_2DPKm(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, ptr noundef) local_unnamed_addr #1
+declare spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, ptr noundef, ptr noundef) local_unnamed_addr #1
+declare spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #1
+
+define spir_func void @test_ndrange_3D(ptr noundef %GS3, ptr noundef %LS3, ptr noundef %WO3, ptr noundef %GS2) local_unnamed_addr #0 {
+entry:
+; CHECK-LABEL: Begin function test_ndrange_3D
+; CHECK: %[[#ret3D_1:]] = OpBuildNDRange %[[#TypeNDRangeStruct]] %[[#GS3D_1:]] %[[#Zero3D:]] %[[#Zero3D:]]
+; CHECK: %[[#ret3D_2:]] = OpBuildNDRange %[[#TypeNDRangeStruct]] %[[#GS3D_2:]] %[[#LS3D_2:]] %[[#Zero3D]]
+; CHECK: %[[#ret3D_3:]] = OpBuildNDRange %[[#TypeNDRangeStruct]] %[[#GS3D_3:]] %[[#LS3D_3:]] %[[#GO3D_3:]]
+; CHECK: %[[#ret3D_4:]] = OpBuildNDRange %[[#TypeNDRangeStruct]] %[[#GS3D_4:]] %[[#GS3D_4:]] %[[#Zero3D:]]
+; CHECK: %[[#ret3D_5:]] = OpBuildNDRange %[[#TypeNDRangeStruct]] %[[#GS3D_5:]] %[[#GS3D_5:]] %[[#GS3D_5:]]
+; CHECK: %[[#ret3D_6:]] = OpBuildNDRange %[[#TypeNDRangeStruct]] %[[#GS2D_4:]] %[[#Zero2D]] %[[#Zero2D]]
%tmp = alloca %struct.ndrange_t, align 8
%tmp1 = alloca %struct.ndrange_t, align 8
%tmp2 = alloca %struct.ndrange_t, align 8
%tmp3 = alloca %struct.ndrange_t, align 8
%tmp4 = alloca %struct.ndrange_t, align 8
- %GS2 = alloca [2 x i64], align 8
- %LS2 = alloca [2 x i64], align 8
- %WO2 = alloca [2 x i64], align 8
- %tmp5 = alloca %struct.ndrange_t, align 8
- %tmp8 = alloca %struct.ndrange_t, align 8
- %tmp12 = alloca %struct.ndrange_t, align 8
- %tmp15 = alloca %struct.ndrange_t, align 8
- %tmp19 = alloca %struct.ndrange_t, align 8
- %GS3 = alloca [3 x i64], align 8
- %LS3 = alloca [3 x i64], align 8
- %WO3 = alloca [3 x i64], align 8
- %tmp21 = alloca %struct.ndrange_t, align 8
- %tmp24 = alloca %struct.ndrange_t, align 8
- %tmp28 = alloca %struct.ndrange_t, align 8
- %tmp31 = alloca %struct.ndrange_t, align 8
- %tmp35 = alloca %struct.ndrange_t, align 8
- %tmp36 = alloca %struct.ndrange_t, align 8
- %tmp37 = alloca %struct.ndrange_t, align 8
- %tmp38 = alloca %struct.ndrange_t, align 8
- %tmp39 = alloca %struct.ndrange_t, align 8
- %tmp40 = alloca %struct.ndrange_t, align 8
- %GS2c = alloca [2 x i64], align 8
- %LS2c = alloca [2 x i64], align 8
- %WO2c = alloca [2 x i64], align 8
- %tmp42 = alloca %struct.ndrange_t, align 8
- %tmp45 = alloca %struct.ndrange_t, align 8
- %tmp49 = alloca %struct.ndrange_t, align 8
- %tmp52 = alloca %struct.ndrange_t, align 8
- %tmp56 = alloca %struct.ndrange_t, align 8
%GS3c = alloca [3 x i64], align 8
- %LS3c = alloca [3 x i64], align 8
- %WO3c = alloca [3 x i64], align 8
- %tmp58 = alloca %struct.ndrange_t, align 8
- %tmp61 = alloca %struct.ndrange_t, align 8
- %tmp65 = alloca %struct.ndrange_t, align 8
- %tmp68 = alloca %struct.ndrange_t, align 8
- %tmp72 = alloca %struct.ndrange_t, align 8
+ %tmp5 = alloca %struct.ndrange_t, align 8
+ %tmp6 = alloca %struct.ndrange_t, align 8
call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp) #4
- call spir_func void @_Z10ndrange_1Dm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp, i64 noundef 1) #5
+ call spir_func void @_Z10ndrange_3DPKm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp, ptr noundef %GS3) #5
call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp) #4
call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp1) #4
- call spir_func void @_Z10ndrange_1Dmm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp1, i64 noundef 1, i64 noundef 2) #5
+ call spir_func void @_Z10ndrange_3DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp1, ptr noundef %GS3, ptr noundef %LS3) #5
call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp1) #4
call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp2) #4
- call spir_func void @_Z10ndrange_1Dmmm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp2, i64 noundef 3, i64 noundef 1, i64 noundef 2) #5
+ call spir_func void @_Z10ndrange_3DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp2, ptr noundef %WO3, ptr noundef %GS3, ptr noundef %LS3) #5
call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp2) #4
call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp3) #4
- call spir_func void @_Z10ndrange_1Dmm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp3, i64 noundef 1, i64 noundef 1) #5
+ call spir_func void @_Z10ndrange_3DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp3, ptr noundef %GS3, ptr noundef %GS3) #5
call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp3) #4
call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp4) #4
- call spir_func void @_Z10ndrange_1Dmmm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp4, i64 noundef 1, i64 noundef 1, i64 noundef 1) #5
+ call spir_func void @_Z10ndrange_3DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp4, ptr noundef %GS3, ptr noundef %GS3, ptr noundef %GS3) #5
call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp4) #4
- call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %GS2) #4
- call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(16) %GS2, ptr addrspace(2) noundef align 8 dereferenceable(16) @__const.test_ndrange_2D3D.GS2, i64 16, i1 false)
- call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %LS2) #4
- call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(16) %LS2, ptr addrspace(2) noundef align 8 dereferenceable(16) @__const.test_ndrange_2D3D.LS2, i64 16, i1 false)
- call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %WO2) #4
- call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(16) %WO2, ptr addrspace(2) noundef align 8 dereferenceable(16) @__const.test_ndrange_2D3D.WO2, i64 16, i1 false)
+ call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %GS3c) #4
+ call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(24) %GS3c, ptr addrspace(2) noundef align 8 dereferenceable(24) @__const.test_ndrange_3D.GS3c, i64 24, i1 false)
call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp5) #4
- call spir_func void @_Z10ndrange_2DPKm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp5, ptr noundef nonnull %GS2) #5
+ call spir_func void @_Z10ndrange_3DPKm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp5, ptr noundef nonnull %GS3c) #5
call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp5) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp8) #4
- call spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp8, ptr noundef nonnull %GS2, ptr noundef nonnull %LS2) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp8) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp12) #4
- call spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp12, ptr noundef nonnull %WO2, ptr noundef nonnull %GS2, ptr noundef nonnull %LS2) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp12) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp15) #4
- call spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp15, ptr noundef nonnull %GS2, ptr noundef nonnull %GS2) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp15) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp19) #4
- call spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp19, ptr noundef nonnull %GS2, ptr noundef nonnull %GS2, ptr noundef nonnull %GS2) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp19) #4
- call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %GS3) #4
- call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(24) %GS3, ptr addrspace(2) noundef align 8 dereferenceable(24) @__const.test_ndrange_2D3D.GS3, i64 24, i1 false)
- call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %LS3) #4
- call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(24) %LS3, ptr addrspace(2) noundef align 8 dereferenceable(24) @__const.test_ndrange_2D3D.LS3, i64 24, i1 false)
- call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %WO3) #4
- call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(24) %WO3, ptr addrspace(2) noundef align 8 dereferenceable(24) @__const.test_ndrange_2D3D.WO3, i64 24, i1 false)
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp21) #4
- call spir_func void @_Z10ndrange_3DPKm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp21, ptr noundef nonnull %GS3) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp21) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp24) #4
- call spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp24, ptr noundef nonnull %GS3, ptr noundef nonnull %LS3) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp24) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp28) #4
- call spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp28, ptr noundef nonnull %WO3, ptr noundef nonnull %GS3, ptr noundef nonnull %LS3) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp28) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp31) #4
- call spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp31, ptr noundef nonnull %GS3, ptr noundef nonnull %GS3) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp31) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp35) #4
- call spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp35, ptr noundef nonnull %GS3, ptr noundef nonnull %GS3, ptr noundef nonnull %GS3) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp35) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp36) #4
- call spir_func void @_Z10ndrange_1Dm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp36, i64 noundef 1) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp36) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp37) #4
- call spir_func void @_Z10ndrange_1Dmm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp37, i64 noundef 1, i64 noundef 2) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp37) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp38) #4
- call spir_func void @_Z10ndrange_1Dmmm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp38, i64 noundef 3, i64 noundef 1, i64 noundef 2) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp38) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp39) #4
- call spir_func void @_Z10ndrange_1Dmm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp39, i64 noundef 1, i64 noundef 1) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp39) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp40) #4
- call spir_func void @_Z10ndrange_1Dmmm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp40, i64 noundef 1, i64 noundef 1, i64 noundef 1) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp40) #4
- call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %GS2c) #4
- call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(16) %GS2c, ptr addrspace(2) noundef align 8 dereferenceable(16) @__const.test_ndrange_2D3D.GS2c, i64 16, i1 false)
- call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %LS2c) #4
- call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(16) %LS2c, ptr addrspace(2) noundef align 8 dereferenceable(16) @__const.test_ndrange_2D3D.LS2c, i64 16, i1 false)
- call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %WO2c) #4
- call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(16) %WO2c, ptr addrspace(2) noundef align 8 dereferenceable(16) @__const.test_ndrange_2D3D.WO2c, i64 16, i1 false)
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp42) #4
- call spir_func void @_Z10ndrange_2DPKm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp42, ptr noundef nonnull %GS2c) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp42) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp45) #4
- call spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp45, ptr noundef nonnull %GS2c, ptr noundef nonnull %LS2c) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp45) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp49) #4
- call spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp49, ptr noundef nonnull %WO2c, ptr noundef nonnull %GS2c, ptr noundef nonnull %LS2c) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp49) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp52) #4
- call spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp52, ptr noundef nonnull %GS2c, ptr noundef nonnull %GS2c) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp52) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp56) #4
- call spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp56, ptr noundef nonnull %GS2c, ptr noundef nonnull %GS2c, ptr noundef nonnull %GS2c) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp56) #4
- call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %GS3c) #4
- call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(24) %GS3c, ptr addrspace(2) noundef align 8 dereferenceable(24) @__const.test_ndrange_2D3D.GS3c, i64 24, i1 false)
- call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %LS3c) #4
- call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(24) %LS3c, ptr addrspace(2) noundef align 8 dereferenceable(24) @__const.test_ndrange_2D3D.LS3c, i64 24, i1 false)
- call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %WO3c) #4
- call void @llvm.memcpy.p0.p2.i64(ptr noundef nonnull align 8 dereferenceable(24) %WO3c, ptr addrspace(2) noundef align 8 dereferenceable(24) @__const.test_ndrange_2D3D.WO3c, i64 24, i1 false)
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp58) #4
- call spir_func void @_Z10ndrange_3DPKm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp58, ptr noundef nonnull %GS3c) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp58) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp61) #4
- call spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp61, ptr noundef nonnull %GS3c, ptr noundef nonnull %LS3c) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp61) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp65) #4
- call spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp65, ptr noundef nonnull %WO3c, ptr noundef nonnull %GS3c, ptr noundef nonnull %LS3c) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp65) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp68) #4
- call spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp68, ptr noundef nonnull %GS3c, ptr noundef nonnull %GS3c) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp68) #4
- call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp72) #4
- call spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp72, ptr noundef nonnull %GS3c, ptr noundef nonnull %GS3c, ptr noundef nonnull %GS3c) #5
- call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp72) #4
- call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %WO3c) #4
- call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %LS3c) #4
+ call void @llvm.lifetime.start.p0(i64 80, ptr nonnull %tmp6) #4
+ call spir_func void @_Z10ndrange_2DPKm(ptr dead_on_unwind nonnull writable sret(%struct.ndrange_t) align 8 %tmp6, ptr noundef %GS2) #5
+ call void @llvm.lifetime.end.p0(i64 80, ptr nonnull %tmp6) #4
call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %GS3c) #4
- call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %WO2c) #4
- call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %LS2c) #4
- call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %GS2c) #4
- call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %WO3) #4
- call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %LS3) #4
- call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %GS3) #4
- call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %WO2) #4
- call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %LS2) #4
- call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %GS2) #4
ret void
}
-declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1
-declare spir_func void @_Z10ndrange_1Dm(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, i64 noundef) local_unnamed_addr #2
-declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1
-declare spir_func void @_Z10ndrange_1Dmm(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, i64 noundef, i64 noundef) local_unnamed_addr #2
-declare spir_func void @_Z10ndrange_1Dmmm(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, i64 noundef, i64 noundef, i64 noundef) local_unnamed_addr #2
-declare void @llvm.memcpy.p0.p2.i64(ptr noalias nocapture writeonly, ptr addrspace(2) noalias nocapture readonly, i64, i1 immarg) #3
-declare spir_func void @_Z10ndrange_2DPKm(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, ptr noundef) local_unnamed_addr #2
-declare spir_func void @_Z10ndrange_2DPKmS0_(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, ptr noundef, ptr noundef) local_unnamed_addr #2
-declare spir_func void @_Z10ndrange_2DPKmS0_S0_(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #2
-declare spir_func void @_Z10ndrange_3DPKm(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, ptr noundef) local_unnamed_addr #2
+declare spir_func void @_Z10ndrange_3DPKm(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, ptr noundef) local_unnamed_addr #1
+declare spir_func void @_Z10ndrange_3DPKmS0_(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, ptr noundef, ptr noundef) local_unnamed_addr #1
+declare spir_func void @_Z10ndrange_3DPKmS0_S0_(ptr dead_on_unwind writable sret(%struct.ndrange_t) align 8, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #1
More information about the llvm-commits
mailing list