Skip to content

Commit 488fb59

Browse files
committed
Add sign extend image operand.
1 parent 0fb198e commit 488fb59

File tree

3 files changed

+79
-28
lines changed

3 files changed

+79
-28
lines changed

clang/lib/CodeGen/Targets/SPIR.cpp

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ class CommonSPIRTargetCodeGenInfo : public TargetCodeGenInfo {
5656
llvm::Type *
5757
getHLSLType(CodeGenModule &CGM, const Type *Ty,
5858
const SmallVector<int32_t> *Packoffsets = nullptr) const override;
59+
llvm::Type *getSampleType(clang::CodeGen::CodeGenModule &CGM,
60+
clang::QualType Ty, llvm::LLVMContext &Ctx) const;
5961
llvm::Type *getSPIRVImageTypeFromHLSLResource(
6062
const HLSLAttributedResourceType::Attributes &attributes,
6163
llvm::Type *ElementType, llvm::LLVMContext &Ctx) const;
@@ -483,12 +485,13 @@ llvm::Type *CommonSPIRTargetCodeGenInfo::getHLSLType(
483485
assert(!ResAttrs.IsROV &&
484486
"Rasterizer order views not implemented for SPIR-V yet");
485487

486-
llvm::Type *ElemType = CGM.getTypes().ConvertType(ContainedTy);
487488
if (!ResAttrs.RawBuffer) {
488489
// convert element type
490+
llvm::Type *ElemType = getSampleType(CGM, ContainedTy, Ctx);
489491
return getSPIRVImageTypeFromHLSLResource(ResAttrs, ElemType, Ctx);
490492
}
491493

494+
llvm::Type *ElemType = CGM.getTypes().ConvertType(ContainedTy);
492495
llvm::ArrayType *RuntimeArrayType = llvm::ArrayType::get(ElemType, 0);
493496
uint32_t StorageClass = /* StorageBuffer storage class */ 12;
494497
bool IsWritable = ResAttrs.ResourceClass == llvm::dxil::ResourceClass::UAV;
@@ -515,16 +518,41 @@ llvm::Type *CommonSPIRTargetCodeGenInfo::getHLSLType(
515518
return nullptr;
516519
}
517520

521+
llvm::Type *CommonSPIRTargetCodeGenInfo::getSampleType(
522+
clang::CodeGen::CodeGenModule &CGM,
523+
clang::QualType Ty, llvm::LLVMContext &Ctx) const {
524+
Ty = Ty->getCanonicalTypeUnqualified();
525+
if (const VectorType *V = dyn_cast<VectorType>(Ty))
526+
Ty = V->getElementType();
527+
assert(!Ty->isVectorType() && "We still have a vector type.");
528+
529+
if (!Ty->isSignedIntegerType())
530+
return CGM.getTypes().ConvertType(Ty);
531+
532+
// We need to maintain signed integers as sign integers for the sampled type.
533+
// See https://docs.vulkan.org/spec/latest/appendices/spirvenv.html#spirvenv-image-signedness.
534+
535+
uint32_t OpTypeInt = 21;
536+
uint32_t BitWidth = CGM.getContext().getIntWidth(Ty);
537+
uint32_t AlignmentInBytes = CGM.getContext().getTypeAlign(Ty)/8;
538+
llvm::Type* BitWidthLitType = getInlineSpirvConstant(CGM, nullptr, llvm::APInt(32, BitWidth));
539+
llvm::Type* SignLitType = getInlineSpirvConstant(CGM, nullptr, llvm::APInt(32, 1));
540+
541+
return llvm::TargetExtType::get(Ctx, "spirv.Type", {BitWidthLitType, SignLitType},
542+
{OpTypeInt, BitWidth / 8, AlignmentInBytes});
543+
}
544+
518545
llvm::Type *CommonSPIRTargetCodeGenInfo::getSPIRVImageTypeFromHLSLResource(
519546
const HLSLAttributedResourceType::Attributes &attributes,
520-
llvm::Type *ElementType, llvm::LLVMContext &Ctx) const {
521-
522-
if (ElementType->isVectorTy())
523-
ElementType = ElementType->getScalarType();
547+
llvm::Type *SampledType, llvm::LLVMContext &Ctx) const {
524548

525-
assert((ElementType->isIntegerTy() || ElementType->isFloatingPointTy()) &&
526-
"The element type for a SPIR-V resource must be a scalar integer or "
527-
"floating point type.");
549+
// assert((SampledType->isIntegerTy() || SampledType->isFloatingPointTy() ||
550+
// (SampledType->isTargetExtTy() &&
551+
// SampledType->getTargetExtName() == "spirv.Type" &&
552+
// cast<llvm::TargetExtType>(SampledType)->getIntParameter(0) ==
553+
// /* OpTypeInt */ 21)) &&
554+
// "The element type for a SPIR-V resource must be a scalar integer or "
555+
// "floating point type.");
528556

529557
// These parameters correspond to the operands to the OpTypeImage SPIR-V
530558
// instruction. See
@@ -553,7 +581,7 @@ llvm::Type *CommonSPIRTargetCodeGenInfo::getSPIRVImageTypeFromHLSLResource(
553581
// Setting to unknown for now.
554582
IntParams[5] = 0;
555583

556-
return llvm::TargetExtType::get(Ctx, "spirv.Image", {ElementType}, IntParams);
584+
return llvm::TargetExtType::get(Ctx, "spirv.Image", {SampledType}, IntParams);
557585
}
558586

559587
std::unique_ptr<TargetCodeGenInfo>

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,16 @@ class SPIRVInstructionSelector : public InstructionSelector {
341341
GIntrinsic &HandleDef, MachineInstr &Pos) const;
342342
};
343343

344+
bool sampledTypeIsSignedInteger(const llvm::Type* HandleType) {
345+
const TargetExtType* TET = cast<TargetExtType>(HandleType);
346+
assert(TET && TET->getTargetExtName() == "spirv.Image");
347+
348+
if (!TET->getTypeParameter(0)->isIntegerTy()) {
349+
return false;
350+
}
351+
352+
return true;
353+
}
344354
} // end anonymous namespace
345355

346356
#define GET_GLOBALISEL_IMPL
@@ -1189,18 +1199,23 @@ bool SPIRVInstructionSelector::selectStore(MachineInstr &I) const {
11891199
MRI->createVirtualRegister(MRI->getRegClass(HandleReg));
11901200
auto *HandleDef = cast<GIntrinsic>(getVRegDef(*MRI, HandleReg));
11911201
SPIRVType *HandleType = GR.getSPIRVTypeForVReg(HandleReg);
1202+
const llvm::Type* LLVMHandleType = GR.getTypeForSPIRVType(HandleType);
11921203
if (!loadHandleBeforePosition(NewHandleReg, HandleType, *HandleDef, I)) {
11931204
return false;
11941205
}
11951206

11961207
Register IdxReg = IntPtrDef->getOperand(3).getReg();
11971208
if (HandleType->getOpcode() == SPIRV::OpTypeImage) {
1198-
return BuildMI(*I.getParent(), I, I.getDebugLoc(),
1199-
TII.get(SPIRV::OpImageWrite))
1200-
.addUse(NewHandleReg)
1201-
.addUse(IdxReg)
1202-
.addUse(StoreVal)
1203-
.constrainAllUses(TII, TRI, RBI);
1209+
auto BMI = BuildMI(*I.getParent(), I, I.getDebugLoc(),
1210+
TII.get(SPIRV::OpImageWrite))
1211+
.addUse(NewHandleReg)
1212+
.addUse(IdxReg)
1213+
.addUse(StoreVal);
1214+
1215+
if (sampledTypeIsSignedInteger(LLVMHandleType))
1216+
BMI.addImm(0x1000); // SignExtend
1217+
1218+
return BMI.constrainAllUses(TII, TRI, RBI);
12041219
}
12051220
}
12061221

@@ -3246,25 +3261,32 @@ bool SPIRVInstructionSelector::generateImageRead(Register &ResVReg,
32463261
Register ImageReg,
32473262
Register IdxReg, DebugLoc Loc,
32483263
MachineInstr &Pos) const {
3264+
SPIRVType *ImageType = GR.getSPIRVTypeForVReg(ImageReg);
3265+
bool IsSignedInteger = sampledTypeIsSignedInteger(GR.getTypeForSPIRVType(ImageType));
3266+
32493267
uint64_t ResultSize = GR.getScalarOrVectorComponentCount(ResType);
32503268
if (ResultSize == 4) {
3251-
return BuildMI(*Pos.getParent(), Pos, Loc, TII.get(SPIRV::OpImageRead))
3252-
.addDef(ResVReg)
3253-
.addUse(GR.getSPIRVTypeID(ResType))
3254-
.addUse(ImageReg)
3255-
.addUse(IdxReg)
3256-
.constrainAllUses(TII, TRI, RBI);
3269+
auto BMI = BuildMI(*Pos.getParent(), Pos, Loc, TII.get(SPIRV::OpImageRead))
3270+
.addDef(ResVReg)
3271+
.addUse(GR.getSPIRVTypeID(ResType))
3272+
.addUse(ImageReg)
3273+
.addUse(IdxReg);
3274+
3275+
if (IsSignedInteger)
3276+
BMI.addImm(0x1000); // SignExtend
3277+
return BMI.constrainAllUses(TII, TRI, RBI);
32573278
}
32583279

32593280
SPIRVType *ReadType = widenTypeToVec4(ResType, Pos);
32603281
Register ReadReg = MRI->createVirtualRegister(GR.getRegClass(ReadType));
3261-
bool Succeed =
3262-
BuildMI(*Pos.getParent(), Pos, Loc, TII.get(SPIRV::OpImageRead))
3263-
.addDef(ReadReg)
3264-
.addUse(GR.getSPIRVTypeID(ReadType))
3265-
.addUse(ImageReg)
3266-
.addUse(IdxReg)
3267-
.constrainAllUses(TII, TRI, RBI);
3282+
auto BMI = BuildMI(*Pos.getParent(), Pos, Loc, TII.get(SPIRV::OpImageRead))
3283+
.addDef(ReadReg)
3284+
.addUse(GR.getSPIRVTypeID(ReadType))
3285+
.addUse(ImageReg)
3286+
.addUse(IdxReg);
3287+
if (IsSignedInteger)
3288+
BMI.addImm(0x1000); // SignExtend
3289+
bool Succeed = BMI.constrainAllUses(TII, TRI, RBI);
32683290
if (!Succeed)
32693291
return false;
32703292

offload-test-suite

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit ef40d70010f26bc3f385e948736e75a470c9aec8

0 commit comments

Comments
 (0)