Skip to content

Commit 8ee8632

Browse files
fda0igcbot
authored andcommitted
JointMatrix canonicalized GEP patching for opaque pointers
This commit revisits functionality introduced by b74e645. Previous solution didn't work on llvm16 + opaque pointers. Additionally it assumed specific bitcast -> GEP pattern which wasn't guaranteed to work in the future if SYCL codegen changed. New algorithm does recursive search on users of AllocaInst to find GEP and lifetime instructions that need fixing.
1 parent d775e45 commit 8ee8632

File tree

5 files changed

+202
-164
lines changed

5 files changed

+202
-164
lines changed

IGC/Compiler/Optimizer/OpenCLPasses/JointMatrixFuncsResolutionPass/JointMatrixFuncsResolutionPass.cpp

Lines changed: 61 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -2764,36 +2764,6 @@ void JointMatrixFuncsResolutionPass::visitCallInst(CallInst &CI) {
27642764
return;
27652765
}
27662766

2767-
// Update size of allocated element in llvm.lifetime.start/end intrincics
2768-
if (auto II = dyn_cast<IntrinsicInst>(&CI)) {
2769-
if (II->getIntrinsicID() == Intrinsic::lifetime_start || II->getIntrinsicID() == Intrinsic::lifetime_end) {
2770-
2771-
// track pointer operand to alloca instr
2772-
auto &DL = CI.getModule()->getDataLayout();
2773-
Value *obj = IGCLLVM::getUnderlyingObject(II->getOperand(1), DL);
2774-
2775-
if (AllocaInst *AI = dyn_cast_or_null<AllocaInst>(obj)) {
2776-
// if alloca requires resolving, resolve alloca, otherwise do not touch intrinsic
2777-
// as it is not related to Joint Matrix type
2778-
if (!isOrContainsMatrixType(AI->getAllocatedType()))
2779-
return;
2780-
2781-
ResolveSIMDSize(CI.getParent()->getParent());
2782-
AllocaInst *NAI = cast<AllocaInst>(Resolve(AI));
2783-
auto allocaSizeInBits = IGCLLVM::makeOptional(NAI->getAllocationSizeInBits(DL));
2784-
if (!allocaSizeInBits.has_value())
2785-
return;
2786-
uint64_t newSize = (uint64_t)(allocaSizeInBits.value() / 8);
2787-
2788-
// update first argument, if it is constant int
2789-
if (auto *ConstInt = dyn_cast<ConstantInt>(CI.getOperand(0))) {
2790-
CI.setOperand(0, ConstantInt::get(ConstInt->getType(), newSize));
2791-
LLVM_DEBUG(dbgs() << " -- UPDATED CALL: " << CI << "\n");
2792-
}
2793-
}
2794-
}
2795-
}
2796-
27972767
if (isAnyFunctionArgMatrixType(func))
27982768
ResolveCallFuncWithMatrixArgs(ResolvedFuncSignatures[func], &CI);
27992769
}
@@ -2879,6 +2849,50 @@ DIType *getOrCreateType(Type *T, Module *M) {
28792849
return diType;
28802850
}
28812851

