Skip to content

Commit a13e80b

Browse files
authored
1 parent a52ef6d commit a13e80b

File tree

11 files changed

+207
-38
lines changed

11 files changed

+207
-38
lines changed

lib/SPIRV/SPIRVReader.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2152,7 +2152,11 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
21522152
case OpAccessChain:
21532153
case OpInBoundsAccessChain:
21542154
case OpPtrAccessChain:
2155-
case OpInBoundsPtrAccessChain: {
2155+
case OpInBoundsPtrAccessChain:
2156+
case OpUntypedAccessChainKHR:
2157+
case OpUntypedInBoundsAccessChainKHR:
2158+
case OpUntypedPtrAccessChainKHR:
2159+
case OpUntypedInBoundsPtrAccessChainKHR: {
21562160
auto *AC = static_cast<SPIRVAccessChainBase *>(BV);
21572161
auto *Base = transValue(AC->getBase(), F, BB);
21582162
SPIRVType *BaseSPVTy = AC->getBase()->getType();

lib/SPIRV/SPIRVWriter.cpp

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

@@ -1327,9 +1328,18 @@ SPIRVValue *LLVMToSPIRVBase::transConstantUse(Constant *C,
13271328
if (auto *GV = dyn_cast<GlobalVariable>(C)) {
13281329
if (GV->getValueType()->isArrayTy() &&
13291330
GV->getValueType()->getArrayElementType()->isIntegerTy(8)) {
1330-
SPIRVValue *Offset = transValue(getUInt32(M, 0), nullptr);
1331-
return BM->addPtrAccessChainInst(ExpectedType, Trans, {Offset, Offset},
1332-
nullptr, true);
1331+
SPIRVWord Offset = transValue(getUInt32(M, 0), nullptr)->getId();
1332+
Ops.push_back(Offset);
1333+
Ops.push_back(Offset);
1334+
if (ExpectedType->isTypeUntypedPointerKHR()) {
1335+
llvm::Type *Ty = Scavenger->getScavengedType(C);
1336+
SPIRVType *PtrTy = nullptr;
1337+
if (auto *TPT = dyn_cast<TypedPointerType>(Ty)) {
1338+
PtrTy = transType(TPT->getElementType());
1339+
Ops = getVec(PtrTy->getId(), Ops);
1340+
}
1341+
}
1342+
return BM->addPtrAccessChainInst(ExpectedType, Ops, nullptr, true);
13331343
}
13341344
}
13351345

@@ -1449,13 +1459,20 @@ SPIRVValue *LLVMToSPIRVBase::transConstant(Value *V) {
14491459

14501460
if (auto *ConstUE = dyn_cast<ConstantExpr>(V)) {
14511461
if (auto *GEP = dyn_cast<GEPOperator>(ConstUE)) {
1452-
std::vector<SPIRVValue *> Indices;
1453-
for (unsigned I = 0, E = GEP->getNumIndices(); I != E; ++I)
1454-
Indices.push_back(transValue(GEP->getOperand(I + 1), nullptr));
14551462
auto *TransPointerOperand = transValue(GEP->getPointerOperand(), nullptr);
1463+
std::vector<SPIRVWord> Ops = {TransPointerOperand->getId()};
1464+
for (unsigned I = 0, E = GEP->getNumIndices(); I != E; ++I)
1465+
Ops.push_back(transValue(GEP->getOperand(I + 1), nullptr)->getId());
14561466
SPIRVType *TranslatedTy = transScavengedType(GEP);
1457-
return BM->addPtrAccessChainInst(TranslatedTy, TransPointerOperand,
1458-
Indices, nullptr, GEP->isInBounds());
1467+
if (TranslatedTy->isTypeUntypedPointerKHR()) {
1468+
llvm::Type *Ty = Scavenger->getScavengedType(GEP->getPointerOperand());
1469+
if (auto *TPT = dyn_cast<TypedPointerType>(Ty)) {
1470+
SPIRVType *PtrTy = transType(TPT->getElementType());
1471+
Ops = getVec(PtrTy->getId(), Ops);
1472+
}
1473+
}
1474+
return BM->addPtrAccessChainInst(TranslatedTy, Ops, nullptr,
1475+
GEP->isInBounds());
14591476
}
14601477
auto *Inst = ConstUE->getAsInstruction();
14611478
SPIRVDBG(dbgs() << "ConstantExpr: " << *ConstUE << '\n';
@@ -2469,18 +2486,17 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
24692486
}
24702487

24712488
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V)) {
2472-
std::vector<SPIRVValue *> Indices;
2473-
for (unsigned I = 0, E = GEP->getNumIndices(); I != E; ++I)
2474-
Indices.push_back(transValue(GEP->getOperand(I + 1), BB));
24752489
auto *PointerOperand = GEP->getPointerOperand();
2476-
auto *TransPointerOperand = transValue(PointerOperand, BB);
2490+
std::vector<SPIRVWord> Ops = {transValue(PointerOperand, BB)->getId()};
2491+
for (unsigned I = 0, E = GEP->getNumIndices(); I != E; ++I)
2492+
Ops.push_back(transValue(GEP->getOperand(I + 1), BB)->getId());
24772493

24782494
// Certain array-related optimization hints can be expressed via
24792495
// LLVM metadata. For the purpose of linking this metadata with
24802496
// the accessed array variables, our GEP may have been marked into
24812497
// a so-called index group, an MDNode by itself.
24822498
if (MDNode *IndexGroup = GEP->getMetadata("llvm.index.group")) {
2483-
SPIRVValue *ActualMemoryPtr = TransPointerOperand;
2499+
SPIRVValue *ActualMemoryPtr = BM->getValue(Ops[0]);
24842500
// If the source is a no-op bitcast (generated to fix up types), look
24852501
// through it to the underlying gep if possible.
24862502
if (auto *BC = dyn_cast<CastInst>(PointerOperand))
@@ -2514,9 +2530,16 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
25142530
// GEP can return a vector of pointers, in this case GEP will calculate
25152531
// addresses for each pointer in the vector
25162532
SPIRVType *TranslatedTy = transScavengedType(GEP);
2517-
return mapValue(V,
2518-
BM->addPtrAccessChainInst(TranslatedTy, TransPointerOperand,
2519-
Indices, BB, GEP->isInBounds()));
2533+
if (TranslatedTy->isTypeUntypedPointerKHR()) {
2534+
llvm::Type *Ty = Scavenger->getScavengedType(PointerOperand);
2535+
SPIRVType *PtrTy = nullptr;
2536+
if (auto *TPT = dyn_cast<TypedPointerType>(Ty)) {
2537+
PtrTy = transType(TPT->getElementType());
2538+
Ops = getVec(PtrTy->getId(), Ops);
2539+
}
2540+
}
2541+
return mapValue(
2542+
V, BM->addPtrAccessChainInst(TranslatedTy, Ops, BB, GEP->isInBounds()));
25202543
}
25212544

25222545
if (auto *Ext = dyn_cast<ExtractElementInst>(V)) {
@@ -4652,8 +4675,12 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II,
46524675
PtrAS == SPIRAS_Generic, SPIRVEC_InvalidInstruction, II,
46534676
"lifetime intrinsic pointer operand must be in private or generic AS");
46544677
auto *SrcTy = PtrOp->getType();
4655-
auto *DstTy = BM->addPointerType(StorageClassFunction,
4656-
SrcTy->getPointerElementType());
4678+
SPIRVType *DstTy = nullptr;
4679+
if (SrcTy->isTypeUntypedPointerKHR())
4680+
DstTy = BM->addUntypedPointerKHRType(StorageClassFunction);
4681+
else
4682+
DstTy = BM->addPointerType(StorageClassFunction,
4683+
SrcTy->getPointerElementType());
46574684
PtrOp = BM->addUnaryInst(OpGenericCastToPtr, DstTy, PtrOp, BB);
46584685
ValueMap[LLVMPtrOp] = PtrOp;
46594686
return BM->addLifetimeInst(OC, PtrOp, Size, BB);

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));

lib/SPIRV/libSPIRV/SPIRVInstruction.h

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

17051705
class SPIRVAccessChainBase : public SPIRVInstTemplateBase {
17061706
public:
1707-
SPIRVValue *getBase() { return this->getValue(this->Ops[0]); }
1707+
SPIRVValue *getBase() {
1708+
if (this->isUntyped())
1709+
return this->getValue(this->Ops[1]);
1710+
return this->getValue(this->Ops[0]);
1711+
}
1712+
SPIRVType *getBaseType() {
1713+
if (this->isUntyped())
1714+
return get<SPIRVType>(this->Ops[0]);
1715+
return this->getValue(this->Ops[0])->getType();
1716+
}
17081717
std::vector<SPIRVValue *> getIndices() const {
1709-
std::vector<SPIRVWord> IndexWords(this->Ops.begin() + 1, this->Ops.end());
1718+
unsigned IdxShift = this->isUntyped() ? 2 : 1;
1719+
std::vector<SPIRVWord> IndexWords(this->Ops.begin() + IdxShift,
1720+
this->Ops.end());
17101721
return this->getValues(IndexWords);
17111722
}
17121723
bool isInBounds() {
17131724
return OpCode == OpInBoundsAccessChain ||
1714-
OpCode == OpInBoundsPtrAccessChain;
1725+
OpCode == OpInBoundsPtrAccessChain ||
1726+
OpCode == OpUntypedInBoundsAccessChainKHR ||
1727+
OpCode == OpUntypedInBoundsPtrAccessChainKHR;
17151728
}
17161729
bool hasPtrIndex() {
1717-
return OpCode == OpPtrAccessChain || OpCode == OpInBoundsPtrAccessChain;
1730+
return OpCode == OpPtrAccessChain || OpCode == OpInBoundsPtrAccessChain ||
1731+
OpCode == OpUntypedPtrAccessChainKHR ||
1732+
OpCode == OpUntypedInBoundsPtrAccessChainKHR;
1733+
}
1734+
bool isUntyped() const {
1735+
return OpCode == OpUntypedAccessChainKHR ||
1736+
OpCode == OpUntypedInBoundsAccessChainKHR ||
1737+
OpCode == OpUntypedPtrAccessChainKHR ||
1738+
OpCode == OpUntypedInBoundsPtrAccessChainKHR;
17181739
}
17191740
};
17201741

@@ -1730,6 +1751,15 @@ typedef SPIRVAccessChainGeneric<OpPtrAccessChain, 5> SPIRVPtrAccessChain;
17301751
typedef SPIRVAccessChainGeneric<OpInBoundsPtrAccessChain, 5>
17311752
SPIRVInBoundsPtrAccessChain;
17321753

1754+
typedef SPIRVAccessChainGeneric<OpUntypedAccessChainKHR, 5>
1755+
SPIRVUntypedAccessChainKHR;
1756+
typedef SPIRVAccessChainGeneric<OpUntypedInBoundsAccessChainKHR, 5>
1757+
SPIRVUntypedInBoundsAccessChainKHR;
1758+
typedef SPIRVAccessChainGeneric<OpUntypedPtrAccessChainKHR, 6>
1759+
SPIRVUntypedPtrAccessChainKHR;
1760+
typedef SPIRVAccessChainGeneric<OpUntypedInBoundsPtrAccessChainKHR, 6>
1761+
SPIRVUntypedInBoundsPtrAccessChainKHR;
1762+
17331763
class SPIRVLoopControlINTEL : public SPIRVInstruction {
17341764
public:
17351765
static const Op OC = OpLoopControlINTEL;

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

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,

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(PtrDiff, 403)
335335
_SPIRV_OP(CopyLogical, 400)
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)

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+
}

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: Name [[#SimpleF:]] "lifetime_simple"
1017
; CHECK-SPIRV-DAG: Name [[#SizedF:]] "lifetime_sized"
1118
; CHECK-SPIRV-DAG: Name [[#GenericF:]] "lifetime_generic"

0 commit comments

Comments
 (0)