Skip to content

Commit be9bfe6

Browse files
Revert "Use Sign/ZeroExtend image operands for read/write_image"
This reverts commit 4256e4e. This change enabled a test that is failing on Windows, so I'm leaving it out of this week's pulldown.
1 parent 7bd097c commit be9bfe6

File tree

9 files changed

+32
-131
lines changed

9 files changed

+32
-131
lines changed

llvm-spirv/lib/SPIRV/OCLToSPIRV.cpp

Lines changed: 9 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -84,20 +84,6 @@ static Type *getBlockStructType(Value *Parameter) {
8484
return ParamType;
8585
}
8686

87-
/// Return one of the SPIR-V 1.4 SignExtend or ZeroExtend image operands
88-
/// for a demangled function name, or 0 if the function does not return an
89-
/// integer type (e.g. read_imagef).
90-
static unsigned getImageSignZeroExt(StringRef DemangledName) {
91-
bool IsSigned = !DemangledName.endswith("ui") && DemangledName.back() == 'i';
92-
bool IsUnsigned = DemangledName.endswith("ui");
93-
94-
if (IsSigned)
95-
return ImageOperandsMask::ImageOperandsSignExtendMask;
96-
if (IsUnsigned)
97-
return ImageOperandsMask::ImageOperandsZeroExtendMask;
98-
return 0;
99-
}
100-
10187
bool OCLToSPIRVLegacy::runOnModule(Module &M) {
10288
setOCLTypeToSPIRV(&getAnalysis<OCLTypeToSPIRVLegacy>());
10389
return runOCLToSPIRV(M);
@@ -280,7 +266,7 @@ void OCLToSPIRVBase::visitCallInst(CallInst &CI) {
280266
}
281267
if (DemangledName.find(kOCLBuiltinName::ReadImage) == 0) {
282268
if (MangledName.find(kMangledName::Sampler) != StringRef::npos) {
283-
visitCallReadImageWithSampler(&CI, MangledName, DemangledName);
269+
visitCallReadImageWithSampler(&CI, MangledName);
284270
return;
285271
}
286272
if (MangledName.find("msaa") != StringRef::npos) {
@@ -987,8 +973,7 @@ void OCLToSPIRVBase::visitCallReadImageMSAA(CallInst *CI,
987973
}
988974

989975
void OCLToSPIRVBase::visitCallReadImageWithSampler(CallInst *CI,
990-
StringRef MangledName,
991-
StringRef DemangledName) {
976+
StringRef MangledName) {
992977
assert(MangledName.find(kMangledName::Sampler) != StringRef::npos);
993978
assert(CI->getCalledFunction() && "Unexpected indirect call");
994979
Function *Func = CI->getCalledFunction();
@@ -1014,26 +999,22 @@ void OCLToSPIRVBase::visitCallReadImageWithSampler(CallInst *CI,
1014999
Args[0] = SampledImg;
10151000
Args.erase(Args.begin() + 1, Args.begin() + 2);
10161001

1017-
unsigned ImgOpMask = getImageSignZeroExt(DemangledName);
1018-
unsigned ImgOpMaskInsIndex = Args.size();
10191002
switch (Args.size()) {
10201003
case 2: // no lod
1021-
ImgOpMask |= ImageOperandsMask::ImageOperandsLodMask;
1022-
ImgOpMaskInsIndex = Args.size();
1004+
Args.push_back(getInt32(M, ImageOperandsMask::ImageOperandsLodMask));
10231005
Args.push_back(getFloat32(M, 0.f));
10241006
break;
10251007
case 3: // explicit lod
1026-
ImgOpMask |= ImageOperandsMask::ImageOperandsLodMask;
1027-
ImgOpMaskInsIndex = 2;
1008+
Args.insert(Args.begin() + 2,
1009+
getInt32(M, ImageOperandsMask::ImageOperandsLodMask));
10281010
break;
10291011
case 4: // gradient
1030-
ImgOpMask |= ImageOperandsMask::ImageOperandsGradMask;
1031-
ImgOpMaskInsIndex = 2;
1012+
Args.insert(Args.begin() + 2,
1013+
getInt32(M, ImageOperandsMask::ImageOperandsGradMask));
10321014
break;
10331015
default:
10341016
assert(0 && "read_image* with unhandled number of args!");
10351017
}
1036-
Args.insert(Args.begin() + ImgOpMaskInsIndex, getInt32(M, ImgOpMask));
10371018

10381019
// SPIR-V instruction always returns 4-element vector
10391020
if (IsRetScalar)
@@ -1149,32 +1130,19 @@ void OCLToSPIRVBase::visitCallBuiltinSimple(CallInst *CI, StringRef MangledName,
11491130
void OCLToSPIRVBase::visitCallReadWriteImage(CallInst *CI,
11501131
StringRef DemangledName) {
11511132
OCLBuiltinTransInfo Info;
1152-
if (DemangledName.find(kOCLBuiltinName::ReadImage) == 0) {
1133+
if (DemangledName.find(kOCLBuiltinName::ReadImage) == 0)
11531134
Info.UniqName = kOCLBuiltinName::ReadImage;
1154-
unsigned ImgOpMask = getImageSignZeroExt(DemangledName);
1155-
if (ImgOpMask) {
1156-
Info.PostProc = [&](std::vector<Value *> &Args) {
1157-
Args.push_back(getInt32(M, ImgOpMask));
1158-
};
1159-
}
1160-
}
11611135

11621136
if (DemangledName.find(kOCLBuiltinName::WriteImage) == 0) {
11631137
Info.UniqName = kOCLBuiltinName::WriteImage;
11641138
Info.PostProc = [&](std::vector<Value *> &Args) {
1165-
unsigned ImgOpMask = getImageSignZeroExt(DemangledName);
1166-
unsigned ImgOpMaskInsIndex = Args.size();
11671139
if (Args.size() == 4) // write with lod
11681140
{
11691141
auto Lod = Args[2];
11701142
Args.erase(Args.begin() + 2);
1171-
ImgOpMask |= ImageOperandsMask::ImageOperandsLodMask;
1172-
ImgOpMaskInsIndex = Args.size();
1143+
Args.push_back(getInt32(M, ImageOperandsMask::ImageOperandsLodMask));
11731144
Args.push_back(Lod);
11741145
}
1175-
if (ImgOpMask) {
1176-
Args.insert(Args.begin() + ImgOpMaskInsIndex, getInt32(M, ImgOpMask));
1177-
}
11781146
};
11791147
}
11801148

llvm-spirv/lib/SPIRV/OCLToSPIRV.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,7 @@ class OCLToSPIRVBase : public InstVisitor<OCLToSPIRVBase> {
169169
/// read_image(image, sampler, ...) =>
170170
/// sampled_image = __spirv_SampledImage(image, sampler);
171171
/// return __spirv_ImageSampleExplicitLod_R{ReturnType}(sampled_image, ...);
172-
void visitCallReadImageWithSampler(CallInst *CI, StringRef MangledName,
173-
StringRef DemangledName);
172+
void visitCallReadImageWithSampler(CallInst *CI, StringRef MangledName);
174173

175174
/// Transform read_image with msaa image arguments.
176175
/// Sample argument must be acoded as Image Operand.

llvm-spirv/lib/SPIRV/SPIRVToOCL.cpp

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -751,43 +751,27 @@ void SPIRVToOCLBase::visitCallGroupWaitEvents(CallInst *CI, Op OC) {
751751
&Attrs);
752752
}
753753

754-
static std::string getTypeSuffix(Type *T, bool IsSigned) {
755-
std::string Suffix;
754+
static char getTypeSuffix(Type *T) {
755+
char Suffix;
756756

757757
Type *ST = T->getScalarType();
758758
if (ST->isHalfTy())
759-
Suffix = "h";
759+
Suffix = 'h';
760760
else if (ST->isFloatTy())
761-
Suffix = "f";
762-
else if (IsSigned)
763-
Suffix = "i";
761+
Suffix = 'f';
764762
else
765-
Suffix = "ui";
763+
Suffix = 'i';
766764

767765
return Suffix;
768766
}
769767

770768
void SPIRVToOCLBase::mutateArgsForImageOperands(std::vector<Value *> &Args,
771-
unsigned ImOpArgIndex,
772-
bool &IsSigned) {
773-
// Default to signed.
774-
IsSigned = true;
769+
unsigned ImOpArgIndex) {
775770
if (Args.size() > ImOpArgIndex) {
776771
ConstantInt *ImOp = dyn_cast<ConstantInt>(Args[ImOpArgIndex]);
777772
uint64_t ImOpValue = 0;
778773
if (ImOp)
779774
ImOpValue = ImOp->getZExtValue();
780-
unsigned SignZeroExtMasks = ImageOperandsMask::ImageOperandsSignExtendMask |
781-
ImageOperandsMask::ImageOperandsZeroExtendMask;
782-
// If one of the SPIR-V 1.4 SignExtend/ZeroExtend operands is present, take
783-
// it into account and drop the mask.
784-
if (ImOpValue & SignZeroExtMasks) {
785-
if (ImOpValue & ImageOperandsMask::ImageOperandsZeroExtendMask)
786-
IsSigned = false;
787-
ImOpValue &= ~SignZeroExtMasks;
788-
Args[3] = getInt32(M, ImOpValue);
789-
ImOp = cast<ConstantInt>(Args[3]);
790-
}
791775
// Drop "Image Operands" argument.
792776
Args.erase(Args.begin() + ImOpArgIndex);
793777

@@ -801,6 +785,7 @@ void SPIRVToOCLBase::mutateArgsForImageOperands(std::vector<Value *> &Args,
801785
}
802786
}
803787

788+
// TODO: Handle unsigned integer return type. May need spec change.
804789
void SPIRVToOCLBase::visitCallSPIRVImageSampleExplicitLodBuiltIn(CallInst *CI,
805790
Op OC) {
806791
assert(CI->getCalledFunction() && "Unexpected indirect call");
@@ -822,8 +807,7 @@ void SPIRVToOCLBase::visitCallSPIRVImageSampleExplicitLodBuiltIn(CallInst *CI,
822807
auto Sampler = CallSampledImg->getArgOperand(1);
823808
Args[0] = Img;
824809
Args.insert(Args.begin() + 1, Sampler);
825-
bool IsSigned;
826-
mutateArgsForImageOperands(Args, 3, IsSigned);
810+
mutateArgsForImageOperands(Args, 3);
827811
if (CallSampledImg->hasOneUse()) {
828812
CallSampledImg->replaceAllUsesWith(
829813
UndefValue::get(CallSampledImg->getType()));
@@ -834,8 +818,7 @@ void SPIRVToOCLBase::visitCallSPIRVImageSampleExplicitLodBuiltIn(CallInst *CI,
834818
if (auto VT = dyn_cast<VectorType>(T))
835819
T = VT->getElementType();
836820
RetTy = IsDepthImage ? T : CI->getType();
837-
return std::string(kOCLBuiltinName::SampledReadImage) +
838-
getTypeSuffix(T, IsSigned);
821+
return std::string(kOCLBuiltinName::SampledReadImage) + getTypeSuffix(T);
839822
};
840823

841824
auto ModifyRetTy = [=](CallInst *NewCI) -> Instruction * {
@@ -859,13 +842,11 @@ void SPIRVToOCLBase::visitCallSPIRVImageWriteBuiltIn(CallInst *CI, Op OC) {
859842
M, CI,
860843
[=](CallInst *, std::vector<Value *> &Args) {
861844
llvm::Type *T = Args[2]->getType();
862-
bool IsSigned;
863-
mutateArgsForImageOperands(Args, 3, IsSigned);
845+
mutateArgsForImageOperands(Args, 3);
864846
if (Args.size() > 3) {
865847
std::swap(Args[2], Args[3]);
866848
}
867-
return std::string(kOCLBuiltinName::WriteImage) +
868-
getTypeSuffix(T, IsSigned);
849+
return std::string(kOCLBuiltinName::WriteImage) + getTypeSuffix(T);
869850
},
870851
&Attrs);
871852
}
@@ -876,11 +857,9 @@ void SPIRVToOCLBase::visitCallSPIRVImageReadBuiltIn(CallInst *CI, Op OC) {
876857
mutateCallInstOCL(
877858
M, CI,
878859
[=](CallInst *, std::vector<Value *> &Args) {
879-
bool IsSigned;
880-
mutateArgsForImageOperands(Args, 2, IsSigned);
860+
mutateArgsForImageOperands(Args, 2);
881861
llvm::Type *T = CI->getType();
882-
return std::string(kOCLBuiltinName::ReadImage) +
883-
getTypeSuffix(T, IsSigned);
862+
return std::string(kOCLBuiltinName::ReadImage) + getTypeSuffix(T);
884863
},
885864
&Attrs);
886865
}

llvm-spirv/lib/SPIRV/SPIRVToOCL.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,10 +273,9 @@ class SPIRVToOCLBase : public InstVisitor<SPIRVToOCLBase> {
273273
std::string translateOpaqueType(StringRef STName);
274274

275275
/// Mutate the argument list based on (optional) image operands at position
276-
/// ImOpArgIndex. Set IsSigned according to any SignExtend/ZeroExtend Image
277-
/// Operands present in Args, or default to signed if there are none.
276+
/// ImOpArgIndex.
278277
void mutateArgsForImageOperands(std::vector<Value *> &Args,
279-
unsigned ImOpArgIndex, bool &IsSigned);
278+
unsigned ImOpArgIndex);
280279

281280
protected:
282281
Module *M;

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

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -157,47 +157,6 @@ std::vector<SPIRVType *> SPIRVInstruction::getOperandTypes() {
157157
return getOperandTypes(getOperands());
158158
}
159159

160-
size_t SPIRVImageInstBase::getImageOperandsIndex() const {
161-
switch (OpCode) {
162-
case OpImageRead:
163-
case OpImageSampleExplicitLod:
164-
return 2;
165-
case OpImageWrite:
166-
return 3;
167-
default:
168-
return ~0U;
169-
}
170-
}
171-
172-
void SPIRVImageInstBase::setOpWords(const std::vector<SPIRVWord> &OpsArg) {
173-
std::vector<SPIRVWord> Ops = OpsArg;
174-
175-
// If the Image Operands field has the SignExtend or ZeroExtend bit set,
176-
// either raise the minimum SPIR-V version to 1.4, or drop the operand
177-
// if SPIR-V 1.4 cannot be emitted.
178-
size_t ImgOpsIndex = getImageOperandsIndex();
179-
if (ImgOpsIndex != ~0U && ImgOpsIndex < Ops.size()) {
180-
SPIRVWord ImgOps = Ops[ImgOpsIndex];
181-
unsigned SignZeroExtMasks = ImageOperandsMask::ImageOperandsSignExtendMask |
182-
ImageOperandsMask::ImageOperandsZeroExtendMask;
183-
if (ImgOps & SignZeroExtMasks) {
184-
SPIRVModule *M = getModule();
185-
if (M->isAllowedToUseVersion(VersionNumber::SPIRV_1_4)) {
186-
M->setMinSPIRVVersion(static_cast<SPIRVWord>(VersionNumber::SPIRV_1_4));
187-
} else {
188-
// Drop SignExtend/ZeroExtend if we cannot use SPIR-V 1.4.
189-
Ops[ImgOpsIndex] &= ~SignZeroExtMasks;
190-
if (Ops[ImgOpsIndex] == 0) {
191-
// Drop the Image Operands if SignExtend/ZeroExtend was the only
192-
// bit set.
193-
Ops.pop_back();
194-
}
195-
}
196-
}
197-
}
198-
SPIRVInstTemplateBase::setOpWords(Ops);
199-
}
200-
201160
bool isSpecConstantOpAllowedOp(Op OC) {
202161
static SPIRVWord Table[] = {
203162
OpSConvert,

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2763,12 +2763,6 @@ class SPIRVImageInstBase : public SPIRVInstTemplateBase {
27632763
SPIRVCapVec getRequiredCapability() const override {
27642764
return getVec(CapabilityImageBasic);
27652765
}
2766-
2767-
protected:
2768-
void setOpWords(const std::vector<SPIRVWord> &OpsArg) override;
2769-
2770-
private:
2771-
size_t getImageOperandsIndex() const;
27722766
};
27732767

27742768
#define _SPIRV_OP(x, ...) \

llvm-spirv/test/read_image.cl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// RUN: %clang_cc1 -triple spir64 -fdeclare-opencl-builtins -finclude-default-header -O0 -cl-std=CL2.0 -emit-llvm-bc %s -o %t.bc -no-opaque-pointers
2-
// RUN: llvm-spirv --spirv-max-version=1.3 %t.bc -o %t.spv
2+
// RUN: llvm-spirv %t.bc -o %t.spv
33
// RUN: spirv-val %t.spv
44
// RUN: llvm-spirv %t.spv -to-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
55
// RUN: llvm-spirv -r %t.spv -o %t.rev.bc --spirv-target-env=SPV-IR
66
// RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-SPV-LLVM
7-
// RUN: llvm-spirv --spirv-max-version=1.3 %t.rev.bc -o %t.rev.spv
7+
// RUN: llvm-spirv %t.rev.bc -o %t.rev.spv
88
// RUN: spirv-val %t.rev.spv
9-
// RUN: llvm-spirv --spirv-max-version=1.3 %t.rev.spv -to-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
9+
// RUN: llvm-spirv %t.rev.spv -to-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
1010

1111
// CHECK-SPIRV: TypeInt [[IntTy:[0-9]+]]
1212
// CHECK-SPIRV: TypeVector [[IVecTy:[0-9]+]] [[IntTy]]

llvm-spirv/test/transcoding/SampledImage.cl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %clang_cc1 -triple spir -cl-std=CL2.0 %s -fdeclare-opencl-builtins -finclude-default-header -emit-llvm-bc -o %t.bc -no-opaque-pointers
22
// RUN: llvm-spirv %t.bc -spirv-text -o %t.txt
33
// RUN: FileCheck < %t.txt %s --check-prefix=CHECK-SPIRV
4-
// RUN: llvm-spirv --spirv-max-version=1.3 %t.bc -o %t.spv
4+
// RUN: llvm-spirv %t.bc -o %t.spv
55
// RUN: spirv-val %t.spv
66
// RUN: llvm-spirv -r %t.spv -o %t.rev.bc
77
// RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM

llvm-spirv/test/transcoding/image_signedness.ll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
; Test that signedness of calls to read_image(u)i/write_image(u)i is preserved.
22

3+
; TODO: Translator does not handle signedness for read_image/write_image yet.
4+
; XFAIL: *
5+
36
; RUN: llvm-as %s -o %t.bc
47
; RUN: llvm-spirv %t.bc -o %t.spv
58
; RUN: spirv-val %t.spv

0 commit comments

Comments
 (0)