Skip to content

Commit ec5ec34

Browse files
wenju-hesys-ce-bb
authored andcommitted
Fix image builtin mangling of unsigned type (#2273)
Return type of image read and Texel type of image write builtins may be unsigned. Before this PR, the builtin names in SPIR-V Friendly IR were always mangled with signed type. Original commit: KhronosGroup/SPIRV-LLVM-Translator@e9b95fb
1 parent 9d1dfd9 commit ec5ec34

File tree

6 files changed

+57
-25
lines changed

6 files changed

+57
-25
lines changed

llvm-spirv/lib/SPIRV/SPIRVInternal.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,9 @@ std::string getImageBaseTypeName(StringRef Name);
830830
/// Extract the image type descriptor from the given image type.
831831
SPIRVTypeImageDescriptor getImageDescriptor(Type *Ty);
832832

833+
/// Return the index of image operands given an image op.
834+
size_t getImageOperandsIndex(Op OpCode);
835+
833836
/// Check if access qualifier is encoded in the type name.
834837
bool hasAccessQualifiedName(StringRef TyName);
835838

@@ -901,9 +904,11 @@ std::string getSPIRVFriendlyIRFunctionName(OCLExtOpKind ExtOpId,
901904
/// \param OC opcode of corresponding built-in instruction. Used to gather info
902905
/// for unsigned/constant arguments.
903906
/// \param Types of arguments of SPIR-V built-in function
907+
/// \param Ops Operands of SPIRVInstruction
904908
/// \return IA64 mangled name.
905909
std::string getSPIRVFriendlyIRFunctionName(const std::string &UniqName,
906-
spv::Op OC, ArrayRef<Type *> ArgTys);
910+
spv::Op OC, ArrayRef<Type *> ArgTys,
911+
ArrayRef<SPIRVValue *> Ops);
907912

908913
/// Get i8* with the same address space.
909914
PointerType *getInt8PtrTy(PointerType *T);

llvm-spirv/lib/SPIRV/SPIRVReader.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3211,7 +3211,7 @@ Instruction *SPIRVToLLVM::transBuiltinFromInst(const std::string &FuncName,
32113211
mangleOpenClBuiltin(FuncName, ArgTys, MangledName);
32123212
else
32133213
MangledName =
3214-
getSPIRVFriendlyIRFunctionName(FuncName, BI->getOpCode(), ArgTys);
3214+
getSPIRVFriendlyIRFunctionName(FuncName, BI->getOpCode(), ArgTys, Ops);
32153215

32163216
opaquifyTypedPointers(ArgTys);
32173217

@@ -3355,7 +3355,7 @@ Instruction *SPIRVToLLVM::transSPIRVBuiltinFromInst(SPIRVInstruction *BI,
33553355
}
33563356
}
33573357

3358-
bool IsRetSigned;
3358+
bool IsRetSigned = true;
33593359
switch (OC) {
33603360
case OpConvertFToU:
33613361
case OpSatConvertSToU:
@@ -3364,8 +3364,17 @@ Instruction *SPIRVToLLVM::transSPIRVBuiltinFromInst(SPIRVInstruction *BI,
33643364
case OpUDotAccSatKHR:
33653365
IsRetSigned = false;
33663366
break;
3367+
case OpImageRead:
3368+
case OpImageSampleExplicitLod: {
3369+
size_t Idx = getImageOperandsIndex(OC);
3370+
if (auto Ops = BI->getOperands(); Ops.size() > Idx) {
3371+
auto ImOp = static_cast<SPIRVConstant *>(Ops[Idx])->getZExtIntValue();
3372+
IsRetSigned = !(ImOp & ImageOperandsMask::ImageOperandsZeroExtendMask);
3373+
}
3374+
break;
3375+
}
33673376
default:
3368-
IsRetSigned = true;
3377+
break;
33693378
}
33703379

33713380
if (AddRetTypePostfix) {

llvm-spirv/lib/SPIRV/SPIRVUtil.cpp

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1598,6 +1598,18 @@ std::string getImageBaseTypeName(StringRef Name) {
15981598
return ImageTyName;
15991599
}
16001600

1601+
size_t getImageOperandsIndex(Op OpCode) {
1602+
switch (OpCode) {
1603+
case OpImageRead:
1604+
case OpImageSampleExplicitLod:
1605+
return 2;
1606+
case OpImageWrite:
1607+
return 3;
1608+
default:
1609+
return ~0U;
1610+
}
1611+
}
1612+
16011613
SPIRVTypeImageDescriptor getImageDescriptor(Type *Ty) {
16021614
if (auto *TET = dyn_cast_or_null<TargetExtType>(Ty)) {
16031615
auto IntParams = TET->int_params();
@@ -2273,8 +2285,9 @@ bool postProcessBuiltinsWithArrayArguments(Module *M, bool IsCpp) {
22732285
namespace {
22742286
class SPIRVFriendlyIRMangleInfo : public BuiltinFuncMangleInfo {
22752287
public:
2276-
SPIRVFriendlyIRMangleInfo(spv::Op OC, ArrayRef<Type *> ArgTys)
2277-
: OC(OC), ArgTys(ArgTys) {}
2288+
SPIRVFriendlyIRMangleInfo(spv::Op OC, ArrayRef<Type *> ArgTys,
2289+
ArrayRef<SPIRVValue *> Ops)
2290+
: OC(OC), ArgTys(ArgTys), Ops(Ops) {}
22782291

22792292
void init(StringRef UniqUnmangledName) override {
22802293
UnmangledName = UniqUnmangledName.str();
@@ -2434,6 +2447,15 @@ class SPIRVFriendlyIRMangleInfo : public BuiltinFuncMangleInfo {
24342447
case OpSUDotAccSatKHR:
24352448
addUnsignedArg(1);
24362449
break;
2450+
case OpImageWrite: {
2451+
size_t Idx = getImageOperandsIndex(OC);
2452+
if (Ops.size() > Idx) {
2453+
auto ImOp = static_cast<SPIRVConstant *>(Ops[Idx])->getZExtIntValue();
2454+
if (ImOp & ImageOperandsMask::ImageOperandsZeroExtendMask)
2455+
addUnsignedArg(2);
2456+
}
2457+
break;
2458+
}
24372459
default:;
24382460
// No special handling is needed
24392461
}
@@ -2442,6 +2464,7 @@ class SPIRVFriendlyIRMangleInfo : public BuiltinFuncMangleInfo {
24422464
private:
24432465
spv::Op OC;
24442466
ArrayRef<Type *> ArgTys;
2467+
ArrayRef<SPIRVValue *> Ops;
24452468
};
24462469
class OpenCLStdToSPIRVFriendlyIRMangleInfo : public BuiltinFuncMangleInfo {
24472470
public:
@@ -2511,9 +2534,9 @@ std::string getSPIRVFriendlyIRFunctionName(OCLExtOpKind ExtOpId,
25112534
}
25122535

25132536
std::string getSPIRVFriendlyIRFunctionName(const std::string &UniqName,
2514-
spv::Op OC,
2515-
ArrayRef<Type *> ArgTys) {
2516-
SPIRVFriendlyIRMangleInfo MangleInfo(OC, ArgTys);
2537+
spv::Op OC, ArrayRef<Type *> ArgTys,
2538+
ArrayRef<SPIRVValue *> Ops) {
2539+
SPIRVFriendlyIRMangleInfo MangleInfo(OC, ArgTys, Ops);
25172540
return mangleBuiltin(UniqName, ArgTys, &MangleInfo);
25182541
}
25192542

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

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "SPIRVInstruction.h"
4141
#include "SPIRVBasicBlock.h"
4242
#include "SPIRVFunction.h"
43+
#include "SPIRVInternal.h"
4344

4445
#include <unordered_set>
4546

@@ -157,25 +158,13 @@ std::vector<SPIRVType *> SPIRVInstruction::getOperandTypes() {
157158
return getOperandTypes(getOperands());
158159
}
159160

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-
172161
void SPIRVImageInstBase::setOpWords(const std::vector<SPIRVWord> &OpsArg) {
173162
std::vector<SPIRVWord> Ops = OpsArg;
174163

175164
// If the Image Operands field has the SignExtend or ZeroExtend bit set,
176165
// either raise the minimum SPIR-V version to 1.4, or drop the operand
177166
// if SPIR-V 1.4 cannot be emitted.
178-
size_t ImgOpsIndex = getImageOperandsIndex();
167+
size_t ImgOpsIndex = getImageOperandsIndex(OpCode);
179168
if (ImgOpsIndex != ~0U && ImgOpsIndex < Ops.size()) {
180169
SPIRVWord ImgOps = Ops[ImgOpsIndex];
181170
unsigned SignZeroExtMasks = ImageOperandsMask::ImageOperandsSignExtendMask |

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2823,9 +2823,6 @@ class SPIRVImageInstBase : public SPIRVInstTemplateBase {
28232823

28242824
protected:
28252825
void setOpWords(const std::vector<SPIRVWord> &OpsArg) override;
2826-
2827-
private:
2828-
size_t getImageOperandsIndex() const;
28292826
};
28302827

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

llvm-spirv/test/transcoding/image_signedness.ll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
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
8+
; RUN: llvm-spirv -r --spirv-target-env=SPV-IR %t.spv -o %t.rev.bc
9+
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-SPV-IR
810

911
; ModuleID = 'image_signedness.ll'
1012
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"
@@ -21,6 +23,11 @@ target triple = "spir-unknown-unknown"
2123
; CHECK-LLVM: call spir_func <4 x i32> @_Z12read_imageui20ocl_image1d_array_rwDv2_i(
2224
; CHECK-LLVM: call spir_func <4 x i32> @_Z12read_imageui14ocl_image1d_roi(
2325
; CHECK-LLVM: call spir_func <4 x i32> @_Z11read_imagei14ocl_image1d_roi(
26+
; CHECK-SPV-IR: call spir_func <4 x i32> @_Z37__spirv_ImageSampleExplicitLod_Ruint4PU3AS140__spirv_SampledImage__void_0_0_0_0_0_0_0iif(
27+
; CHECK-SPV-IR: call spir_func <4 x i32> @_Z36__spirv_ImageSampleExplicitLod_Rint4PU3AS140__spirv_SampledImage__void_0_0_0_0_0_0_0iif(
28+
; CHECK-SPV-IR: call spir_func <4 x i32> @_Z24__spirv_ImageRead_Ruint4PU3AS133__spirv_Image__void_0_0_1_0_0_0_2Dv2_ii(
29+
; CHECK-SPV-IR: call spir_func <4 x i32> @_Z24__spirv_ImageRead_Ruint4PU3AS133__spirv_Image__void_0_0_0_0_0_0_0ii(
30+
; CHECK-SPV-IR: call spir_func <4 x i32> @_Z23__spirv_ImageRead_Rint4PU3AS133__spirv_Image__void_0_0_0_0_0_0_0ii(
2431

2532
; Function Attrs: convergent nounwind
2633
define dso_local spir_kernel void @imagereads(ptr addrspace(1) %im, ptr addrspace(1) %ima, ptr addrspace(1) nocapture %res, ptr addrspace(1) nocapture %resu) local_unnamed_addr #0 !kernel_arg_addr_space !4 !kernel_arg_access_qual !5 !kernel_arg_type !6 !kernel_arg_base_type !7 !kernel_arg_type_qual !8 {
@@ -42,6 +49,8 @@ entry:
4249
; CHECK-LLVM-LABEL: @imagewrites
4350
; CHECK-LLVM: call spir_func void @_Z12write_imagei14ocl_image2d_woDv2_iDv4_i(
4451
; CHECK-LLVM: call spir_func void @_Z13write_imageui14ocl_image2d_woDv2_iDv4_j(
52+
; CHECK-SPV-IR: call spir_func void @_Z18__spirv_ImageWritePU3AS133__spirv_Image__void_1_0_0_0_0_0_1Dv2_iDv4_ii(
53+
; CHECK-SPV-IR: call spir_func void @_Z18__spirv_ImageWritePU3AS133__spirv_Image__void_1_0_0_0_0_0_1Dv2_iDv4_ji(
4554

4655
; Function Attrs: alwaysinline convergent nounwind
4756
define spir_kernel void @imagewrites(i32 %offset, ptr addrspace(1) nocapture readonly %input, ptr addrspace(1) nocapture readonly %inputu, ptr addrspace(1) %output) local_unnamed_addr #0 !kernel_arg_addr_space !14 !kernel_arg_access_qual !15 !kernel_arg_type !16 !kernel_arg_base_type !17 !kernel_arg_type_qual !18 !kernel_arg_name !19 !kernel_attributes !20 {

0 commit comments

Comments
 (0)