Skip to content

Commit 65ab635

Browse files
vmaksimojsji
authored andcommitted
1 parent 08430ff commit 65ab635

File tree

11 files changed

+207
-38
lines changed

11 files changed

+207
-38
lines changed

llvm-spirv/lib/SPIRV/SPIRVReader.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2155,7 +2155,11 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
21552155
case OpAccessChain:
21562156
case OpInBoundsAccessChain:
21572157
case OpPtrAccessChain:
2158-
case OpInBoundsPtrAccessChain: {
2158+
case OpInBoundsPtrAccessChain:
2159+
case OpUntypedAccessChainKHR:
2160+
case OpUntypedInBoundsAccessChainKHR:
2161+
case OpUntypedPtrAccessChainKHR:
2162+
case OpUntypedInBoundsPtrAccessChainKHR: {
21592163
auto *AC = static_cast<SPIRVAccessChainBase *>(BV);
21602164
auto *Base = transValue(AC->getBase(), F, BB);
21612165
SPIRVType *BaseSPVTy = AC->getBase()->getType();

llvm-spirv/lib/SPIRV/SPIRVWriter.cpp

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,6 +1329,7 @@ SPIRVValue *LLVMToSPIRVBase::transConstantUse(Constant *C,
13291329
// mode, but the value may have a different "natural" type. If that is the
13301330
// case, we need to adjust the type of the constant.
13311331
SPIRVValue *Trans = transValue(C, nullptr, true, FuncTransMode::Pointer);
1332+
std::vector<SPIRVWord> Ops = {Trans->getId()};
13321333
if (Trans->getType() == ExpectedType || Trans->getType()->isTypePipeStorage())
13331334
return Trans;
13341335

@@ -1340,9 +1341,18 @@ SPIRVValue *LLVMToSPIRVBase::transConstantUse(Constant *C,
13401341
if (auto *GV = dyn_cast<GlobalVariable>(C)) {
13411342
if (GV->getValueType()->isArrayTy() &&
13421343
GV->getValueType()->getArrayElementType()->isIntegerTy(8)) {
1343-
SPIRVValue *Offset = transValue(getUInt32(M, 0), nullptr);
1344-
return BM->addPtrAccessChainInst(ExpectedType, Trans, {Offset, Offset},
1345-
nullptr, true);
1344+
SPIRVWord Offset = transValue(getUInt32(M, 0), nullptr)->getId();
1345+
Ops.push_back(Offset);
1346+
Ops.push_back(Offset);
1347+
if (ExpectedType->isTypeUntypedPointerKHR()) {
1348+
llvm::Type *Ty = Scavenger->getScavengedType(C);
1349+
SPIRVType *PtrTy = nullptr;
1350+
if (auto *TPT = dyn_cast<TypedPointerType>(Ty)) {
1351+
PtrTy = transType(TPT->getElementType());
1352+
Ops = getVec(PtrTy->getId(), Ops);
1353+
}
1354+
}
1355+
return BM->addPtrAccessChainInst(ExpectedType, Ops, nullptr, true);
13461356
}
13471357
}
13481358

@@ -1462,13 +1472,20 @@ SPIRVValue *LLVMToSPIRVBase::transConstant(Value *V) {
14621472

14631473
if (auto *ConstUE = dyn_cast<ConstantExpr>(V)) {
14641474
if (auto *GEP = dyn_cast<GEPOperator>(ConstUE)) {
1465-
std::vector<SPIRVValue *> Indices;
1466-
for (unsigned I = 0, E = GEP->getNumIndices(); I != E; ++I)
1467-
Indices.push_back(transValue(GEP->getOperand(I + 1), nullptr));
14681475
auto *TransPointerOperand = transValue(GEP->getPointerOperand(), nullptr);
1476+
std::vector<SPIRVWord> Ops = {TransPointerOperand->getId()};
1477+
for (unsigned I = 0, E = GEP->getNumIndices(); I != E; ++I)
1478+
Ops.push_back(transValue(GEP->getOperand(I + 1), nullptr)->getId());
14691479
SPIRVType *TranslatedTy = transScavengedType(GEP);
1470-
return BM->addPtrAccessChainInst(TranslatedTy, TransPointerOperand,
1471-
Indices, nullptr, GEP->isInBounds());
1480+
if (TranslatedTy->isTypeUntypedPointerKHR()) {
1481+
llvm::Type *Ty = Scavenger->getScavengedType(GEP->getPointerOperand());
1482+
if (auto *TPT = dyn_cast<TypedPointerType>(Ty)) {
1483+
SPIRVType *PtrTy = transType(TPT->getElementType());
1484+
Ops = getVec(PtrTy->getId(), Ops);
1485+
}
1486+
}
1487+
return BM->addPtrAccessChainInst(TranslatedTy, Ops, nullptr,
1488+
GEP->isInBounds());
14721489
}
14731490
auto *Inst = ConstUE->getAsInstruction();
14741491
SPIRVDBG(dbgs() << "ConstantExpr: " << *ConstUE << '\n';
@@ -2477,18 +2494,17 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
24772494
}
24782495

24792496
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V)) {
2480-
std::vector<SPIRVValue *> Indices;
2481-
for (unsigned I = 0, E = GEP->getNumIndices(); I != E; ++I)
2482-
Indices.push_back(transValue(GEP->getOperand(I + 1), BB));
24832497
auto *PointerOperand = GEP->getPointerOperand();
2484-
auto *TransPointerOperand = transValue(PointerOperand, BB);
2498+
std::vector<SPIRVWord> Ops = {transValue(PointerOperand, BB)->getId()};
2499+
for (unsigned I = 0, E = GEP->getNumIndices(); I != E; ++I)
2500+
Ops.push_back(transValue(GEP->getOperand(I + 1), BB)->getId());
24852501

24862502
// Certain array-related optimization hints can be expressed via
24872503
// LLVM metadata. For the purpose of linking this metadata with
24882504
// the accessed array variables, our GEP may have been marked into
24892505
// a so-called index group, an MDNode by itself.
24902506
if (MDNode *IndexGroup = GEP->getMetadata("llvm.index.group")) {
2491-
SPIRVValue *ActualMemoryPtr = TransPointerOperand;
2507+
SPIRVValue *ActualMemoryPtr = BM->getValue(Ops[0]);
24922508
// If the source is a no-op bitcast (generated to fix up types), look
24932509
// through it to the underlying gep if possible.
24942510
if (auto *BC = dyn_cast<CastInst>(PointerOperand))
@@ -2522,9 +2538,16 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
25222538
// GEP can return a vector of pointers, in this case GEP will calculate
25232539
// addresses for each pointer in the vector
25242540
SPIRVType *TranslatedTy = transScavengedType(GEP);
2525-
return mapValue(V,
2526-
BM->addPtrAccessChainInst(TranslatedTy, TransPointerOperand,
2527-
Indices, BB, GEP->isInBounds()));
2541+
if (TranslatedTy->isTypeUntypedPointerKHR()) {
2542+
llvm::Type *Ty = Scavenger->getScavengedType(PointerOperand);
2543+
SPIRVType *PtrTy = nullptr;
2544+
if (auto *TPT = dyn_cast<TypedPointerType>(Ty)) {
2545+
PtrTy = transType(TPT->getElementType());
2546+
Ops = getVec(PtrTy->getId(), Ops);
2547+
}
2548+
}
2549+
return mapValue(
2550+
V, BM->addPtrAccessChainInst(TranslatedTy, Ops, BB, GEP->isInBounds()));
25282551
}
25292552

25302553
if (auto *Ext = dyn_cast<ExtractElementInst>(V)) {
@@ -4660,8 +4683,12 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II,
46604683
PtrAS == SPIRAS_Generic, SPIRVEC_InvalidInstruction, II,
46614684
"lifetime intrinsic pointer operand must be in private or generic AS");
46624685
auto *SrcTy = PtrOp->getType();
4663-
auto *DstTy = BM->addPointerType(StorageClassFunction,
4664-
SrcTy->getPointerElementType());
4686+
SPIRVType *DstTy = nullptr;
4687+
if (SrcTy->isTypeUntypedPointerKHR())
4688+
DstTy = BM->addUntypedPointerKHRType(StorageClassFunction);
4689+
else
4690+
DstTy = BM->addPointerType(StorageClassFunction,
4691+
SrcTy->getPointerElementType());
46654692
PtrOp = BM->addUnaryInst(OpGenericCastToPtr, DstTy, PtrOp, BB);
46664693
ValueMap[LLVMPtrOp] = PtrOp;
46674694
return BM->addLifetimeInst(OC, PtrOp, Size, BB);

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVInstruction.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,10 @@ bool isSpecConstantOpAllowedOp(Op OC) {
248248
OpInBoundsAccessChain,
249249
OpPtrAccessChain,
250250
OpInBoundsPtrAccessChain,
251+
OpUntypedAccessChainKHR,
252+
OpUntypedInBoundsAccessChainKHR,
253+
OpUntypedPtrAccessChainKHR,
254+
OpUntypedInBoundsPtrAccessChainKHR,
251255
};
252256
static std::unordered_set<SPIRVWord> Allow(std::begin(Table),
253257
std::end(Table));

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVInstruction.h

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,17 +1695,38 @@ _SPIRV_OP_INTERNAL(ArithmeticFenceINTEL)
16951695

16961696
class SPIRVAccessChainBase : public SPIRVInstTemplateBase {
16971697
public:
1698-
SPIRVValue *getBase() { return this->getValue(this->Ops[0]); }
1698+
SPIRVValue *getBase() {
1699+
if (this->isUntyped())
1700+
return this->getValue(this->Ops[1]);
1701+
return this->getValue(this->Ops[0]);
1702+
}
1703+
SPIRVType *getBaseType() {
1704+
if (this->isUntyped())
1705+
return get<SPIRVType>(this->Ops[0]);
1706+
return this->getValue(this->Ops[0])->getType();
1707+
}
16991708
std::vector<SPIRVValue *> getIndices() const {
1700-
std::vector<SPIRVWord> IndexWords(this->Ops.begin() + 1, this->Ops.end());
1709+
unsigned IdxShift = this->isUntyped() ? 2 : 1;
1710+
std::vector<SPIRVWord> IndexWords(this->Ops.begin() + IdxShift,
1711+
this->Ops.end());
17011712
return this->getValues(IndexWords);
17021713
}
17031714
bool isInBounds() {
17041715
return OpCode == OpInBoundsAccessChain ||
1705-
OpCode == OpInBoundsPtrAccessChain;
1716+
OpCode == OpInBoundsPtrAccessChain ||
1717+
OpCode == OpUntypedInBoundsAccessChainKHR ||
1718+
OpCode == OpUntypedInBoundsPtrAccessChainKHR;
17061719
}
17071720
bool hasPtrIndex() {
1708-
return OpCode == OpPtrAccessChain || OpCode == OpInBoundsPtrAccessChain;
1721+
return OpCode == OpPtrAccessChain || OpCode == OpInBoundsPtrAccessChain ||
1722+
OpCode == OpUntypedPtrAccessChainKHR ||
1723+
OpCode == OpUntypedInBoundsPtrAccessChainKHR;
1724+
}
1725+
bool isUntyped() const {
1726+
return OpCode == OpUntypedAccessChainKHR ||
1727+
OpCode == OpUntypedInBoundsAccessChainKHR ||
1728+
OpCode == OpUntypedPtrAccessChainKHR ||
1729+
OpCode == OpUntypedInBoundsPtrAccessChainKHR;
17091730
}
17101731
};
17111732

@@ -1721,6 +1742,15 @@ typedef SPIRVAccessChainGeneric<OpPtrAccessChain, 5> SPIRVPtrAccessChain;
17211742
typedef SPIRVAccessChainGeneric<OpInBoundsPtrAccessChain, 5>
17221743
SPIRVInBoundsPtrAccessChain;
17231744

1745+
typedef SPIRVAccessChainGeneric<OpUntypedAccessChainKHR, 5>
1746+
SPIRVUntypedAccessChainKHR;
1747+
typedef SPIRVAccessChainGeneric<OpUntypedInBoundsAccessChainKHR, 5>
1748+
SPIRVUntypedInBoundsAccessChainKHR;
1749+
typedef SPIRVAccessChainGeneric<OpUntypedPtrAccessChainKHR, 6>
1750+
SPIRVUntypedPtrAccessChainKHR;
1751+
typedef SPIRVAccessChainGeneric<OpUntypedInBoundsPtrAccessChainKHR, 6>
1752+
SPIRVUntypedInBoundsPtrAccessChainKHR;
1753+
17241754
class SPIRVLoopControlINTEL : public SPIRVInstruction {
17251755
public:
17261756
static const Op OC = OpLoopControlINTEL;

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVModule.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,7 @@ class SPIRVModuleImpl : public SPIRVModule {
323323
SPIRVWord Capacity) override;
324324

325325
// Instruction creation functions
326-
SPIRVInstruction *addPtrAccessChainInst(SPIRVType *, SPIRVValue *,
327-
std::vector<SPIRVValue *>,
326+
SPIRVInstruction *addPtrAccessChainInst(SPIRVType *, std::vector<SPIRVWord>,
328327
SPIRVBasicBlock *, bool) override;
329328
SPIRVInstruction *addAsyncGroupCopy(SPIRVValue *Scope, SPIRVValue *Dest,
330329
SPIRVValue *Src, SPIRVValue *NumElems,
@@ -1725,13 +1724,19 @@ SPIRVInstruction *SPIRVModuleImpl::addArbFloatPointIntelInst(
17251724
}
17261725

17271726
SPIRVInstruction *
1728-
SPIRVModuleImpl::addPtrAccessChainInst(SPIRVType *Type, SPIRVValue *Base,
1729-
std::vector<SPIRVValue *> Indices,
1727+
SPIRVModuleImpl::addPtrAccessChainInst(SPIRVType *Type,
1728+
std::vector<SPIRVWord> TheOps,
17301729
SPIRVBasicBlock *BB, bool IsInBounds) {
1730+
if (Type->isTypeUntypedPointerKHR())
1731+
return addInstruction(SPIRVInstTemplateBase::create(
1732+
IsInBounds ? OpUntypedInBoundsPtrAccessChainKHR
1733+
: OpUntypedPtrAccessChainKHR,
1734+
Type, getId(), TheOps, BB, this),
1735+
BB);
17311736
return addInstruction(
1732-
SPIRVInstTemplateBase::create(
1733-
IsInBounds ? OpInBoundsPtrAccessChain : OpPtrAccessChain, Type,
1734-
getId(), getVec(Base->getId(), Base->getIds(Indices)), BB, this),
1737+
SPIRVInstTemplateBase::create(IsInBounds ? OpInBoundsPtrAccessChain
1738+
: OpPtrAccessChain,
1739+
Type, getId(), TheOps, BB, this),
17351740
BB);
17361741
}
17371742

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVModule.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,8 @@ class SPIRVModule {
313313
SPIRVWord Capacity) = 0;
314314

315315
// Instruction creation functions
316-
virtual SPIRVInstruction *addPtrAccessChainInst(SPIRVType *, SPIRVValue *,
317-
std::vector<SPIRVValue *>,
316+
virtual SPIRVInstruction *addPtrAccessChainInst(SPIRVType *,
317+
std::vector<SPIRVWord>,
318318
SPIRVBasicBlock *, bool) = 0;
319319
virtual SPIRVInstruction *
320320
addAsyncGroupCopy(SPIRVValue *Scope, SPIRVValue *Dest, SPIRVValue *Src,

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,10 @@ _SPIRV_OP(PtrNotEqual, 402)
335335
_SPIRV_OP(PtrDiff, 403)
336336
_SPIRV_OP(TypeUntypedPointerKHR, 4417)
337337
_SPIRV_OP(UntypedVariableKHR, 4418)
338+
_SPIRV_OP(UntypedAccessChainKHR, 4419)
339+
_SPIRV_OP(UntypedInBoundsAccessChainKHR, 4420)
340+
_SPIRV_OP(UntypedPtrAccessChainKHR, 4423)
341+
_SPIRV_OP(UntypedInBoundsPtrAccessChainKHR, 4424)
338342
_SPIRV_OP(GroupNonUniformRotateKHR, 4431)
339343
_SPIRV_OP(SDotKHR, 4450)
340344
_SPIRV_OP(UDotKHR, 4451)

llvm-spirv/test/extensions/KHR/SPV_KHR_untyped_pointers/globals.ll

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
; This test validated untyped access chain and its use in SpecConstantOp.
2+
13
; RUN: llvm-as %s -o %t.bc
24
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_KHR_untyped_pointers -o %t.spv
3-
; TODO: enable back once spirv-tools are updated.
5+
; TODO: enable back once spirv-tools are updated and allow untyped access chain as OpSpecConstantOp operand.
46
; R/UN: spirv-val %t.spv
57
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_KHR_untyped_pointers -spirv-text -o %t.spt
68
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
@@ -14,25 +16,51 @@ target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:2
1416
target triple = "spir-unknown-unknown"
1517

1618
; CHECK-SPIRV-DAG: TypeInt [[#I16:]] 16 0
17-
; CHECK-SPIRV-DAG: Constant [[#I16]] [[#CONST0:]] 0
1819
; CHECK-SPIRV-DAG: TypeInt [[#I32:]] 32 0
20+
; CHECK-SPIRV-DAG: TypeInt [[#I64:]] 64 0
21+
; CHECK-SPIRV-DAG: Constant [[#I16]] [[#CONST0:]] 0
22+
; CHECK-SPIRV-DAG: Constant [[#I32]] [[#CONST2:]] 2
23+
; CHECK-SPIRV-DAG: Constant [[#I32]] [[#CONST3:]] 3
24+
; CHECK-SPIRV-DAG: Constant [[#I32]] [[#CONST4:]] 4
25+
; CHECK-SPIRV-DAG: Constant [[#I64]] [[#CONST0_I64:]] 0
26+
; CHECK-SPIRV-DAG: Constant [[#I64]] [[#CONST1_I64:]] 1
27+
; CHECK-SPIRV-DAG: Constant [[#I64]] [[#CONST2_I64:]] 2
28+
; CHECK-SPIRV-DAG: Constant [[#I64]] [[#CONST3_I64:]] 3
29+
1930
; CHECK-SPIRV-DAG: TypeUntypedPointerKHR [[#PTRTY:]] 5
2031
; CHECK-SPIRV-DAG: TypeUntypedPointerKHR [[#LOCALPTRTY:]] 4
32+
; CHECK-SPIRV-DAG: TypeArray [[#ARRAYTY:]] [[#PTRTY]] [[#CONST2]]
33+
; CHECK-SPIRV-DAG: TypePointer [[#ARRAYPTRTY:]] 5 [[#ARRAYTY]]
34+
; CHECK-SPIRV-DAG: TypeArray [[#ARRAY1TY:]] [[#I32]] [[#CONST4]]
35+
; CHECK-SPIRV-DAG: TypeArray [[#ARRAY2TY:]] [[#ARRAY1TY]] [[#CONST3]]
36+
; CHECK-SPIRV-DAG: TypeArray [[#ARRAY3TY:]] [[#ARRAY2TY]] [[#CONST2]]
37+
; CHECK-SPIRV-DAG: TypePointer [[#ARRAY3PTRTY:]] 5 [[#ARRAY3TY]]
38+
2139

2240
; CHECK-SPIRV: UntypedVariableKHR [[#PTRTY]] [[#VARA:]] 5 [[#I16]] [[#CONST0]]
2341
; CHECK-SPIRV: UntypedVariableKHR [[#PTRTY]] [[#VARB:]] 5 [[#I32]]
2442
; CHECK-SPIRV: UntypedVariableKHR [[#PTRTY]] [[#VARC:]] 5 [[#PTRTY]] [[#VARA]]
2543
; CHECK-SPIRV: UntypedVariableKHR [[#LOCALPTRTY]] [[#VARD:]] 4 [[#PTRTY]]
44+
; CHECK-SPIRV: Variable [[#ARRAYPTRTY]] [[#VARE:]] 5
45+
; CHECK-SPIRV: Variable [[#ARRAY3PTRTY]] [[#VARF:]] 5
46+
; CHECK-SPIRV: SpecConstantOp [[#PTRTY]] [[#SPECCONST:]] 4424 [[#ARRAY3TY]] [[#VARF]] [[#CONST0_I64]] [[#CONST1_I64]] [[#CONST2_I64]] [[#CONST3_I64]]
47+
; CHECK-SPIRV: UntypedVariableKHR [[#PTRTY]] [[#VARG:]] 5 [[#PTRTY]] [[#SPECCONST]]
2648

2749
; CHECK-LLVM: @a = addrspace(1) global i16 0
2850
; CHECK-LLVM: @b = external addrspace(1) global i32
2951
; CHECK-LLVM: @c = addrspace(1) global ptr addrspace(1) @a
3052
; CHECK-LLVM: @d = external addrspace(3) global ptr addrspace(1)
53+
; CHECK-LLVM: @e = addrspace(1) global [2 x ptr addrspace(1)] [ptr addrspace(1) @a, ptr addrspace(1) @b]
54+
; CHECK-LLVM: @f = addrspace(1) global [2 x [3 x [4 x i32]]]
55+
; CHECK-LLVM: @g = addrspace(1) global ptr addrspace(1) getelementptr inbounds ([2 x [3 x [4 x i32]]], ptr addrspace(1) @f, i64 0, i64 1, i64 2, i64 3)
3156

3257
@a = addrspace(1) global i16 0
3358
@b = external addrspace(1) global i32
3459
@c = addrspace(1) global ptr addrspace(1) @a
3560
@d = external addrspace(3) global ptr addrspace(1)
61+
@e = addrspace(1) global [2 x ptr addrspace(1)] [ptr addrspace(1) @a, ptr addrspace(1) @b]
62+
@f = addrspace(1) global [2 x [3 x [4 x i32]]] [[3 x [4 x i32]] [[4 x i32] [i32 1, i32 2, i32 3, i32 4], [4 x i32] [i32 1, i32 2, i32 3, i32 4], [4 x i32] [i32 1, i32 2, i32 3, i32 4]], [3 x [4 x i32]] [[4 x i32] [i32 1, i32 2, i32 3, i32 4], [4 x i32] [i32 1, i32 2, i32 3, i32 4], [4 x i32] [i32 1, i32 2, i32 3, i32 4]]]
63+
@g = addrspace(1) global ptr addrspace(1) getelementptr inbounds ([2 x [3 x [4 x i32]]], ptr addrspace(1) @f, i64 0, i64 1, i64 2, i64 3)
3664

3765
; Function Attrs: nounwind
3866
define spir_func void @foo() {
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
; Source:
2+
; struct Example { int a; int b; };
3+
; void test(int val) {
4+
; Example obj;
5+
; obj.b = val;
6+
; }
7+
8+
; RUN: llvm-as %s -o %t.bc
9+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_KHR_untyped_pointers -o %t.spv
10+
; TODO: enable back once spirv-tools are updated.
11+
; R/UN: spirv-val %t.spv
12+
13+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_KHR_untyped_pointers -spirv-text -o %t.spt
14+
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
15+
16+
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
17+
; RUN: llvm-dis %t.rev.bc -o %t.rev.ll
18+
; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM
19+
20+
; CHECK-SPIRV: Capability UntypedPointersKHR
21+
; CHECK-SPIRV: Extension "SPV_KHR_untyped_pointers"
22+
; CHECK-SPIRV: TypeInt [[#IntTy:]] 32
23+
; CHECK-SPIRV: Constant [[#IntTy]] [[#Const0:]] 0
24+
; CHECK-SPIRV: Constant [[#IntTy]] [[#Const1:]] 1
25+
; CHECK-SPIRV: TypeUntypedPointerKHR [[#UntypedPtrTy:]] 7
26+
; CHECK-SPIRV: TypeStruct [[#StructTy:]] [[#IntTy]] [[#IntTy]]
27+
; CHECK-SPIRV: TypePointer [[#PtrStructTy:]] 7 [[#StructTy]]
28+
29+
; CHECK-SPIRV: Variable [[#PtrStructTy]] [[#StructVarId:]] 7
30+
; CHECK-SPIRV: UntypedInBoundsPtrAccessChainKHR [[#UntypedPtrTy]] [[#]] [[#StructTy]] [[#StructVarId]] [[#Const0]] [[#Const1]]
31+
32+
target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
33+
target triple = "spir-unknown-unknown"
34+
35+
%struct.Example = type { i32, i32 }
36+
37+
define spir_func void @test(i32 noundef %0) {
38+
%2 = alloca i32, align 4
39+
%3 = alloca %struct.Example, align 4
40+
store i32 %0, ptr %2, align 4
41+
%4 = load i32, ptr %2, align 4
42+
; CHECK-LLVM: %[[#Str:]] = alloca %struct.Example, align 4
43+
; CHECK-LLVM: getelementptr inbounds %struct.Example, ptr %[[#Str]], i32 0, i32 1
44+
%5 = getelementptr inbounds nuw %struct.Example, ptr %3, i32 0, i32 1
45+
store i32 %4, ptr %5, align 4
46+
ret void
47+
}

llvm-spirv/test/llvm-intrinsics/lifetime.ll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
; RUN: llvm-spirv -r %t.spv -o %t.spv.bc
77
; RUN: llvm-dis < %t.spv.bc | FileCheck %s --check-prefix=CHECK-LLVM
88

9+
; Verify that we have valid SPV and the same output LLVM IR when using untyped pointers.
10+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_KHR_untyped_pointers -o %t.spv
11+
; TODO: enable back once spirv-tools are updated.
12+
; R/UN: spirv-val %t.spv
13+
; RUN: llvm-spirv -r %t.spv -o %t.spv.bc
14+
; RUN: llvm-dis < %t.spv.bc | FileCheck %s --check-prefix=CHECK-LLVM
15+
916
; CHECK-SPIRV-DAG: EntryPoint [[#]] [[#SimpleF:]] "lifetime_simple"
1017
; CHECK-SPIRV-DAG: EntryPoint [[#]] [[#SizedF:]] "lifetime_sized"
1118
; CHECK-SPIRV-DAG: EntryPoint [[#]] [[#GenericF:]] "lifetime_generic"

0 commit comments

Comments
 (0)