From 7b0a6a3ee5fff67cb7ed736e2cc6e01c2de33a67 Mon Sep 17 00:00:00 2001 From: "Maksimova, Viktoria" Date: Mon, 23 Jan 2023 03:29:02 -0800 Subject: [PATCH 1/2] [Backport to 8] Support SPV_EXT_relaxed_printf_string_address_space extension This backport is a squash of #1364, #1749, #1818 The extension was added in https://github.com/KhronosGroup/SPIRV-Registry/pull/148 --- include/LLVMSPIRVExtensions.inc | 1 + lib/SPIRV/SPIRVWriter.cpp | 22 ++++- .../non-constant-printf.ll | 86 +++++++++++++++++++ 3 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 test/transcoding/SPV_EXT_relaxed_printf_string_address_space/non-constant-printf.ll diff --git a/include/LLVMSPIRVExtensions.inc b/include/LLVMSPIRVExtensions.inc index 3d5b4ffec7..66b8e4d25b 100644 --- a/include/LLVMSPIRVExtensions.inc +++ b/include/LLVMSPIRVExtensions.inc @@ -16,3 +16,4 @@ EXT(SPV_INTEL_optnone) EXT(SPV_INTEL_masked_gather_scatter) EXT(SPV_INTEL_bfloat16_conversion) EXT(SPV_INTEL_tensor_float32_conversion) +EXT(SPV_EXT_relaxed_printf_string_address_space) diff --git a/lib/SPIRV/SPIRVWriter.cpp b/lib/SPIRV/SPIRVWriter.cpp index 7be326421b..c998e217f0 100644 --- a/lib/SPIRV/SPIRVWriter.cpp +++ b/lib/SPIRV/SPIRVWriter.cpp @@ -1770,7 +1770,26 @@ SPIRVValue *LLVMToSPIRV::transCallInst(CallInst *CI, SPIRVBasicBlock *BB) { SmallVector Dec; if (isBuiltinTransToExtInst(CI->getCalledFunction(), &ExtSetKind, &ExtOp, - &Dec)) + &Dec)) { + if (DemangledName.find("__spirv_ocl_printf") != StringRef::npos) { + auto *FormatStrPtr = cast(CI->getArgOperand(0)->getType()); + if (FormatStrPtr->getAddressSpace() != + SPIR::TypeAttributeEnum::ATTR_CONST) { + if (!BM->isAllowedToUseExtension( + ExtensionID::SPV_EXT_relaxed_printf_string_address_space)) { + getErrorLog().checkError( + false, SPIRVEC_RequiresExtension, + toString(CI) + + "SPV_EXT_relaxed_printf_string_address_space extension " + "should be allowed to translate this module, because this " + "LLVM module contains the printf function with format " + "string, whose address space is not equal to 2 (constant)."); + } + BM->addExtension( + ExtensionID::SPV_EXT_relaxed_printf_string_address_space); + } + } + return addDecorations( BM->addExtInst( transType(CI->getType()), BM->getExtInstSetId(ExtSetKind), ExtOp, @@ -1778,6 +1797,7 @@ SPIRVValue *LLVMToSPIRV::transCallInst(CallInst *CI, SPIRVBasicBlock *BB) { SPIRVEntry::createUnique(ExtSetKind, ExtOp).get()), BB), Dec); + } Function *Callee = CI->getCalledFunction(); if (!Callee || Callee->isDeclaration()) { diff --git a/test/transcoding/SPV_EXT_relaxed_printf_string_address_space/non-constant-printf.ll b/test/transcoding/SPV_EXT_relaxed_printf_string_address_space/non-constant-printf.ll new file mode 100644 index 0000000000..d5005a5b0e --- /dev/null +++ b/test/transcoding/SPV_EXT_relaxed_printf_string_address_space/non-constant-printf.ll @@ -0,0 +1,86 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: not llvm-spirv %t.bc -o %t.spv 2>&1 | FileCheck %s --check-prefix=CHECK-WO-EXT + +; RUN: llvm-spirv -spirv-text %t.bc -o %t.spt --spirv-ext=+SPV_EXT_relaxed_printf_string_address_space +; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV + +; RUN: llvm-spirv -to-binary %t.spt -o %t.spv +; RUN: llvm-spirv -r %t.spv -o %t.rev.bc +; RUN: llvm-dis %t.rev.bc -o %t.rev.ll +; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM + +; CHECK-WO-EXT: RequiresExtension: Feature requires the following SPIR-V extension: +; CHECK-WO-EXT: SPV_EXT_relaxed_printf_string_address_space extension should be allowed to translate this module, because this LLVM module contains the printf function with format string, whose address space is not equal to 2 (constant). + +; CHECK-SPIRV: Extension "SPV_EXT_relaxed_printf_string_address_space" +; CHECK-SPIRV: ExtInstImport [[#ExtInstSetId:]] "OpenCL.std" +; CHECK-SPIRV: TypeInt [[#TypeInt8Id:]] 8 0 +; CHECK-SPIRV: TypeInt [[#TypeInt32Id:]] 32 0 +; CHECK-SPIRV: TypePointer [[#FunctionStorClassPtrTy:]] 7 [[#TypeInt8Id]] +; CHECK-SPIRV: TypePointer [[#WGStorClassPtrTy:]] 5 [[#TypeInt8Id]] +; CHECK-SPIRV: TypePointer [[#CrossWFStorClassPtrTy:]] 4 [[#TypeInt8Id]] +; CHECK-SPIRV: TypePointer [[#GenericStorCalssPtrTy:]] 8 [[#TypeInt8Id]] +; CHECK-SPIRV: InBoundsPtrAccessChain [[#FunctionStorClassPtrTy]] [[#GEP1:]] +; CHECK-SPIRV: ExtInst [[#TypeInt32Id]] {{[0-9]+}} [[#ExtInstSetId:]] printf [[#GEP1]] +; CHECK-SPIRV: InBoundsPtrAccessChain [[#WGStorClassPtrTy]] [[#GEP2:]] +; CHECK-SPIRV: ExtInst [[#TypeInt32Id]] {{[0-9]+}} [[#ExtInstSetId:]] printf [[#GEP2]] +; CHECK-SPIRV: InBoundsPtrAccessChain [[#CrossWFStorClassPtrTy:]] [[#GEP3:]] +; CHECK-SPIRV: ExtInst [[#TypeInt32Id]] {{[0-9]+}} [[#ExtInstSetId:]] printf [[#GEP3]] +; CHECK-SPIRV: InBoundsPtrAccessChain [[#GenericStorCalssPtrTy:]] [[#GEP4:]] +; CHECK-SPIRV: ExtInst [[#TypeInt32Id]] {{[0-9]+}} [[#ExtInstSetId:]] printf [[#GEP4]] + +; CHECK-LLVM: call spir_func i32 @_Z18__spirv_ocl_printfPc(i8* {{.*}} +; CHECK-LLVM: call spir_func i32 @_Z18__spirv_ocl_printfPU3AS1c(i8 addrspace(1)* {{.*}} +; CHECK-LLVM: call spir_func i32 @_Z18__spirv_ocl_printfPU3AS3c(i8 addrspace(3)* {{.*}} +; CHECK-LLVM: call spir_func i32 @_Z18__spirv_ocl_printfPU3AS4c(i8 addrspace(4)* {{.*}} + +; ModuleID = 'non-constant-printf' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024" +target triple = "spir-unknown-unknown" + +@0 = internal unnamed_addr addrspace(0) constant [6 x i8] c"Test\0A\00", align 1 +@1 = internal unnamed_addr addrspace(1) constant [6 x i8] c"Test\0A\00", align 1 +@2 = internal unnamed_addr addrspace(3) constant [6 x i8] c"Test\0A\00", align 1 +@3 = internal unnamed_addr addrspace(4) constant [6 x i8] c"Test\0A\00", align 1 + +; Function Attrs: nounwind +define spir_kernel void @test() #0 !kernel_arg_addr_space !3 !kernel_arg_access_qual !3 !kernel_arg_type !3 !kernel_arg_type_qual !3 !kernel_arg_base_type !3 { + %1 = getelementptr inbounds [6 x i8], [6 x i8]* @0, i32 0, i32 0 + %2 = call spir_func i32 @_Z18__spirv_ocl_printfPc(i8* %1) #0 + %3 = getelementptr inbounds [6 x i8], [6 x i8] addrspace(1)* @1, i32 0, i32 0 + %4 = call spir_func i32 @_Z18__spirv_ocl_printfPU3AS1c(i8 addrspace(1)* %3) #0 + %5 = getelementptr inbounds [6 x i8], [6 x i8] addrspace(3)* @2, i32 0, i32 0 + %6 = call spir_func i32 @_Z18__spirv_ocl_printfPU3AS3c(i8 addrspace(3)* %5) #0 + %7 = getelementptr inbounds [6 x i8], [6 x i8] addrspace(4)* @3, i32 0, i32 0 + %8 = call spir_func i32 @_Z18__spirv_ocl_printfPU3AS4c(i8 addrspace(4)* %7) #0 + ret void +} + +; Function Attrs: nounwind +declare spir_func i32 @_Z18__spirv_ocl_printfPc(i8*) #0 + +; Function Attrs: nounwind +declare spir_func i32 @_Z18__spirv_ocl_printfPU3AS1c(i8 addrspace(1)*) #0 + +; Function Attrs: nounwind +declare spir_func i32 @_Z18__spirv_ocl_printfPU3AS3c(i8 addrspace(3)*) #0 + +; Function Attrs: nounwind +declare spir_func i32 @_Z18__spirv_ocl_printfPU3AS4c(i8 addrspace(4)*) #0 + +attributes #0 = { nounwind } + +!spirv.MemoryModel = !{!0} +!opencl.enable.FP_CONTRACT = !{} +!spirv.Source = !{!1} +!opencl.spir.version = !{!2} +!opencl.ocl.version = !{!2} +!opencl.used.extensions = !{!3} +!opencl.used.optional.core.features = !{!3} +!spirv.Generator = !{!4} + +!0 = !{i32 1, i32 2} +!1 = !{i32 3, i32 200000} +!2 = !{i32 2, i32 0} +!3 = !{} +!4 = !{i16 7, i16 0} From e4ca5bbeb104bb56c5489d68afaca669d5b5163f Mon Sep 17 00:00:00 2001 From: "Maksimova, Viktoria" Date: Wed, 25 Jan 2023 05:29:30 -0800 Subject: [PATCH 2/2] Fix test --- .../non-constant-printf.ll | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/transcoding/SPV_EXT_relaxed_printf_string_address_space/non-constant-printf.ll b/test/transcoding/SPV_EXT_relaxed_printf_string_address_space/non-constant-printf.ll index d5005a5b0e..735433ec8c 100644 --- a/test/transcoding/SPV_EXT_relaxed_printf_string_address_space/non-constant-printf.ll +++ b/test/transcoding/SPV_EXT_relaxed_printf_string_address_space/non-constant-printf.ll @@ -21,13 +21,13 @@ ; CHECK-SPIRV: TypePointer [[#CrossWFStorClassPtrTy:]] 4 [[#TypeInt8Id]] ; CHECK-SPIRV: TypePointer [[#GenericStorCalssPtrTy:]] 8 [[#TypeInt8Id]] ; CHECK-SPIRV: InBoundsPtrAccessChain [[#FunctionStorClassPtrTy]] [[#GEP1:]] -; CHECK-SPIRV: ExtInst [[#TypeInt32Id]] {{[0-9]+}} [[#ExtInstSetId:]] printf [[#GEP1]] +; CHECK-SPIRV: ExtInst [[#TypeInt32Id]] {{[0-9]+}} [[#ExtInstSetId1:]] printf [[#GEP1]] ; CHECK-SPIRV: InBoundsPtrAccessChain [[#WGStorClassPtrTy]] [[#GEP2:]] -; CHECK-SPIRV: ExtInst [[#TypeInt32Id]] {{[0-9]+}} [[#ExtInstSetId:]] printf [[#GEP2]] -; CHECK-SPIRV: InBoundsPtrAccessChain [[#CrossWFStorClassPtrTy:]] [[#GEP3:]] -; CHECK-SPIRV: ExtInst [[#TypeInt32Id]] {{[0-9]+}} [[#ExtInstSetId:]] printf [[#GEP3]] -; CHECK-SPIRV: InBoundsPtrAccessChain [[#GenericStorCalssPtrTy:]] [[#GEP4:]] -; CHECK-SPIRV: ExtInst [[#TypeInt32Id]] {{[0-9]+}} [[#ExtInstSetId:]] printf [[#GEP4]] +; CHECK-SPIRV: ExtInst [[#TypeInt32Id]] {{[0-9]+}} [[#ExtInstSetId2:]] printf [[#GEP2]] +; CHECK-SPIRV: InBoundsPtrAccessChain [[#CrossWFStorClassPtrTy]] [[#GEP3:]] +; CHECK-SPIRV: ExtInst [[#TypeInt32Id]] {{[0-9]+}} [[#ExtInstSetId3:]] printf [[#GEP3]] +; CHECK-SPIRV: InBoundsPtrAccessChain [[#GenericStorCalssPtrTy]] [[#GEP4:]] +; CHECK-SPIRV: ExtInst [[#TypeInt32Id]] {{[0-9]+}} [[#ExtInstSetId4:]] printf [[#GEP4]] ; CHECK-LLVM: call spir_func i32 @_Z18__spirv_ocl_printfPc(i8* {{.*}} ; CHECK-LLVM: call spir_func i32 @_Z18__spirv_ocl_printfPU3AS1c(i8 addrspace(1)* {{.*}}