2852+
void JointMatrixFuncsResolutionPass::RecursiveSearchAndFixCanonicalizdGEPandLifetime(
2853+
std::unordered_set<llvm::Value *> &visited, const DataLayout &DL, Value *root, uint64_t matrixTypeAllocSize,
2854+
uint64_t totalAllocationSize) {
2855+
auto insertToVisited = visited.insert(root);
2856+
if (!insertToVisited.second) // root was already visited
2857+
return;
2858+
2859+
// Depth first recursive traversal of root users
2860+
for (auto U : root->users()) {
2861+
// Only traverse children nodes if current node is a cast or a PHI node.
2862+
if (isa<CastInst>(U) || isa<PHINode>(U)) {
2863+
LLVM_DEBUG(dbgs() << "DFS: visiting users of " << *U << '\n');
2864+
RecursiveSearchAndFixCanonicalizdGEPandLifetime(visited, DL, U, matrixTypeAllocSize, totalAllocationSize);
2865+
continue;
2866+
}
2867+
2868+
if (auto GEP = dyn_cast<GetElementPtrInst>(U)) {
2869+
// Update canonicalized i8 GEP:
2870+
// getelementptr i8, ptr %x, i64 <const>
2871+
if (GEP->getSourceElementType()->isIntegerTy(8) && GEP->hasAllConstantIndices() && GEP->getNumIndices() == 1) {
2872+
LLVM_DEBUG(dbgs() << "Found canonicalized i8 GEP: " << *GEP << "\n");
2873+
auto offset = cast<ConstantInt>(GEP->getOperand(1));
2874+
uint64_t pointerSize = DL.getPointerSizeInBits(GEP->getPointerAddressSpace()) / 8;
2875+
uint64_t offsetInElements = offset->getZExtValue() / pointerSize;
2876+
uint64_t correctOffset = offsetInElements * matrixTypeAllocSize;
2877+
ConstantInt *newOffsetConstant = ConstantInt::get(offset->getType(), correctOffset);
2878+
GEP->setOperand(1, newOffsetConstant);
2879+
LLVM_DEBUG(dbgs().indent(2) << "Fixed index: " << *GEP << "\n");
2880+
}
2881+
} else if (auto II = dyn_cast<IntrinsicInst>(U)) {
2882+
// Update size for lifetime intrinsics
2883+
if (II->getIntrinsicID() == Intrinsic::lifetime_start || II->getIntrinsicID() == Intrinsic::lifetime_end) {
2884+
if (auto constInt = dyn_cast<ConstantInt>(II->getOperand(0))) {
2885+
LLVM_DEBUG(dbgs() << "Found lifetime intrinsic for joint matrix array allocation" << *II << '\n');
2886+
II->setOperand(0, ConstantInt::get(constInt->getType(), totalAllocationSize));
2887+
LLVM_DEBUG(dbgs().indent(2) << "Fixed size: " << *II << "\n");
2888+
}
2889+
}
2890+
} else {
2891+
LLVM_DEBUG(dbgs() << "Skipping joint matrix array alloca user: " << *U << '\n');
2892+
}
2893+
}
2894+
}
2895+
28822896
void JointMatrixFuncsResolutionPass::visitAllocaInst(AllocaInst &I) {
28832897
LLVM_DEBUG(dbgs() << " - VISIT: " << I << "\n");
28842898

@@ -2890,9 +2904,10 @@ void JointMatrixFuncsResolutionPass::visitAllocaInst(AllocaInst &I) {
28902904

28912905
ResolveSIMDSize(I.getParent()->getParent());
28922906

2893-
Value *newInst = ResolveGeneric(&I);
2907+
AllocaInst *newInst = cast<AllocaInst>(ResolveGeneric(&I));
28942908

2895-
if (newInst) {
2909+
// update debug info
2910+
{
28962911
TinyPtrVector<DbgDeclareInst *> DDIs;
28972912
for (DbgVariableIntrinsic *DVI : FindDbgAddrUses(&I))
28982913
if (auto *DDI = dyn_cast<DbgDeclareInst>(DVI))
@@ -2913,6 +2928,20 @@ void JointMatrixFuncsResolutionPass::visitAllocaInst(AllocaInst &I) {
29132928
ddi->eraseFromParent();
29142929
}
29152930
}
2931+
2932+
// update GEPs and lifetime intrinsics
2933+
{
2934+
Type *unresolvedMatrixType = getContainedMatrixType(I.getAllocatedType());
2935+
Type *resolvedMatrixType = ResolveTypes(unresolvedMatrixType);
2936+
2937+
const DataLayout &DL = newInst->getModule()->getDataLayout();
2938+
uint64_t matrixTypeSize = DL.getTypeAllocSize(resolvedMatrixType);
2939+
uint64_t totalAllocSize =
2940+
IGCLLVM::makeOptional(newInst->getAllocationSizeInBits(DL)).value_or(TypeSize(0, false)) / 8;
2941+
// We have to use old alloca instruction I because its uses weren't replaced by newInst yet.
2942+
std::unordered_set<Value *> visited;
2943+
RecursiveSearchAndFixCanonicalizdGEPandLifetime(visited, DL, &I, matrixTypeSize, totalAllocSize);
2944+
}
29162945
}
29172946

29182947
void JointMatrixFuncsResolutionPass::visitAddrSpaceCastInst(AddrSpaceCastInst &I) {
@@ -2969,46 +2998,6 @@ void JointMatrixFuncsResolutionPass::visitGetElementPtrInst(GetElementPtrInst &G
29692998
return;
29702999

29713000
Type *GEPEltType = GEP.getSourceElementType();
2972-
2973-
// After constant GEPs are canonicalized to i8 types, we may get patterns like below:
2974-
//
2975-
// %8 = bitcast [4 x [4 x %"struct.sycl::_V1::ext::oneapi::experimental::matrix::joint_matrix"]]* %tC.i to i8*
2976-
// %arrayctor.end.i = getelementptr inbounds i8, i8* %8, i64 128
2977-
//
2978-
// It is not correct, because
2979-
// original offset was 16 elements of matrix type. Matrix type before resolution is represented as pointer
2980-
// Pointer is typically 8 bytes, hence offset of 128 bytes is calculated as 16 x 8 = 128
2981-
// The real offset would be 16 matrix types after resolution, not pointer types.
2982-
// So to fix the offset, we need calculate the offset in matrix type, taking into account pointer type size
2983-
// Then we need calculate real matrix type size after resolution in bytes
2984-
// Then real offset in bytes will be multiplicaiton of offset in matrix types and size of matrix type in bytes
2985-
//
2986-
// For example, if matrix type was resolved like that:
2987-
// %"struct.sycl::_V1::ext::oneapi::experimental::matrix::joint_matrix.resolved" = type { <8 x float> }
2988-
// offset will be 16 * (8 * 4) = 512:
2989-
//
2990-
// %arrayctor.end.i = getelementptr inbounds i8, i8* %8, i64 512
2991-
BitCastInst *BC = dyn_cast<BitCastInst>(GEP.getOperand(0));
2992-
2993-
if (GEPEltType->isIntegerTy(8) && BC && (GEP.getNumIndices() == 1) && GEP.hasAllConstantIndices()) {
2994-
if (Type *BCSrcTy = BC->getSrcTy(); BCSrcTy->isPointerTy()) {
2995-
if (Type *unresolvedMatTy = getContainedMatrixType(BCSrcTy)) {
2996-
2997-
// Calculate offset based on matrix type
2998-
ConstantInt *index = cast<ConstantInt>(GEP.getOperand(1));
2999-
auto &DL = GEP.getModule()->getDataLayout();
3000-
uint64_t pointerSizeInBytes = DL.getPointerSizeInBits(GEP.getPointerAddressSpace()) / 8;
3001-
uint64_t offsetInElements = index->getZExtValue() / pointerSizeInBytes;
3002-
3003-
// Calculate correct offset in bytes and update GEP
3004-
uint64_t elementSize = (uint64_t)DL.getTypeAllocSize(ResolveTypes(unresolvedMatTy));
3005-
uint64_t correctOffset = offsetInElements * elementSize;
3006-
GEP.idx_begin()->set(ConstantInt::get(index->getType(), correctOffset));
3007-
return;
3008-
}
3009-
}
3010-
}
3011-
30123001
if (!isOrContainsMatrixType(GEPEltType))
30133002
return;
30143003

IGC/Compiler/Optimizer/OpenCLPasses/JointMatrixFuncsResolutionPass/JointMatrixFuncsResolutionPass.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ class JointMatrixFuncsResolutionPass final : public llvm::ModulePass,
8484
IGC::JointMatrixTypeDescription *outDescription);
8585
#endif
8686

87+
void RecursiveSearchAndFixCanonicalizdGEPandLifetime(std::unordered_set<llvm::Value *> &visited,
88+
const llvm::DataLayout &DL, llvm::Value *rootValue,
89+
uint64_t matrixTypeAllocSize, uint64_t totalAllocationSize);
8790
llvm::StringRef GetMatrixTypeName(llvm::Type *opaqueType);
8891
bool SetLayoutFromUse(IGC::JointMatrixTypeDescription *outDescription);
8992
unsigned GetUseFromLegacyLayout(unsigned int legacyLayout);

IGC/Compiler/tests/JointMatrixFuncsResolutionPass/offset_correction-typed-pointers-targetextensiontype.ll

Lines changed: 58 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ target triple = "spir64-unknown-unknown"
3030
; CHECK-LABEL: define spir_kernel void @test(
3131
; CHECK-SAME: i64 [[OFFSET:%.*]], i8 addrspace(1)* [[PTR:%.*]], i8* [[PTR1:%.*]]) {
3232
define spir_kernel void @test(i64 %offset, i8 addrspace(1)* %ptr, i8* %ptr1) {
33+
entry:
3334

34-
; CHECK-NEXT: [[TC_I1:%.*]] = alloca [4 x [4 x %"struct::joint_matrix::C.resolved"]], align 8
35+
; CHECK: [[TC_I1:%.*]] = alloca [4 x [4 x %"struct::joint_matrix::C.resolved"]], align 8
3536
; CHECK-NEXT: [[TA_I3:%.*]] = alloca [4 x [2 x %"struct::joint_matrix::A.resolved"]], align 8
3637
; CHECK-NEXT: [[TB_I5:%.*]] = alloca [4 x [2 x %"struct::joint_matrix::B.resolved"]], align 8
3738
; CHECK-NEXT: [[TI_I:%.*]] = alloca [4 x [4 x %"struct::almost_joint_matrix"]], align 8
@@ -49,74 +50,89 @@ define spir_kernel void @test(i64 %offset, i8 addrspace(1)* %ptr, i8* %ptr1) {
4950
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 128, i8* [[TMP2]])
5051
; CHECK-NEXT: [[TMP3:%.*]] = bitcast [4 x [2 x %"struct::joint_matrix::B.resolved"]]* [[TB_I5]] to i8*
5152
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 256, i8* [[TMP3]])
52-
%1 = bitcast [4 x [4 x %"struct::joint_matrix::C"]]* %tC.i to i8*
53-
call void @llvm.lifetime.start.p0i8(i64 128, i8* %1)
54-
%2 = bitcast [4 x [2 x %"struct::joint_matrix::A"]]* %tA.i to i8*
55-
call void @llvm.lifetime.start.p0i8(i64 64, i8* %2)
56-
%3 = bitcast [4 x [2 x %"struct::joint_matrix::B"]]* %tB.i to i8*
57-
call void @llvm.lifetime.start.p0i8(i64 64, i8* %3)
58-
59-
; Update GEP offsets
53+
%b1 = bitcast [4 x [4 x %"struct::joint_matrix::C"]]* %tC.i to i8*
54+
call void @llvm.lifetime.start.p0i8(i64 128, i8* %b1)
55+
%b2 = bitcast [4 x [2 x %"struct::joint_matrix::A"]]* %tA.i to i8*
56+
call void @llvm.lifetime.start.p0i8(i64 64, i8* %b2)
57+
%b3 = bitcast [4 x [2 x %"struct::joint_matrix::B"]]* %tB.i to i8*
58+
call void @llvm.lifetime.start.p0i8(i64 64, i8* %b3)
59+
60+
; Update GEP offsets coming from alloca directly
6061
; CHECK-NEXT: [[TMP4:%.*]] = bitcast [4 x [4 x %"struct::joint_matrix::C.resolved"]]* [[TC_I1]] to i8*
6162
; CHECK-NEXT: [[I1:%.*]] = getelementptr inbounds i8, i8* [[TMP4]], i64 512
6263
; CHECK-NEXT: [[TMP5:%.*]] = bitcast [4 x [2 x %"struct::joint_matrix::A.resolved"]]* [[TA_I3]] to i8*
6364
; CHECK-NEXT: [[I2:%.*]] = getelementptr inbounds i8, i8* [[TMP5]], i64 128
6465
; CHECK-NEXT: [[TMP6:%.*]] = bitcast [4 x [2 x %"struct::joint_matrix::B.resolved"]]* [[TB_I5]] to i8*
6566
; CHECK-NEXT: [[I3:%.*]] = getelementptr inbounds i8, i8* [[TMP6]], i64 256
66-
%4 = bitcast [4 x [4 x %"struct::joint_matrix::C"]]* %tC.i to i8*
67-
%i1 = getelementptr inbounds i8, i8* %4, i64 128
68-
%5 = bitcast [4 x [2 x %"struct::joint_matrix::A"]]* %tA.i to i8*
69-
%i2 = getelementptr inbounds i8, i8* %5, i64 64
70-
%6 = bitcast [4 x [2 x %"struct::joint_matrix::B"]]* %tB.i to i8*
71-
%i3 = getelementptr inbounds i8, i8* %6, i64 64
67+
%b4 = bitcast [4 x [4 x %"struct::joint_matrix::C"]]* %tC.i to i8*
68+
%i1 = getelementptr inbounds i8, i8* %b4, i64 128
69+
%b5 = bitcast [4 x [2 x %"struct::joint_matrix::A"]]* %tA.i to i8*
70+
%i2 = getelementptr inbounds i8, i8* %b5, i64 64
71+
%b6 = bitcast [4 x [2 x %"struct::joint_matrix::B"]]* %tB.i to i8*
72+
%i3 = getelementptr inbounds i8, i8* %b6, i64 64
7273

7374
; Do not touch if offest is not a constant
7475
; CHECK-NEXT: [[TMP7:%.*]] = bitcast [4 x [4 x %"struct::joint_matrix::C.resolved"]]* [[TC_I1]] to i8*
7576
; CHECK-NEXT: [[I4:%.*]] = getelementptr inbounds i8, i8* [[TMP7]], i64 [[OFFSET]]
76-
%7 = bitcast [4 x [4 x %"struct::joint_matrix::C"]]* %tC.i to i8*
77-
%i4 = getelementptr inbounds i8, i8* %7, i64 %offset
77+
%b7 = bitcast [4 x [4 x %"struct::joint_matrix::C"]]* %tC.i to i8*
78+
%i4 = getelementptr inbounds i8, i8* %b7, i64 %offset
7879

79-
; no change: GEP operand is not a result of bitcast
80+
; no change: GEP operand is comming from kernel argument - not from matrix type
8081
; CHECK-NEXT: [[I5:%.*]] = getelementptr inbounds i8, i8* [[PTR1]], i64 128
8182
%i5 = getelementptr inbounds i8, i8* %ptr1, i64 128
8283

83-
; Do not touch if bitcast is not for matrix type
84+
; no change: GEP comes from bitcast that doesn't come from matrix type
8485
; CHECK-NEXT: [[TMP8:%.*]] = bitcast [4 x [4 x %"struct::almost_joint_matrix"]]* [[TI_I]] to i8*
8586
; CHECK-NEXT: [[I6:%.*]] = getelementptr inbounds i8, i8* [[TMP8]], i64 128
86-
%8 = bitcast [4 x [4 x %"struct::almost_joint_matrix"]]* %tI.i to i8*
87-
%i6 = getelementptr inbounds i8, i8* %8, i64 128
87+
%b8 = bitcast [4 x [4 x %"struct::almost_joint_matrix"]]* %tI.i to i8*
88+
%i6 = getelementptr inbounds i8, i8* %b8, i64 128
8889

8990
; no change - GEP is not based on i8
9091
; CHECK-NEXT: [[TMP9:%.*]] = bitcast [4 x [4 x %"struct::joint_matrix::C.resolved"]]* [[TC_I1]] to i16*
9192
; CHECK-NEXT: [[ARRAYCTOR_END_I:%.*]] = getelementptr inbounds i16, i16* [[TMP9]], i64 128
92-
%9 = bitcast [4 x [4 x %"struct::joint_matrix::C"]]* %tC.i to i16*
93-
%arrayctor.end.i = getelementptr inbounds i16, i16* %9, i64 128
93+
%b9 = bitcast [4 x [4 x %"struct::joint_matrix::C"]]* %tC.i to i16*
94+
%arrayctor.end.i = getelementptr inbounds i16, i16* %b9, i64 128
95+
br label %loop_header
9496

97+
; Test going through phi value + check that we aren't doing ininite recursion
98+
loop_header:
99+
%loop_cond = phi i1 [1, %entry], [0, %loop_header]
100+
%loop_matrix = phi [4 x [4 x %"struct::joint_matrix::C"]]* [%tC.i, %entry], [%loop_matrix, %loop_header]
101+
102+
; Update GEP offsets coming from phi value
103+
; CHECK: [[TMP10:%.*]] = bitcast [4 x [4 x %"struct::joint_matrix::C.resolved"]]* {{.*}} to i8*
104+
; CHECK-NEXT: {{.*}} = getelementptr inbounds i8, i8* [[TMP10]], i64 128
105+
%b10 = bitcast [4 x [4 x %"struct::joint_matrix::C"]]* %tC.i to i8*
106+
%i7 = getelementptr inbounds i8, i8* %b10, i64 32
107+
108+
br i1 %loop_cond, label %loop_header, label %after_loop
109+
110+
after_loop:
95111
; Life time end size update
96-
; CHECK-NEXT: [[TMP10:%.*]] = bitcast [4 x [2 x %"struct::joint_matrix::B.resolved"]]* [[TB_I5]] to i8*
97-
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 256, i8* [[TMP10]])
98-
; CHECK-NEXT: [[TMP11:%.*]] = bitcast [4 x [2 x %"struct::joint_matrix::A.resolved"]]* [[TA_I3]] to i8*
99-
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 128, i8* [[TMP11]])
100-
; CHECK-NEXT: [[TMP12:%.*]] = bitcast [4 x [4 x %"struct::joint_matrix::C.resolved"]]* [[TC_I1]] to i8*
101-
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 512, i8* [[TMP12]])
102-
%10 = bitcast [4 x [2 x %"struct::joint_matrix::B"]]* %tB.i to i8*
103-
call void @llvm.lifetime.end.p0i8(i64 64, i8* %10)
104-
%11 = bitcast [4 x [2 x %"struct::joint_matrix::A"]]* %tA.i to i8*
105-
call void @llvm.lifetime.end.p0i8(i64 64, i8* %11)
106-
%12 = bitcast [4 x [4 x %"struct::joint_matrix::C"]]* %tC.i to i8*
107-
call void @llvm.lifetime.end.p0i8(i64 128, i8* %12)
112+
; CHECK: [[TMP11:%.*]] = bitcast [4 x [2 x %"struct::joint_matrix::B.resolved"]]* [[TB_I5]] to i8*
113+
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 256, i8* [[TMP11]])
114+
; CHECK-NEXT: [[TMP12:%.*]] = bitcast [4 x [2 x %"struct::joint_matrix::A.resolved"]]* [[TA_I3]] to i8*
115+
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 128, i8* [[TMP12]])
116+
; CHECK-NEXT: [[TMP13:%.*]] = bitcast [4 x [4 x %"struct::joint_matrix::C.resolved"]]* [[TC_I1]] to i8*
117+
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 512, i8* [[TMP13]])
118+
%b11 = bitcast [4 x [2 x %"struct::joint_matrix::B"]]* %tB.i to i8*
119+
call void @llvm.lifetime.end.p0i8(i64 64, i8* %b11)
120+
%b12 = bitcast [4 x [2 x %"struct::joint_matrix::A"]]* %tA.i to i8*
121+
call void @llvm.lifetime.end.p0i8(i64 64, i8* %b12)
122+
%b13 = bitcast [4 x [4 x %"struct::joint_matrix::C"]]* %tC.i to i8*
123+
call void @llvm.lifetime.end.p0i8(i64 128, i8* %b13)
108124

