[llvm] [SPIR-V] Fix generation of invalid SPIR-V in cases of bitcasts between pointers and null pointers are used in the input LLVM IR (PR #118298)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 2 06:29:20 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-spir-v
Author: Vyacheslav Levytskyy (VyacheslavLevytskyy)
<details>
<summary>Changes</summary>
This PR resolved the following issues:
(1) There are rare but possible cases when there are bitcasts between pointers intertwined in a sophisticated way with loads, stores, function calls and other instructions that are part of type deduction. In this case we must account for inserted bitcasts between pointers rather than just ignore them.
(2) Null pointers have the same constant representation but different types. Type info from Intrinsic::spv_track_constant() refers to the opaque (untyped) pointer, so that each MF/v-reg pair would fall into the same Const record in Duplicate Tracker and would be represented by a single OpConstantNull instruction, unless we use precise pointee type info. We must be able to distinguish one constant (null) pointer from another to avoid generating invalid code with inconsistent types of operands.
---
Patch is 220.45 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/118298.diff
3 Files Affected:
- (modified) llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp (+45-18)
- (modified) llvm/test/CodeGen/SPIRV/transcoding/OpPhi_ArgumentsPlaceholders.ll (+6-5)
- (added) llvm/test/CodeGen/SPIRV/validate/sycl-tangle-group-algorithms.ll (+4673)
``````````diff
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index e6f136cc81b4b4..82d354a3e3a228 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -475,7 +475,7 @@ void SPIRVEmitIntrinsics::propagateElemType(
DenseMap<Function *, CallInst *> Ptrcasts;
SmallVector<User *> Users(Op->users());
for (auto *U : Users) {
- if (!isa<Instruction>(U) || isa<BitCastInst>(U) || isSpvIntrinsic(U))
+ if (!isa<Instruction>(U) || isSpvIntrinsic(U))
continue;
if (!VisitedSubst.insert(std::make_pair(U, Op)).second)
continue;
@@ -506,7 +506,7 @@ void SPIRVEmitIntrinsics::propagateElemTypeRec(
return;
SmallVector<User *> Users(Op->users());
for (auto *U : Users) {
- if (!isa<Instruction>(U) || isa<BitCastInst>(U) || isSpvIntrinsic(U))
+ if (!isa<Instruction>(U) || isSpvIntrinsic(U))
continue;
if (!VisitedSubst.insert(std::make_pair(U, Op)).second)
continue;
@@ -958,6 +958,14 @@ void SPIRVEmitIntrinsics::deduceOperandElementType(
return;
Uncomplete = isTodoType(I);
Ops.push_back(std::make_pair(Ref->getPointerOperand(), 0));
+ } else if (auto *Ref = dyn_cast<BitCastInst>(I)) {
+ if (!isPointerTy(I->getType()))
+ return;
+ KnownElemTy = GR->findDeducedElementType(I);
+ if (!KnownElemTy)
+ return;
+ Uncomplete = isTodoType(I);
+ Ops.push_back(std::make_pair(Ref->getOperand(0), 0));
} else if (auto *Ref = dyn_cast<GetElementPtrInst>(I)) {
if (GR->findDeducedElementType(Ref->getPointerOperand()))
return;
@@ -1030,7 +1038,6 @@ void SPIRVEmitIntrinsics::deduceOperandElementType(
}
}
}
- TypeValidated.insert(I);
// Non-recursive update of types in the function uncomplete returns.
// This may happen just once per a function, the latch is a pair of
// findDeducedElementType(F) / addDeducedElementType(F, ...).
@@ -1043,6 +1050,7 @@ void SPIRVEmitIntrinsics::deduceOperandElementType(
} else if (UncompleteRets) {
UncompleteRets->insert(I);
}
+ TypeValidated.insert(I);
return;
}
Uncomplete = isTodoType(CurrF);
@@ -1369,10 +1377,6 @@ void SPIRVEmitIntrinsics::replacePointerOperandWithPtrCast(
Instruction *I, Value *Pointer, Type *ExpectedElementType,
unsigned OperandToReplace, IRBuilder<> &B) {
TypeValidated.insert(I);
- // If Pointer is the result of nop BitCastInst (ptr -> ptr), use the source
- // pointer instead. The BitCastInst should be later removed when visited.
- while (BitCastInst *BC = dyn_cast<BitCastInst>(Pointer))
- Pointer = BC->getOperand(0);
// Do not emit spv_ptrcast if Pointer's element type is ExpectedElementType
Type *PointerElemTy = deduceElementTypeHelper(Pointer, false);
@@ -1759,8 +1763,7 @@ bool SPIRVEmitIntrinsics::insertAssignPtrTypeIntrs(Instruction *I,
IRBuilder<> &B,
bool UnknownElemTypeI8) {
reportFatalOnTokenType(I);
- if (!isPointerTy(I->getType()) || !requireAssignType(I) ||
- isa<BitCastInst>(I))
+ if (!isPointerTy(I->getType()) || !requireAssignType(I))
return false;
setInsertPointAfterDef(B, I);
@@ -1861,8 +1864,9 @@ void SPIRVEmitIntrinsics::insertSpirvDecorations(Instruction *I,
void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I,
IRBuilder<> &B) {
auto *II = dyn_cast<IntrinsicInst>(I);
- if (II && II->getIntrinsicID() == Intrinsic::spv_const_composite &&
- TrackConstants) {
+ bool IsConstComposite =
+ II && II->getIntrinsicID() == Intrinsic::spv_const_composite;
+ if (IsConstComposite && TrackConstants) {
setInsertPointAfterDef(B, I);
auto t = AggrConsts.find(I);
assert(t != AggrConsts.end());
@@ -1886,12 +1890,27 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I,
: B.SetInsertPoint(I);
BPrepared = true;
}
+ Type *OpTy = Op->getType();
Value *OpTyVal = Op;
- if (Op->getType()->isTargetExtTy())
- OpTyVal = PoisonValue::get(Op->getType());
- auto *NewOp = buildIntrWithMD(Intrinsic::spv_track_constant,
- {Op->getType(), OpTyVal->getType()}, Op,
- OpTyVal, {}, B);
+ if (OpTy->isTargetExtTy())
+ OpTyVal = PoisonValue::get(OpTy);
+ CallInst *NewOp =
+ buildIntrWithMD(Intrinsic::spv_track_constant,
+ {OpTy, OpTyVal->getType()}, Op, OpTyVal, {}, B);
+ Type *OpElemTy = nullptr;
+ if (!IsConstComposite && isPointerTy(OpTy) &&
+ (OpElemTy = GR->findDeducedElementType(Op)) != nullptr &&
+ OpElemTy != IntegerType::getInt8Ty(I->getContext())) {
+ buildAssignPtr(B, IntegerType::getInt8Ty(I->getContext()), NewOp);
+ SmallVector<Type *, 2> Types = {OpTy, OpTy};
+ SmallVector<Value *, 2> Args = {
+ NewOp, buildMD(PoisonValue::get(OpElemTy)),
+ B.getInt32(getPointerAddressSpace(OpTy))};
+ CallInst *PtrCasted =
+ B.CreateIntrinsic(Intrinsic::spv_ptrcast, {Types}, Args);
+ buildAssignPtr(B, OpElemTy, PtrCasted);
+ NewOp = PtrCasted;
+ }
I->setOperand(OpNo, NewOp);
}
}
@@ -2022,8 +2041,16 @@ void SPIRVEmitIntrinsics::processParamTypes(Function *F, IRBuilder<> &B) {
if (!isUntypedPointerTy(Arg->getType()))
continue;
Type *ElemTy = GR->findDeducedElementType(Arg);
- if (!ElemTy && (ElemTy = deduceFunParamElementType(F, OpIdx)) != nullptr)
- buildAssignPtr(B, ElemTy, Arg);
+ if (!ElemTy && (ElemTy = deduceFunParamElementType(F, OpIdx)) != nullptr) {
+ if (CallInst *AssignCI = GR->findAssignPtrTypeInstr(Arg)) {
+ DenseSet<std::pair<Value *, Value *>> VisitedSubst;
+ updateAssignType(AssignCI, Arg, PoisonValue::get(ElemTy));
+ propagateElemType(Arg, IntegerType::getInt8Ty(F->getContext()),
+ VisitedSubst);
+ } else {
+ buildAssignPtr(B, ElemTy, Arg);
+ }
+ }
}
}
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/OpPhi_ArgumentsPlaceholders.ll b/llvm/test/CodeGen/SPIRV/transcoding/OpPhi_ArgumentsPlaceholders.ll
index c98fef3631e04b..ee5596ed38b1b7 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/OpPhi_ArgumentsPlaceholders.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/OpPhi_ArgumentsPlaceholders.ll
@@ -12,7 +12,8 @@
;; }
;; }
-; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
; XFAIL: *
%struct.Node = type { %struct.Node.0 addrspace(1)* }
@@ -25,8 +26,8 @@ entry:
for.cond: ; preds = %for.inc, %entry
%pNode.0 = phi %struct.Node addrspace(1)* [ %pNodes, %entry ], [ %1, %for.inc ]
%j.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
-; CHECK-SPIRV: %[[#]] = OpPhi %[[#]] %[[#]] %[[#]] %[[#BitcastResultId:]] %[[#]]
-; CHECK-SPIRV-NEXT: OpPhi
+; CHECK: %[[#]] = OpPhi %[[#]] %[[#]] %[[#]] %[[#BitcastResultId:]] %[[#]]
+; CHECK-NEXT: OpPhi
%cmp = icmp slt i32 %j.0, 10
br i1 %cmp, label %for.body, label %for.end
@@ -36,8 +37,8 @@ for.body: ; preds = %for.cond
%0 = load %struct.Node.0 addrspace(1)*, %struct.Node.0 addrspace(1)* addrspace(1)* %pNext, align 4
%1 = bitcast %struct.Node.0 addrspace(1)* %0 to %struct.Node addrspace(1)*
-; CHECK-SPIRV: %[[#LoadResultId:]] = OpLoad %[[#]]
-; CHECK-SPIRV: %[[#BitcastResultId]] = OpBitcast %[[#]] %[[#LoadResultId]]
+; CHECK: %[[#LoadResultId:]] = OpLoad %[[#]]
+; CHECK: %[[#BitcastResultId]] = OpBitcast %[[#]] %[[#LoadResultId]]
br label %for.inc
diff --git a/llvm/test/CodeGen/SPIRV/validate/sycl-tangle-group-algorithms.ll b/llvm/test/CodeGen/SPIRV/validate/sycl-tangle-group-algorithms.ll
new file mode 100644
index 00000000000000..b6b919f36d92c6
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/validate/sycl-tangle-group-algorithms.ll
@@ -0,0 +1,4673 @@
+; This is an excerpt from the SYCL end-to-end test suite, cleaned out from
+; unrelevant details, that reproduced cases of invalid SPIR-V generation due
+; to wrong types, deduced from the input LLVM IR. Namely, this test case covers
+; cases of type mismatch when null pointer constant is used in different
+; contexts and so with different pointee types, and intertwined
+; load/store/function call LLVM IR input with bitcasts inserted between
+; instruction uses.
+
+; The only pass criterion is that spirv-val considers output valid.
+
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64v1.5-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+%"nd_item" = type { i8 }
+%struct.AssertHappened = type { i32, [257 x i8], [257 x i8], [129 x i8], i32, i64, i64, i64, i64, i64, i64 }
+%"range" = type { %"detail::array" }
+%"detail::array" = type { [1 x i64] }
+%class.anon = type { %"accessor", %"accessor", %"accessor", %"accessor", %"accessor", %"accessor", %"accessor", %"accessor", %"accessor", %"accessor", %"accessor", %"accessor", %"accessor" }
+%"accessor" = type { %"detail::AccessorImplDevice", %union.anon }
+%"detail::AccessorImplDevice" = type { %"range", %"range", %"range" }
+%union.anon = type { ptr addrspace(1) }
+%class.anon.6 = type { ptr addrspace(4), ptr addrspace(4), ptr addrspace(4), ptr addrspace(4) }
+%"group" = type { %"range", %"range", %"range", %"range" }
+%"item" = type { %"detail::AccessorImplDevice" }
+%"item.22" = type { %"sd_ItemBase.23" }
+%"sd_ItemBase.23" = type { %"range", %"range" }
+%"tangle_group" = type { %"ss_sub_group_mask" }
+%"ss_sub_group_mask" = type { i64, i64 }
+%class.anon.8 = type { %"accessor", %"accessor", [8 x i8], %"accessor", %"accessor", %"accessor", %"accessor", %"accessor", %"accessor", %"accessor", %"accessor", %"accessor", %"accessor", %"accessor" }
+%"vec.16" = type { %"struct.std::array.20" }
+%"struct.std::array.20" = type { [4 x i32] }
+%class.anon.15 = type { ptr addrspace(4), ptr addrspace(4), ptr addrspace(4) }
+%class.anon.7 = type { ptr addrspace(4), ptr addrspace(4) }
+
+ at .str = private unnamed_addr addrspace(1) constant [21 x i8] c"bits_num <= max_bits\00", align 1
+ at .str.1 = private unnamed_addr addrspace(1) constant [17 x i8] c"subgroupmask.hpp\00", align 1
+ at __PRETTY_FUNCTION1 = private unnamed_addr addrspace(1) constant [32 x i8] c"subgroup_mask(BitsType, size_t)\00", align 1
+ at .str.2 = private unnamed_addr addrspace(1) constant [15 x i8] c"bn <= max_bits\00", align 1
+ at __PRETTY_FUNCTION2 = private unnamed_addr addrspace(1) constant [52 x i8] c"BitsType subgroup_mask::valuable_bits(size_t) const\00", align 1
+ at __spirv_BuiltInSubgroupMaxSize = external dso_local addrspace(1) constant i32, align 4
+ at __spirv_BuiltInSubgroupLocalInvocationId = external dso_local addrspace(1) constant i32, align 4
+ at _ZSt6ignore = linkonce_odr dso_local addrspace(1) constant %"nd_item" undef, align 1
+ at __spirv_BuiltInNumWorkgroups = external dso_local addrspace(1) constant <3 x i64>, align 32
+ at __spirv_BuiltInGlobalOffset = external dso_local addrspace(1) constant <3 x i64>, align 32
+ at __spirv_BuiltInGlobalInvocationId = external dso_local addrspace(1) constant <3 x i64>, align 32
+ at __spirv_BuiltInGlobalSize = external dso_local addrspace(1) constant <3 x i64>, align 32
+ at __spirv_BuiltInLocalInvocationId = external dso_local addrspace(1) constant <3 x i64>, align 32
+ at SPIR_AssertHappenedMem = linkonce_odr dso_local addrspace(1) global %struct.AssertHappened zeroinitializer
+ at __spirv_BuiltInWorkgroupId = external dso_local addrspace(1) constant <3 x i64>, align 32
+ at __spirv_BuiltInWorkgroupSize = external dso_local addrspace(1) constant <3 x i64>, align 32
+
+
+define weak_odr dso_local spir_kernel void @TestKernel(ptr addrspace(1) %_arg_TmpAcc, ptr byval(%"range") %_arg_TmpAcc1, ptr byval(%"range") %_arg_TmpAcc2, ptr byval(%"range") %_arg_TmpAcc3, ptr addrspace(1) align 1 %_arg_BarrierAcc, ptr byval(%"range") %_arg_BarrierAcc4, ptr byval(%"range") %_arg_BarrierAcc5, ptr byval(%"range") %_arg_BarrierAcc6, ptr addrspace(1) align 1 %_arg_BroadcastAcc, ptr byval(%"range") %_arg_BroadcastAcc7, ptr byval(%"range") %_arg_BroadcastAcc8, ptr byval(%"range") %_arg_BroadcastAcc9, ptr addrspace(1) align 1 %_arg_AnyAcc, ptr byval(%"range") %_arg_AnyAcc10, ptr byval(%"range") %_arg_AnyAcc11, ptr byval(%"range") %_arg_AnyAcc12, ptr addrspace(1) align 1 %_arg_AllAcc, ptr byval(%"range") %_arg_AllAcc13, ptr byval(%"range") %_arg_AllAcc14, ptr byval(%"range") %_arg_AllAcc15, ptr addrspace(1) align 1 %_arg_NoneAcc, ptr byval(%"range") %_arg_NoneAcc16, ptr byval(%"range") %_arg_NoneAcc17, ptr byval(%"range") %_arg_NoneAcc18, ptr addrspace(1) align 1 %_arg_ReduceAcc, ptr byval(%"range") %_arg_ReduceAcc19, ptr byval(%"range") %_arg_ReduceAcc20, ptr byval(%"range") %_arg_ReduceAcc21, ptr addrspace(1) align 1 %_arg_ExScanAcc, ptr byval(%"range") %_arg_ExScanAcc22, ptr byval(%"range") %_arg_ExScanAcc23, ptr byval(%"range") %_arg_ExScanAcc24, ptr addrspace(1) align 1 %_arg_IncScanAcc, ptr byval(%"range") %_arg_IncScanAcc25, ptr byval(%"range") %_arg_IncScanAcc26, ptr byval(%"range") %_arg_IncScanAcc27, ptr addrspace(1) align 1 %_arg_ShiftLeftAcc, ptr byval(%"range") %_arg_ShiftLeftAcc28, ptr byval(%"range") %_arg_ShiftLeftAcc29, ptr byval(%"range") %_arg_ShiftLeftAcc30, ptr addrspace(1) align 1 %_arg_ShiftRightAcc, ptr byval(%"range") %_arg_ShiftRightAcc31, ptr byval(%"range") %_arg_ShiftRightAcc32, ptr byval(%"range") %_arg_ShiftRightAcc33, ptr addrspace(1) align 1 %_arg_SelectAcc, ptr byval(%"range") %_arg_SelectAcc34, ptr byval(%"range") %_arg_SelectAcc35, ptr byval(%"range") %_arg_SelectAcc36, ptr addrspace(1) align 1 %_arg_PermuteXorAcc, ptr byval(%"range") %_arg_PermuteXorAcc37, ptr byval(%"range") %_arg_PermuteXorAcc38, ptr byval(%"range") %_arg_PermuteXorAcc39) {
+entry:
+ %_arg_TmpAcc.addr = alloca ptr addrspace(1)
+ %_arg_BarrierAcc.addr = alloca ptr addrspace(1)
+ %_arg_BroadcastAcc.addr = alloca ptr addrspace(1)
+ %_arg_AnyAcc.addr = alloca ptr addrspace(1)
+ %_arg_AllAcc.addr = alloca ptr addrspace(1)
+ %_arg_NoneAcc.addr = alloca ptr addrspace(1)
+ %_arg_ReduceAcc.addr = alloca ptr addrspace(1)
+ %_arg_ExScanAcc.addr = alloca ptr addrspace(1)
+ %_arg_IncScanAcc.addr = alloca ptr addrspace(1)
+ %_arg_ShiftLeftAcc.addr = alloca ptr addrspace(1)
+ %_arg_ShiftRightAcc.addr = alloca ptr addrspace(1)
+ %_arg_SelectAcc.addr = alloca ptr addrspace(1)
+ %_arg_PermuteXorAcc.addr = alloca ptr addrspace(1)
+ %Kernel = alloca %class.anon
+ %agg.tmp = alloca %"range"
+ %agg.tmp41 = alloca %"range"
+ %agg.tmp42 = alloca %"range"
+ %agg.tmp44 = alloca %"range"
+ %agg.tmp45 = alloca %"range"
+ %agg.tmp46 = alloca %"range"
+ %agg.tmp48 = alloca %"range"
+ %agg.tmp49 = alloca %"range"
+ %agg.tmp50 = alloca %"range"
+ %agg.tmp52 = alloca %"range"
+ %agg.tmp53 = alloca %"range"
+ %agg.tmp54 = alloca %"range"
+ %agg.tmp56 = alloca %"range"
+ %agg.tmp57 = alloca %"range"
+ %agg.tmp58 = alloca %"range"
+ %agg.tmp60 = alloca %"range"
+ %agg.tmp61 = alloca %"range"
+ %agg.tmp62 = alloca %"range"
+ %agg.tmp64 = alloca %"range"
+ %agg.tmp65 = alloca %"range"
+ %agg.tmp66 = alloca %"range"
+ %agg.tmp68 = alloca %"range"
+ %agg.tmp69 = alloca %"range"
+ %agg.tmp70 = alloca %"range"
+ %agg.tmp72 = alloca %"range"
+ %agg.tmp73 = alloca %"range"
+ %agg.tmp74 = alloca %"range"
+ %agg.tmp76 = alloca %"range"
+ %agg.tmp77 = alloca %"range"
+ %agg.tmp78 = alloca %"range"
+ %agg.tmp80 = alloca %"range"
+ %agg.tmp81 = alloca %"range"
+ %agg.tmp82 = alloca %"range"
+ %agg.tmp84 = alloca %"range"
+ %agg.tmp85 = alloca %"range"
+ %agg.tmp86 = alloca %"range"
+ %agg.tmp88 = alloca %"range"
+ %agg.tmp89 = alloca %"range"
+ %agg.tmp90 = alloca %"range"
+ %agg.tmp91 = alloca %"nd_item", align 1
+ %Kernel.ascast = addrspacecast ptr %Kernel to ptr addrspace(4)
+ %agg.tmp91.ascast = addrspacecast ptr %agg.tmp91 to ptr addrspace(4)
+ store ptr addrspace(1) %_arg_TmpAcc, ptr %_arg_TmpAcc.addr
+ store ptr addrspace(1) %_arg_BarrierAcc, ptr %_arg_BarrierAcc.addr
+ store ptr addrspace(1) %_arg_BroadcastAcc, ptr %_arg_BroadcastAcc.addr
+ store ptr addrspace(1) %_arg_AnyAcc, ptr %_arg_AnyAcc.addr
+ store ptr addrspace(1) %_arg_AllAcc, ptr %_arg_AllAcc.addr
+ store ptr addrspace(1) %_arg_NoneAcc, ptr %_arg_NoneAcc.addr
+ store ptr addrspace(1) %_arg_ReduceAcc, ptr %_arg_ReduceAcc.addr
+ store ptr addrspace(1) %_arg_ExScanAcc, ptr %_arg_ExScanAcc.addr
+ store ptr addrspace(1) %_arg_IncScanAcc, ptr %_arg_IncScanAcc.addr
+ store ptr addrspace(1) %_arg_ShiftLeftAcc, ptr %_arg_ShiftLeftAcc.addr
+ store ptr addrspace(1) %_arg_ShiftRightAcc, ptr %_arg_ShiftRightAcc.addr
+ store ptr addrspace(1) %_arg_SelectAcc, ptr %_arg_SelectAcc.addr
+ store ptr addrspace(1) %_arg_PermuteXorAcc, ptr %_arg_PermuteXorAcc.addr
+ %TmpAcc1 = bitcast ptr addrspace(4) %Kernel.ascast to ptr addrspace(4)
+ call spir_func void @Foo1(ptr addrspace(4) %TmpAcc1)
+ %BarrierAcc = getelementptr inbounds nuw %class.anon, ptr addrspace(4) %Kernel.ascast, i32 0, i32 1
+ call spir_func void @Foo2(ptr addrspace(4) %BarrierAcc)
+ %BroadcastAcc = getelementptr inbounds nuw %class.anon, ptr addrspace(4) %Kernel.ascast, i32 0, i32 2
+ call spir_func void @Foo2(ptr addrspace(4) %BroadcastAcc)
+ %AnyAcc = getelementptr inbounds nuw %class.anon, ptr addrspace(4) %Kernel.ascast, i32 0, i32 3
+ call spir_func void @Foo2(ptr addrspace(4) %AnyAcc)
+ %AllAcc = getelementptr inbounds nuw %class.anon, ptr addrspace(4) %Kernel.ascast, i32 0, i32 4
+ call spir_func void @Foo2(ptr addrspace(4) %AllAcc)
+ %NoneAcc = getelementptr inbounds nuw %class.anon, ptr addrspace(4) %Kernel.ascast, i32 0, i32 5
+ call spir_func void @Foo2(ptr addrspace(4) %NoneAcc)
+ %ReduceAcc = getelementptr inbounds nuw %class.anon, ptr addrspace(4) %Kernel.ascast, i32 0, i32 6
+ call spir_func void @Foo2(ptr addrspace(4) %ReduceAcc)
+ %ExScanAcc = getelementptr inbounds nuw %class.anon, ptr addrspace(4) %Kernel.ascast, i32 0, i32 7
+ call spir_func void @Foo2(ptr addrspace(4) %ExScanAcc)
+ %IncScanAcc = getelementptr inbounds nuw %class.anon, ptr addrspace(4) %Kernel.ascast, i32 0, i32 8
+ call spir_func void @Foo2(ptr addrspace(4) %IncScanAcc)
+ %ShiftLeftAcc = getelementptr inbounds nuw %class.anon, ptr addrspace(4) %Kernel.ascast, i32 0, i32 9
+ call spir_func void @Foo2(ptr addrspace(4) %ShiftLeftAcc)
+ %ShiftRightAcc = getelementptr inbounds nuw %class.anon, ptr addrspace(4) %Kernel.ascast, i32 0, i32 10
+ call spir_func void @Foo2(ptr addrspace(4) %ShiftRightAcc)
+ %SelectAcc = getelementptr inbounds nuw %class.anon, ptr addrspace(4) %Kernel.ascast, i32 0, i32 11
+ call spir_func void @Foo2(ptr addrspace(4) %SelectAcc)
+ %PermuteXorAcc = getelementptr inbounds nuw %class.anon, ptr addrspace(4) %Kernel.ascast, i32 0, i32 12
+ call spir_func void @Foo2(ptr addrspace(4) %PermuteXorAcc)
+ %TmpAcc402 = bitcast ptr addrspace(4) %Kernel.ascast to ptr addrspace(4)
+ %0 = load ptr addrspace(1), ptr %_arg_TmpAcc.addr
+ call spir_func void @Foo3(ptr addrspace(4) %TmpAcc402, ptr addrspace(1) %0, ptr byval(%"range") %agg.tmp, ptr byval(%"range") %agg.tmp41, ptr byval(%"range") %agg.tmp42)
+ %BarrierAcc43 = getelementptr inbounds nuw %class.anon, ptr addrspace(4) %Kernel.ascast, i32 0, i32 1
+ %1 = load ptr addrspace(1), ptr %_arg_BarrierAcc.addr
+ call spir_func void @Foo4(ptr addrspace(4) %BarrierAcc43, ptr addrspace(1) %1, ptr byval(%"range") %agg.tmp44, ptr byval(%"range") %agg.tmp45, ptr byval(%"range") %agg.tmp46)
+ %BroadcastAcc47 = getelementptr inbounds nuw %class.anon, ptr addrspace(4) %Kernel.ascast, i32 0, i32 2
+ %2 = load ptr addrspace(1), ptr %_arg_BroadcastAcc.addr
+ call spir_func void @Foo4(ptr addrspace(4) %BroadcastAcc47, ptr addrspace(1) %2, ptr byval(%"range") %agg.tmp48, ptr byval(%"range") %agg.tmp49, ptr byval(%"range") %agg.tmp50)
+ %AnyAcc51 = getelementptr inbounds nuw %class.anon, ptr addrspace(4) %Kernel.ascast, i32 0, i32 3
+ %3 = load ptr addrspace(1), ptr %_arg_AnyAcc.addr
+ call spir_func void @Foo4(ptr addrspace(4) %AnyAcc51, ptr...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/118298
More information about the llvm-commits
mailing list