From 21342cb8e9182fb1eb8454864596d5ecc464471f Mon Sep 17 00:00:00 2001 From: Ben Ashbaugh Date: Tue, 20 Aug 2024 06:11:45 -0700 Subject: [PATCH] [Backport to 14] add reverse translation for OpDecorateString and OpMemberDecorateString (#2677) This PR adds "reverse translation" (from SPIR-V to LLVM IR) support for OpDecorateString and OpMemberDecorateString, see #2460 and #2670. These instructions are currently treated as synonyms for OpDecorate and OpMemberDecorate. We'll want to tidy this up at some point, but at least for now we won't crash if we see these instructions. I'll still need to add proper support for decorating variables in the input storage class for #2670, but I'll do that in a separate PR. (cherry picked from commit f7057b44e20fd06ce8ff885af37befcfc5893894) --- lib/SPIRV/SPIRVReader.cpp | 5 ++- lib/SPIRV/libSPIRV/SPIRVDecorate.h | 4 ++ lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h | 2 + test/OpDecorateString_UserSemantic.spvasm | 33 +++++++++++++++++ ...OpMemberDecorateString_UserSemantic.spvasm | 37 +++++++++++++++++++ 5 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 test/OpDecorateString_UserSemantic.spvasm create mode 100644 test/OpMemberDecorateString_UserSemantic.spvasm diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 239d0accb4..b8580267fc 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -3649,9 +3649,10 @@ void SPIRVToLLVM::transIntelFPGADecorations(SPIRVValue *BV, Value *V) { if (!AnnotStr.empty()) { auto *GS = Builder.CreateGlobalStringPtr(AnnotStr); - auto GEP = Builder.CreateConstInBoundsGEP2_32(AllocatedTy, AL, 0, I); + auto *GEP = cast( + Builder.CreateConstInBoundsGEP2_32(AllocatedTy, AL, 0, I)); - Type *IntTy = GEP->getType()->getPointerElementType()->isIntegerTy() + Type *IntTy = GEP->getResultElementType()->isIntegerTy() ? GEP->getType() : Int8PtrTyPrivate; diff --git a/lib/SPIRV/libSPIRV/SPIRVDecorate.h b/lib/SPIRV/libSPIRV/SPIRVDecorate.h index c9e58fdc80..a7f8bd37ce 100644 --- a/lib/SPIRV/libSPIRV/SPIRVDecorate.h +++ b/lib/SPIRV/libSPIRV/SPIRVDecorate.h @@ -203,6 +203,8 @@ class SPIRVDecorate : public SPIRVDecorateGeneric { } }; +class SPIRVDecorateString : public SPIRVDecorate {}; + class SPIRVDecorateId : public SPIRVDecorateGeneric { public: static const Op OC = OpDecorateId; @@ -352,6 +354,8 @@ class SPIRVMemberDecorate : public SPIRVDecorateGeneric { SPIRVWord MemberNumber; }; +class SPIRVMemberDecorateString : public SPIRVMemberDecorate {}; + class SPIRVDecorationGroup : public SPIRVEntry { public: static const Op OC = OpDecorationGroup; diff --git a/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h b/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h index 6a22ab9623..a31342dc30 100644 --- a/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h +++ b/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h @@ -364,6 +364,8 @@ _SPIRV_OP(AtomicFMinEXT, 5614) _SPIRV_OP(AtomicFMaxEXT, 5615) _SPIRV_OP(AssumeTrueKHR, 5630) _SPIRV_OP(ExpectKHR, 5631) +_SPIRV_OP(DecorateString, 5632) +_SPIRV_OP(MemberDecorateString, 5633) _SPIRV_OP(VmeImageINTEL, 5699) _SPIRV_OP(TypeVmeImageINTEL, 5700) _SPIRV_OP(TypeAvcImePayloadINTEL, 5701) diff --git a/test/OpDecorateString_UserSemantic.spvasm b/test/OpDecorateString_UserSemantic.spvasm new file mode 100644 index 0000000000..f6df26883c --- /dev/null +++ b/test/OpDecorateString_UserSemantic.spvasm @@ -0,0 +1,33 @@ +; REQUIRES: spirv-as +; RUN: spirv-as --target-env spv1.4 -o %t.spv %s +; RUN: spirv-val %t.spv +; RUN: llvm-spirv --opaque-pointers -r -o - %t.spv | llvm-dis -opaque-pointers | FileCheck %s + +; SPIR-V +; Version: 1.4 +; Generator: Khronos LLVM/SPIR-V Translator; 14 +; Bound: 40 +; Schema: 0 + OpCapability Addresses + OpCapability Linkage + OpCapability Kernel + OpMemoryModel Physical64 OpenCL + OpEntryPoint Kernel %kernel "test" + ; Note: this is decorating a variable in the function storage class, which + ; is not actually valid according to the SPIR-V spec, but is processed by + ; the SPIR-V LLVM Translator and not rejected by spirv-val. + OpDecorateString %temp UserSemantic "foo" +; CHECK: [[STR:@[0-9_.]+]] = {{.*}}foo +; CHECK: call void @llvm.var.annotation(ptr %{{.*}}, ptr getelementptr inbounds ([4 x i8], ptr [[STR]], i32 0, i32 0), ptr undef, i32 undef, ptr undef) + %uint = OpTypeInt 32 0 + %void = OpTypeVoid + %kernel_sig = OpTypeFunction %void %uint + %ptr_uint = OpTypePointer Function %uint + %kernel = OpFunction %void None %kernel_sig + %a = OpFunctionParameter %uint + %entry = OpLabel + %temp = OpVariable %ptr_uint Function + %add = OpIAdd %uint %a %a + OpStore %temp %add Aligned 4 + OpReturn + OpFunctionEnd diff --git a/test/OpMemberDecorateString_UserSemantic.spvasm b/test/OpMemberDecorateString_UserSemantic.spvasm new file mode 100644 index 0000000000..3156d561a8 --- /dev/null +++ b/test/OpMemberDecorateString_UserSemantic.spvasm @@ -0,0 +1,37 @@ +; REQUIRES: spirv-as +; RUN: spirv-as --target-env spv1.4 -o %t.spv %s +; RUN: spirv-val %t.spv +; RUN: llvm-spirv --opaque-pointers -r -o - %t.spv | llvm-dis -opaque-pointers | FileCheck %s + +; SPIR-V +; Version: 1.4 +; Generator: Khronos LLVM/SPIR-V Translator; 14 +; Bound: 44 +; Schema: 0 + OpCapability Addresses + OpCapability Linkage + OpCapability Kernel + OpCapability Int64 + OpMemoryModel Physical64 OpenCL + OpEntryPoint Kernel %kernel "test" + OpMemberDecorateString %struct 0 UserSemantic "foo" +; CHECK: [[STR:@[0-9_.]+]] = {{.*}}foo +; Note: this is checking for an annotation on an instantiation of the structure, +; which is different than an annotation on the structure type. +; CHECK: call ptr @llvm.ptr.annotation.p0(ptr %{{.*}}, ptr getelementptr inbounds ([4 x i8], ptr [[STR]], i32 0, i32 0), ptr undef, i32 undef, ptr undef) + %uint = OpTypeInt 32 0 + %uint_0 = OpConstant %uint 0 + %void = OpTypeVoid + %kernel_sig = OpTypeFunction %void %uint + %struct = OpTypeStruct %uint + %ptr_struct = OpTypePointer Function %struct + %ptr_uint = OpTypePointer Function %uint + %kernel = OpFunction %void None %kernel_sig + %a = OpFunctionParameter %uint + %entry = OpLabel + %s = OpVariable %ptr_struct Function + %add = OpIAdd %uint %a %a + %x = OpInBoundsPtrAccessChain %ptr_uint %s %uint_0 %uint_0 + OpStore %x %add Aligned 4 + OpReturn + OpFunctionEnd