109125
; do not touch life time intrinsics if not for Joint Matrix types
110126
; CHECK-NEXT: [[GROUPID_ASCAST:%.*]] = addrspacecast [3 x i64]* [[GROUPID]] to [3 x i64] addrspace(4)*
111-
; CHECK-NEXT: [[TMP13:%.*]] = bitcast [3 x i64]* [[GROUPID]] to i8*
112-
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 24, i8* [[TMP13]])
113127
; CHECK-NEXT: [[TMP14:%.*]] = bitcast [3 x i64]* [[GROUPID]] to i8*
114-
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 24, i8* [[TMP14]])
128+
; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 24, i8* [[TMP14]])
129+
; CHECK-NEXT: [[TMP15:%.*]] = bitcast [3 x i64]* [[GROUPID]] to i8*
130+
; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 24, i8* [[TMP15]])
115131
%GroupID.ascast = addrspacecast [3 x i64]* %GroupID to [3 x i64] addrspace(4)*
116-
%13 = bitcast [3 x i64]* %GroupID to i8*
117-
call void @llvm.lifetime.start.p0i8(i64 24, i8* %13)
118-
%14 = bitcast [3 x i64]* %GroupID to i8*
119-
call void @llvm.lifetime.end.p0i8(i64 24, i8* %14)
132+
%b14 = bitcast [3 x i64]* %GroupID to i8*
133+
call void @llvm.lifetime.start.p0i8(i64 24, i8* %b14)
134+
%b15 = bitcast [3 x i64]* %GroupID to i8*
135+
call void @llvm.lifetime.end.p0i8(i64 24, i8* %b15)
120136

121137
; CHECK-NEXT: ret void
122138
ret void

0 commit comments

Comments
 (0)