Skip to content

Commit 6cd2668

Browse files
jcranmer-intelsys-ce-bb
authored andcommitted
More typing rule issues found during testing. (#2009)
Original commit: KhronosGroup/SPIRV-LLVM-Translator@4879ebe
1 parent 8678c7a commit 6cd2668

File tree

5 files changed

+87
-36
lines changed

5 files changed

+87
-36
lines changed

llvm-spirv/lib/SPIRV/SPIRVTypeScavenger.cpp

+55-3
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,17 @@ bool SPIRVTypeScavenger::typeIntrinsicCall(
440440
"Call is not an intrinsic function call");
441441
LLVMContext &Ctx = TargetFn->getContext();
442442

443+
// If the type is a pointer type, replace it with a typedptr(typevar) type
444+
// instead, using AssociatedTypeVariables.
445+
auto GetTypeOrTypeVar = [&](Type *BaseTy) {
446+
if (!BaseTy->isPointerTy())
447+
return BaseTy;
448+
Type *&AssociatedTy = AssociatedTypeVariables[&CB];
449+
if (!AssociatedTy)
450+
AssociatedTy = allocateTypeVariable(BaseTy);
451+
return AssociatedTy;
452+
};
453+
443454
StringRef DemangledName;
444455
if (oclIsBuiltin(TargetFn->getName(), DemangledName) ||
445456
isDecoratedSPIRVFunc(TargetFn, DemangledName)) {
@@ -536,13 +547,31 @@ bool SPIRVTypeScavenger::typeIntrinsicCall(
536547
// llvm.instrprof.* intrinsics are not supported
537548
TypeRules.push_back(TypeRule::pointsTo(CB, 0, Type::getInt8Ty(Ctx)));
538549
break;
539-
// TODO: handle masked gather/scatter intrinsics. This requires support
540-
// for vector-of-pointers in the type scavenger.
550+
case Intrinsic::masked_gather: {
551+
Type *ScalarTy = GetTypeOrTypeVar(CB.getType()->getScalarType());
552+
TypeRules.push_back(TypeRule::pointsTo(CB, 0, ScalarTy));
553+
if (CB.getType()->getScalarType()->isPointerTy())
554+
TypeRules.push_back(TypeRule::propagates(CB, 3));
555+
break;
556+
}
557+
case Intrinsic::masked_scatter: {
558+
Type *ScalarTy =
559+
GetTypeOrTypeVar(CB.getOperand(0)->getType()->getScalarType());
560+
TypeRules.push_back(TypeRule::pointsTo(CB, 1, ScalarTy));
561+
break;
562+
}
541563
default:
542564
return false;
543565
}
544566
} else if (TargetFn->getName().startswith("_Z18__spirv_ocl_printf")) {
545-
TypeRules.push_back(TypeRule::pointsTo(CB, 0, Type::getInt8Ty(Ctx)));
567+
Type *Int8Ty = Type::getInt8Ty(Ctx);
568+
// The first argument is a string pointer. Subsequent arguments may include
569+
// pointer-valued arguments, corresponding to %s or %p parameters.
570+
// Therefore, all parameters need to be i8*.
571+
for (Use &U : CB.args()) {
572+
if (U->getType()->isPointerTy())
573+
TypeRules.push_back(TypeRule::pointsTo(U, Int8Ty));
574+
}
546575
} else if (TargetFn->getName() == "__spirv_GetKernelWorkGroupSize__") {
547576
TypeRules.push_back(TypeRule::pointsTo(CB, 1, Type::getInt8Ty(Ctx)));
548577
} else if (TargetFn->getName() ==
@@ -558,6 +587,15 @@ bool SPIRVTypeScavenger::typeIntrinsicCall(
558587
TypeRules.push_back(TypeRule::pointsTo(CB, 4, DevEvent));
559588
TypeRules.push_back(TypeRule::pointsTo(CB, 5, DevEvent));
560589
TypeRules.push_back(TypeRule::pointsTo(CB, 7, Type::getInt8Ty(Ctx)));
590+
} else if (TargetFn->getName().starts_with(
591+
"_Z33__regcall3____builtin_invoke_simd")) {
592+
// First argument is a function to call, subsequent arguments are parameters
593+
// to said function.
594+
auto *FnTy = getFunctionType(cast<Function>(CB.getArgOperand(0)));
595+
TypeRules.push_back(TypeRule::pointsTo(CB, 0, FnTy));
596+
typeFunctionParams(CB, FnTy, 1, true, TypeRules);
597+
// Also apply type rules to the parameter types of the underlying function.
598+
return false;
561599
} else
562600
return false;
563601

@@ -899,6 +937,20 @@ void SPIRVTypeScavenger::getTypeRules(Instruction &I,
899937
TypeRules.push_back(TypeRule::pointsTo(CB->getCalledOperandUse(), FT));
900938
typeFunctionParams(*CB, FT, 0, true, TypeRules);
901939
}
940+
} else if (isa<ExtractElementInst>(&I)) {
941+
if (!hasPointerType(I.getType()))
942+
return;
943+
TypeRules.push_back(TypeRule::propagatesIndirect(I, 0));
944+
} else if (isa<InsertElementInst>(&I)) {
945+
if (!hasPointerType(I.getType()))
946+
return;
947+
TypeRules.push_back(TypeRule::propagatesIndirect(I, 0));
948+
TypeRules.push_back(TypeRule::propagatesIndirect(I, 1));
949+
} else if (isa<ShuffleVectorInst>(&I)) {
950+
if (!hasPointerType(I.getType()))
951+
return;
952+
TypeRules.push_back(TypeRule::propagatesIndirect(I, 0));
953+
TypeRules.push_back(TypeRule::propagatesIndirect(I, 1));
902954
}
903955

904956
// TODO: Handle insertvalue, extractvalue that work with pointers (requires

llvm-spirv/lib/SPIRV/SPIRVWriter.cpp

+17-20
Original file line numberDiff line numberDiff line change
@@ -1451,7 +1451,7 @@ SPIRVInstruction *LLVMToSPIRVBase::transCmpInst(CmpInst *Cmp,
14511451

14521452
SPIRVValue *LLVMToSPIRVBase::transUnaryInst(UnaryInstruction *U,
14531453
SPIRVBasicBlock *BB) {
1454-
if (isa<BitCastInst>(U) && U->getType()->isPointerTy()) {
1454+
if (isa<BitCastInst>(U) && U->getType()->isPtrOrPtrVectorTy()) {
14551455
if (isa<ConstantPointerNull>(U->getOperand(0))) {
14561456
SPIRVType *ExpectedTy = transScavengedType(U);
14571457
return BM->addNullConstant(bcast<SPIRVTypePointer>(ExpectedTy));
@@ -1817,7 +1817,7 @@ SPIRVValue *LLVMToSPIRVBase::transAtomicLoad(LoadInst *LD,
18171817
std::vector<SPIRVValue *> SPIRVOps = transValue(Ops, BB);
18181818

18191819
return mapValue(LD, BM->addInstTemplate(OpAtomicLoad, BM->getIds(SPIRVOps),
1820-
BB, transType(LD->getType())));
1820+
BB, transScavengedType(LD)));
18211821
}
18221822

18231823
// Aliasing list MD contains several scope MD nodes whithin it. Each scope MD
@@ -1896,9 +1896,9 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
18961896
// Though variables with common linkage type are initialized by 0,
18971897
// they can be represented in SPIR-V as uninitialized variables with
18981898
// 'Export' linkage type, just as tentative definitions look in C
1899-
llvm::Value *Init = GV->hasInitializer() && !GV->hasCommonLinkage()
1900-
? GV->getInitializer()
1901-
: nullptr;
1899+
llvm::Constant *Init = GV->hasInitializer() && !GV->hasCommonLinkage()
1900+
? GV->getInitializer()
1901+
: nullptr;
19021902
SPIRVValue *BVarInit = nullptr;
19031903
StructType *ST = Init ? dyn_cast<StructType>(Init->getType()) : nullptr;
19041904
if (ST && ST->hasName() && isSPIRVConstantName(ST->getName())) {
@@ -1945,10 +1945,8 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
19451945
}
19461946
}
19471947
}
1948-
// As global variables define a pointer to their "content" type, we should
1949-
// translate here only pointer without declaration even if it is a
1950-
// function pointer.
1951-
BVarInit = transValue(Init, nullptr, true, FuncTransMode::Pointer);
1948+
SPIRVType *TransTy = transType(Ty);
1949+
BVarInit = transConstantUse(Init, TransTy->getPointerElementType());
19521950
}
19531951

19541952
SPIRVStorageClassKind StorageClass;
@@ -2302,7 +2300,7 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
23022300

23032301
if (auto Ext = dyn_cast<ExtractValueInst>(V)) {
23042302
return mapValue(V, BM->addCompositeExtractInst(
2305-
transType(Ext->getType()),
2303+
transScavengedType(Ext),
23062304
transValue(Ext->getAggregateOperand(), BB),
23072305
Ext->getIndices(), BB));
23082306
}
@@ -2370,7 +2368,7 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
23702368
auto Index = Ext->getIndexOperand();
23712369
if (auto Const = dyn_cast<ConstantInt>(Index))
23722370
return mapValue(V, BM->addCompositeExtractInst(
2373-
transType(Ext->getType()),
2371+
transScavengedType(Ext),
23742372
transValue(Ext->getVectorOperand(), BB),
23752373
std::vector<SPIRVWord>(1, Const->getZExtValue()),
23762374
BB));
@@ -2401,7 +2399,7 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
24012399
for (auto &I : SF->getShuffleMask())
24022400
Comp.push_back(I);
24032401
return mapValue(V, BM->addVectorShuffleInst(
2404-
transType(SF->getType()),
2402+
transScavengedType(SF),
24052403
transValue(SF->getOperand(0), BB),
24062404
transValue(SF->getOperand(1), BB), Comp, BB));
24072405
}
@@ -2434,7 +2432,7 @@ LLVMToSPIRVBase::transValueWithoutDecoration(Value *V, SPIRVBasicBlock *BB,
24342432
Operands[3] = ARMW->getValOperand();
24352433
std::vector<SPIRVValue *> OpVals = transValue(Operands, BB);
24362434
std::vector<SPIRVId> Ops = BM->getIds(OpVals);
2437-
SPIRVType *Ty = transType(ARMW->getType());
2435+
SPIRVType *Ty = transScavengedType(ARMW);
24382436

24392437
spv::Op OC;
24402438
if (Op == AtomicRMWInst::FSub) {
@@ -4082,7 +4080,7 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II,
40824080
case Intrinsic::dbg_value:
40834081
return DbgTran->createDebugValuePlaceholder(cast<DbgValueInst>(II), BB);
40844082
case Intrinsic::annotation: {
4085-
SPIRVType *Ty = transType(II->getType());
4083+
SPIRVType *Ty = transScavengedType(II);
40864084

40874085
GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(II->getArgOperand(1));
40884086
if (!GEP)
@@ -4149,8 +4147,7 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II,
41494147

41504148
// Translate FPGARegIntel annotations to OpFPGARegINTEL.
41514149
if (AnnotationString == kOCLBuiltinName::FPGARegIntel) {
4152-
// TODO: Check for opaque pointer requirements.
4153-
auto *Ty = transType(II->getType());
4150+
auto *Ty = transScavengedType(II);
41544151
auto *BI = dyn_cast<BitCastInst>(II->getOperand(0));
41554152
if (BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_fpga_reg))
41564153
return BM->addFPGARegINTELInst(Ty, transValue(BI, BB), BB);
@@ -4295,7 +4292,7 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II,
42954292
"-spirv-allow-unknown-intrinsics option.");
42964293
return nullptr;
42974294
}
4298-
SPIRVType *Ty = transType(II->getType());
4295+
SPIRVType *Ty = transScavengedType(II);
42994296
auto *PtrVector = transValue(II->getArgOperand(0), BB);
43004297
uint32_t Alignment =
43014298
cast<ConstantInt>(II->getArgOperand(1))->getZExtValue();
@@ -5865,7 +5862,7 @@ LLVMToSPIRVBase::transBuiltinToInstWithoutDecoration(Op OC, CallInst *CI,
58655862
}
58665863
default: {
58675864
if (isCvtOpCode(OC) && OC != OpGenericCastToPtrExplicit) {
5868-
return BM->addUnaryInst(OC, transType(CI->getType()),
5865+
return BM->addUnaryInst(OC, transScavengedType(CI),
58695866
transValue(CI->getArgOperand(0), BB), BB);
58705867
} else if (isCmpOpCode(OC) || isUnaryPredicateOpCode(OC)) {
58715868
auto ResultTy = CI->getType();
@@ -5895,12 +5892,12 @@ LLVMToSPIRVBase::transBuiltinToInstWithoutDecoration(Op OC, CallInst *CI,
58955892
return BM->addSelectInst(Res, One, Zero, BB);
58965893
} else if (isBinaryOpCode(OC)) {
58975894
assert(CI && CI->arg_size() == 2 && "Invalid call inst");
5898-
return BM->addBinaryInst(OC, transType(CI->getType()),
5895+
return BM->addBinaryInst(OC, transScavengedType(CI),
58995896
transValue(CI->getArgOperand(0), BB),
59005897
transValue(CI->getArgOperand(1), BB), BB);
59015898
} else if (CI->arg_size() == 1 && !CI->getType()->isVoidTy() &&
59025899
!hasExecScope(OC) && !isAtomicOpCode(OC)) {
5903-
return BM->addUnaryInst(OC, transType(CI->getType()),
5900+
return BM->addUnaryInst(OC, transScavengedType(CI),
59045901
transValue(CI->getArgOperand(0), BB), BB);
59055902
} else {
59065903
auto Args = getArguments(CI);

llvm-spirv/test/extensions/INTEL/SPV_INTEL_function_pointers/vector_elem.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: llvm-as -opaque-pointers=0 < %s | llvm-spirv -opaque-pointers=0 -spirv-text --spirv-ext=+SPV_INTEL_function_pointers,+SPV_INTEL_masked_gather_scatter | FileCheck %s --check-prefix=CHECK-SPIRV
1+
; RUN: llvm-as < %s | llvm-spirv -spirv-text --spirv-ext=+SPV_INTEL_function_pointers,+SPV_INTEL_masked_gather_scatter | FileCheck %s --check-prefix=CHECK-SPIRV
22

33
; CHECK-SPIRV-DAG: 6 Name [[F1:[0-9+]]] "_Z2f1u2CMvb32_j"
44
; CHECK-SPIRV-DAG: 6 Name [[F2:[0-9+]]] "_Z2f2u2CMvb32_j"

llvm-spirv/test/extensions/INTEL/SPV_INTEL_masked_gather_scatter/intel-gather-scatter.ll

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
; RUN: llvm-as -opaque-pointers=0 %s -o %t.bc
2-
; RUN: llvm-spirv %t.bc -opaque-pointers=0 --spirv-ext=+SPV_INTEL_masked_gather_scatter -o %t.spv
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_masked_gather_scatter -o %t.spv
33
; RUN: llvm-spirv %t.spv --to-text -o %t.spt
44
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
55

66
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
77
; RUN: llvm-dis -opaque-pointers=0 < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM
88

9-
; RUN: llvm-spirv %t.bc -opaque-pointers=0 --spirv-ext=+SPV_INTEL_masked_gather_scatter -o %t.spv -spirv-allow-unknown-intrinsics
9+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_masked_gather_scatter -o %t.spv -spirv-allow-unknown-intrinsics
1010
; RUN: llvm-spirv %t.spv --to-text -o %t.spt
1111
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
1212

13-
; RUN: not llvm-spirv %t.bc -opaque-pointers=0 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
13+
; RUN: not llvm-spirv %t.bc 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
1414
; CHECK-ERROR: RequiresExtension: Feature requires the following SPIR-V extension:
1515
; CHECK-ERROR-NEXT: SPV_INTEL_masked_gather_scatter
1616
; CHECK-ERROR-NEXT: NOTE: LLVM module contains vector of pointers, translation of which requires this extension

llvm-spirv/test/type-scavenger/varargs.ll

+10-8
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@ target triple = "spir-unknown-unknown"
88
@.str = internal unnamed_addr addrspace(2) constant [11 x i8] c"Value: %p\0A\00", align 1
99

1010

11-
; CHECK-DAG: 4 TypeInt [[INT:[0-9]+]] 32 0
12-
; CHECK-DAG: 4 TypeInt [[CHAR:[0-9]+]] 8 0
13-
; CHECK-DAG: 4 TypePointer [[INTPTR:[0-9]+]] 7 [[INT]]
14-
; CHECK-DAG: 4 TypePointer [[CHARPTR:[0-9]+]] 0 [[CHAR]]
15-
; CHECK: 5 Variable {{[0-9]+}} [[STR:[0-9]+]] 0
16-
; CHECK: 4 Variable [[INTPTR]] [[IPTR:[0-9]+]] 7
17-
; CHECK: 4 Bitcast [[CHARPTR]] [[I8STR:[0-9]+]] [[STR]]
18-
; CHECK: 7 ExtInst [[INT]] {{[0-9]+}} {{[0-9]+}} printf [[I8STR]] [[IPTR]]
11+
; CHECK-DAG: TypeInt [[INT:[0-9]+]] 32 0
12+
; CHECK-DAG: TypeInt [[CHAR:[0-9]+]] 8 0
13+
; CHECK-DAG: TypePointer [[INTPTR:[0-9]+]] 7 [[INT]]
14+
; CHECK-DAG: TypePointer [[CHARPTR:[0-9]+]] 0 [[CHAR]]
15+
; CHECK-DAG: TypePointer [[CHARPTR2:[0-9]+]] 7 [[CHAR]]
16+
; CHECK: Variable {{[0-9]+}} [[STR:[0-9]+]] 0
17+
; CHECK: Variable [[INTPTR]] [[IPTR:[0-9]+]] 7
18+
; CHECK: Bitcast [[CHARPTR]] [[I8STR:[0-9]+]] [[STR]]
19+
; CHECK: Bitcast [[CHARPTR2]] [[VAR8:[0-9]+]] [[IPTR]]
20+
; CHECK: ExtInst [[INT]] {{[0-9]+}} {{[0-9]+}} printf [[I8STR]] [[VAR8]]
1921

2022
; Function Attrs: nounwind
2123
define spir_kernel void @foo() {

0 commit comments

Comments
 (0)