From 3564ad53112a42bd0f8d6cec0d887d36c34520a7 Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Fri, 9 Jun 2023 12:16:57 -0700 Subject: [PATCH 01/13] Add support for SPV_INTEL_fp_max_error extension Signed-off-by: Arvind Sudarsanam --- include/LLVMSPIRVExtensions.inc | 1 + lib/SPIRV/SPIRVWriter.cpp | 165 +++++++++++++++++- lib/SPIRV/libSPIRV/SPIRVDecorate.h | 2 + lib/SPIRV/libSPIRV/SPIRVEnum.h | 2 + lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h | 2 + .../SPV_INTEL_fp_max_error/IntelFPMaxError.ll | 37 ++++ 6 files changed, 206 insertions(+), 3 deletions(-) create mode 100644 test/extensions/INTEL/SPV_INTEL_fp_max_error/IntelFPMaxError.ll diff --git a/include/LLVMSPIRVExtensions.inc b/include/LLVMSPIRVExtensions.inc index b560bb4048..805b9fb6c5 100644 --- a/include/LLVMSPIRVExtensions.inc +++ b/include/LLVMSPIRVExtensions.inc @@ -60,3 +60,4 @@ EXT(SPV_INTEL_tensor_float32_rounding) EXT(SPV_EXT_relaxed_printf_string_address_space) EXT(SPV_INTEL_fpga_argument_interfaces) EXT(SPV_INTEL_fpga_latency_control) +EXT(SPV_INTEL_fp_max_error) diff --git a/lib/SPIRV/SPIRVWriter.cpp b/lib/SPIRV/SPIRVWriter.cpp index 8bf3bad681..feb0bdf310 100644 --- a/lib/SPIRV/SPIRVWriter.cpp +++ b/lib/SPIRV/SPIRVWriter.cpp @@ -161,6 +161,15 @@ static void translateSEVDecoration(Attribute Sev, SPIRVValue *Val) { Val->addDecorate(DecorationSingleElementVectorINTEL); } +static SPIRVWord convertFloatToSPPIRVWord(float f) { + union { + float f; + SPIRVWord spir; + } FPMaxError; + FPMaxError.f = f; + return FPMaxError.spir; +} + LLVMToSPIRVBase::LLVMToSPIRVBase(SPIRVModule *SMod) : BuiltinCallHelper(ManglingRules::None), M(nullptr), Ctx(nullptr), BM(SMod), SrcLang(0), SrcLangVer(0) { @@ -3521,6 +3530,26 @@ bool LLVMToSPIRVBase::isKnownIntrinsic(Intrinsic::ID Id) { } } +// Add decoration if needed +SPIRVInstruction *addFPBuiltinDecoration(SPIRVModule *BM, IntrinsicInst *II, + SPIRVInstruction *I) { + const bool AllowFPMaxError = + BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_fp_max_error); + bool IsLLVMFPBuiltin = + II->getCalledFunction()->getName().startswith("llvm.fpbuiltin"); + // Add a new decoration for llvm.builtin intrinsics, if needed + if (IsLLVMFPBuiltin && AllowFPMaxError) + if (II->getAttributes().hasFnAttr("fpbuiltin-max-error")) { + double f = 0.0; + II->getAttributes().getFnAttr("fpbuiltin-max-error") + .getValueAsString().getAsDouble(f); + I->addDecorate(DecorationFPMaxErrorDecorationINTEL, + convertFloatToSPPIRVWord(f)); + } + return I; +} + + // Performs mapping of LLVM IR rounding mode to SPIR-V rounding mode // Value *V is metadata argument of // llvm.experimental.constrained.* intrinsics @@ -3548,27 +3577,63 @@ static SPIRVWord getBuiltinIdForIntrinsic(Intrinsic::ID IID) { // and assume that the operations have no side effects (FP status flags // aren't maintained), so the OpenCL builtin behavior should be // acceptable. + case Intrinsic::fpbuiltin_acos: + return OpenCLLIB::Acos; + case Intrinsic::fpbuiltin_acosh: + return OpenCLLIB::Acosh; + case Intrinsic::fpbuiltin_asin: + return OpenCLLIB::Asin; + case Intrinsic::fpbuiltin_asinh: + return OpenCLLIB::Asinh; + case Intrinsic::fpbuiltin_atan: + return OpenCLLIB::Atan; + case Intrinsic::fpbuiltin_atan2: + return OpenCLLIB::Atan2; + case Intrinsic::fpbuiltin_atanh: + return OpenCLLIB::Atanh; case Intrinsic::ceil: return OpenCLLIB::Ceil; case Intrinsic::copysign: return OpenCLLIB::Copysign; case Intrinsic::cos: + case Intrinsic::fpbuiltin_cos: return OpenCLLIB::Cos; + case Intrinsic::fpbuiltin_cosh: + return OpenCLLIB::Cosh; + case Intrinsic::fpbuiltin_erf: + return OpenCLLIB::Erf; + case Intrinsic::fpbuiltin_erfc: + return OpenCLLIB::Erfc; case Intrinsic::exp: + case Intrinsic::fpbuiltin_exp: return OpenCLLIB::Exp; case Intrinsic::exp2: + case Intrinsic::fpbuiltin_exp2: return OpenCLLIB::Exp2; + case Intrinsic::fpbuiltin_exp10: + return OpenCLLIB::Exp10; + case Intrinsic::fpbuiltin_expm1: + return OpenCLLIB::Expm1; case Intrinsic::fabs: return OpenCLLIB::Fabs; case Intrinsic::floor: return OpenCLLIB::Floor; case Intrinsic::fma: return OpenCLLIB::Fma; + case Intrinsic::fpbuiltin_hypot: + return OpenCLLIB::Hypot; + case Intrinsic::fpbuiltin_ldexp: + return OpenCLLIB::Ldexp; case Intrinsic::log: + case Intrinsic::fpbuiltin_log: return OpenCLLIB::Log; case Intrinsic::log10: + case Intrinsic::fpbuiltin_log10: return OpenCLLIB::Log10; + case Intrinsic::fpbuiltin_log1p: + return OpenCLLIB::Log1p; case Intrinsic::log2: + case Intrinsic::fpbuiltin_log2: return OpenCLLIB::Log2; case Intrinsic::maximum: return OpenCLLIB::Fmax; @@ -3581,6 +3646,7 @@ static SPIRVWord getBuiltinIdForIntrinsic(Intrinsic::ID IID) { case Intrinsic::nearbyint: return OpenCLLIB::Rint; case Intrinsic::pow: + case Intrinsic::fpbuiltin_pow: return OpenCLLIB::Pow; case Intrinsic::powi: return OpenCLLIB::Pown; @@ -3590,10 +3656,22 @@ static SPIRVWord getBuiltinIdForIntrinsic(Intrinsic::ID IID) { return OpenCLLIB::Round; case Intrinsic::roundeven: return OpenCLLIB::Rint; + case Intrinsic::fpbuiltin_rsqrt: + return OpenCLLIB::Rsqrt; case Intrinsic::sin: + case Intrinsic::fpbuiltin_sin: return OpenCLLIB::Sin; + case Intrinsic::fpbuiltin_sincos: + return OpenCLLIB::Sincos; + case Intrinsic::fpbuiltin_sinh: + return OpenCLLIB::Sinh; case Intrinsic::sqrt: + case Intrinsic::fpbuiltin_sqrt: return OpenCLLIB::Sqrt; + case Intrinsic::fpbuiltin_tan: + return OpenCLLIB::Tan; + case Intrinsic::fpbuiltin_tanh: + return OpenCLLIB::Tanh; case Intrinsic::trunc: return OpenCLLIB::Trunc; default: @@ -4470,14 +4548,95 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II, return Result; } + // add/sub/mul/div/rem fpbuiltin intrinsics + case Intrinsic::fpbuiltin_fadd: { + auto BI = BM->addBinaryInst(OpFAdd, transType(II->getType()), + transValue(II->getArgOperand(0), BB), + transValue(II->getArgOperand(1), BB), BB); + return addFPBuiltinDecoration(BM, II, BI); + } + case Intrinsic::fpbuiltin_fsub: { + auto BI = BM->addBinaryInst(OpFSub, transType(II->getType()), + transValue(II->getArgOperand(0), BB), + transValue(II->getArgOperand(1), BB), BB); + return addFPBuiltinDecoration(BM, II, BI); + } + case Intrinsic::fpbuiltin_fmul: { + auto BI = BM->addBinaryInst(OpFMul, transType(II->getType()), + transValue(II->getArgOperand(0), BB), + transValue(II->getArgOperand(1), BB), BB); + return addFPBuiltinDecoration(BM, II, BI); + } + case Intrinsic::fpbuiltin_fdiv: { + auto BI = BM->addBinaryInst(OpFDiv, transType(II->getType()), + transValue(II->getArgOperand(0), BB), + transValue(II->getArgOperand(1), BB), BB); + return addFPBuiltinDecoration(BM, II, BI); + } + case Intrinsic::fpbuiltin_frem: { + auto BI = BM->addBinaryInst(OpFRem, transType(II->getType()), + transValue(II->getArgOperand(0), BB), + transValue(II->getArgOperand(1), BB), BB); + return addFPBuiltinDecoration(BM, II, BI); + } + + // Unary fpbuiltin intrinsics + case::fpbuiltin_sin: + case::fpbuiltin_cos: + case::fpbuiltin_tan: + case::fpbuiltin_sinh: + case::fpbuiltin_cosh: + case::fpbuiltin_tanh: + case::fpbuiltin_asin: + case::fpbuiltin_acos: + case::fpbuiltin_atan: + case::fpbuiltin_atan2: + case::fpbuiltin_asinh: + case::fpbuiltin_acosh: + case::fpbuiltin_atanh: + case::fpbuiltin_exp: + case::fpbuiltin_exp2: + case::fpbuiltin_exp10: + case::fpbuiltin_expm1: + case::fpbuiltin_log: + case::fpbuiltin_log2: + case::fpbuiltin_log10: + case::fpbuiltin_log1p: + case::fpbuiltin_sqrt: + case::fpbuiltin_rsqrt: + case::fpbuiltin_erf: + case::fpbuiltin_erfc: { + if (!checkTypeForSPIRVExtendedInstLowering(II, BM)) + break; + SPIRVWord ExtOp = getBuiltinIdForIntrinsic(IID); + SPIRVType *STy = transType(II->getType()); + std::vector Ops(1, transValue(II->getArgOperand(0), BB)); + auto BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, Ops, + BB); + return addFPBuiltinDecoration(BM, II, BI); + } + default: - if (BM->isUnknownIntrinsicAllowed(II)) - return BM->addCallInst( + if (BM->isUnknownIntrinsicAllowed(II)) { + auto BVar = BM->addCallInst( transFunctionDecl(II->getCalledFunction()), transArguments(II, BB, SPIRVEntry::createUnique(OpFunctionCall).get()), BB); - else + const bool AllowFPMaxError = + BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_fp_max_error); + bool IsLLVMFPBuiltin = + II->getCalledFunction()->getName().startswith("llvm.fpbuiltin"); + // Add a new decoration for llvm.builtin intrinsics, if needed + if (IsLLVMFPBuiltin && AllowFPMaxError) + if (II->getAttributes().hasFnAttr("fpbuiltin-max-error")) { + double f = 0.0; + II->getAttributes().getFnAttr("fpbuiltin-max-error") + .getValueAsString().getAsDouble(f); + BVar->addDecorate(DecorationFPMaxErrorDecorationINTEL, convertFloatToSPPIRVWord(f)); + } + return BVar; + } else // Other LLVM intrinsics shouldn't get to SPIRV, because they // can't be represented in SPIRV or aren't implemented yet. BM->SPIRVCK( diff --git a/lib/SPIRV/libSPIRV/SPIRVDecorate.h b/lib/SPIRV/libSPIRV/SPIRVDecorate.h index 19d254d943..685a27532e 100644 --- a/lib/SPIRV/libSPIRV/SPIRVDecorate.h +++ b/lib/SPIRV/libSPIRV/SPIRVDecorate.h @@ -201,6 +201,8 @@ class SPIRVDecorate : public SPIRVDecorateGeneric { case DecorationLatencyControlLabelINTEL: case DecorationLatencyControlConstraintINTEL: return ExtensionID::SPV_INTEL_fpga_latency_control; + case DecorationFPMaxErrorDecorationINTEL: + return ExtensionID::SPV_INTEL_fp_max_error; default: return {}; } diff --git a/lib/SPIRV/libSPIRV/SPIRVEnum.h b/lib/SPIRV/libSPIRV/SPIRVEnum.h index e9537da1ef..e6fe33eb8a 100644 --- a/lib/SPIRV/libSPIRV/SPIRVEnum.h +++ b/lib/SPIRV/libSPIRV/SPIRVEnum.h @@ -493,6 +493,8 @@ template <> inline void SPIRVMap::init() { {CapabilityFPGALatencyControlINTEL}); ADD_VEC_INIT(DecorationLatencyControlConstraintINTEL, {CapabilityFPGALatencyControlINTEL}); + ADD_VEC_INIT(DecorationFPMaxErrorDecorationINTEL, + {CapabilityFPMaxErrorINTEL}); } template <> inline void SPIRVMap::init() { diff --git a/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h b/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h index 56cadaa265..b91a01434c 100644 --- a/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h +++ b/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h @@ -198,6 +198,7 @@ template <> inline void SPIRVMap::init() { add(DecorationStableKernelArgumentINTEL, "StableKernelArgumentINTEL"); add(DecorationLatencyControlLabelINTEL, "LatencyControlLabelINTEL"); add(DecorationLatencyControlConstraintINTEL, "LatencyControlConstraintINTEL"); + add(DecorationFPMaxErrorDecorationINTEL, "FPMaxErrorDecorationINTEL"); // From spirv_internal.hpp add(internal::DecorationCallableFunctionINTEL, "CallableFunctionINTEL"); @@ -620,6 +621,7 @@ template <> inline void SPIRVMap::init() { add(CapabilityMax, "Max"); add(CapabilityFPGAArgumentInterfacesINTEL, "FPGAArgumentInterfacesINTEL"); add(CapabilityFPGALatencyControlINTEL, "FPGALatencyControlINTEL"); + add(CapabilityFPMaxErrorINTEL, "FPMaxErrorINTEL"); // From spirv_internal.hpp add(internal::CapabilityFastCompositeINTEL, "FastCompositeINTEL"); add(internal::CapabilityOptNoneINTEL, "OptNoneINTEL"); diff --git a/test/extensions/INTEL/SPV_INTEL_fp_max_error/IntelFPMaxError.ll b/test/extensions/INTEL/SPV_INTEL_fp_max_error/IntelFPMaxError.ll new file mode 100644 index 0000000000..05bcacd2dd --- /dev/null +++ b/test/extensions/INTEL/SPV_INTEL_fp_max_error/IntelFPMaxError.ll @@ -0,0 +1,37 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_fp_max_error --spirv-allow-unknown-intrinsics=llvm.fpbuiltin -o %t.spv +; RUN: llvm-spirv %t.spv -to-text -o %t.spt +; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV + +; RUN: llvm-spirv -r -emit-opaque-pointers %t.spv -o %t.rev.bc +; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM + +; CHECK-SPIRV: Capability FPMaxErrorINTEL +; CHECK-SPIRV: Extension "SPV_INTEL_fp_max_error" + +target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" +target triple = "spir64-unknown-unknown" + +define void @test_scalar_1_0(half %h, float %f, double %d) { +entry: +; NO-CHECK-LLVM: %t1 = call float @llvm.fpbuiltin.sin.f32(float %f) #[[#ATTR_ID:]] + %t1 = call float @llvm.fpbuiltin.sin.f32(float %f) #1 +; NO-CHECK-LLVM: %t1 = call float @llvm.fpbuiltin.cos.f32(float %f) #[[#ATTR_ID:]] + %t2 = call float @llvm.fpbuiltin.cos.f32(float %f) #1 + ret void +} + +; Function Attrs: nounwind readnone +define spir_func i1 @TestIsConstantF32_True() local_unnamed_addr #0 { +entry: + %0 = tail call i1 @Isconstant.f32(float 0.5) + ret i1 %0 +} + +declare float @llvm.fpbuiltin.sin.f32(float) +declare float @llvm.fpbuiltin.cos.f32(float) +declare i1 @Isconstant.f32(float) + +attributes #1 = { "fpbuiltin-max-error"="0.5" } + + From 132c5313147b56ef0dc1a069c1de9c2a15a190e5 Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Sun, 18 Jun 2023 17:27:40 -0700 Subject: [PATCH 02/13] Test changes Signed-off-by: Arvind Sudarsanam --- lib/SPIRV/SPIRVWriter.cpp | 1 - .../SPV_INTEL_fp_max_error/IntelFPMaxError.ll | 145 ++++++++++++++++++ 2 files changed, 145 insertions(+), 1 deletion(-) diff --git a/lib/SPIRV/SPIRVWriter.cpp b/lib/SPIRV/SPIRVWriter.cpp index 93cb656c7b..8133c38217 100644 --- a/lib/SPIRV/SPIRVWriter.cpp +++ b/lib/SPIRV/SPIRVWriter.cpp @@ -4524,7 +4524,6 @@ LLVMToSPIRVBase::getFPBuiltinType(IntrinsicInst *II, StringRef &OpName) { return FPBuiltinType::UNKNOWN; Name.consume_front("llvm.fpbuiltin."); OpName = Name.split('.').first; - llvm::errs() << "ARV: OpName = " << OpName << "\n"; FPBuiltinType Type = StringSwitch(OpName) .Cases("fadd", "fsub", "fmul", "fdiv", "frem", FPBuiltinType::REGULAR_MATH) .Cases("sin", "cos", "tan", FPBuiltinType::EXT_1OPS) diff --git a/test/extensions/INTEL/SPV_INTEL_fp_max_error/IntelFPMaxError.ll b/test/extensions/INTEL/SPV_INTEL_fp_max_error/IntelFPMaxError.ll index 2f1fa2b48b..4a7cf5d7a9 100644 --- a/test/extensions/INTEL/SPV_INTEL_fp_max_error/IntelFPMaxError.ll +++ b/test/extensions/INTEL/SPV_INTEL_fp_max_error/IntelFPMaxError.ll @@ -8,54 +8,194 @@ ; CHECK-SPIRV: Capability FPMaxErrorINTEL ; CHECK-SPIRV: Extension "SPV_INTEL_fp_max_error" +; CHECK-SPIRV: ExtInstImport [[#OCLEXTID:]] "OpenCL.std" + +; CHECK-SPIRV: Name [[#T1:]] "t1" +; CHECK-SPIRV: Name [[#T2:]] "t2" +; CHECK-SPIRV: Name [[#T3:]] "t3" +; CHECK-SPIRV: Name [[#T4:]] "t4" +; CHECK-SPIRV: Name [[#T5:]] "t5" +; CHECK-SPIRV: Name [[#T6:]] "t6" +; CHECK-SPIRV: Name [[#T7:]] "t7" +; CHECK-SPIRV: Name [[#T8:]] "t8" +; CHECK-SPIRV: Name [[#T9:]] "t9" +; CHECK-SPIRV: Name [[#T10:]] "t10" +; CHECK-SPIRV: Name [[#T11:]] "t11" +; CHECK-SPIRV: Name [[#T12:]] "t12" +; CHECK-SPIRV: Name [[#T13:]] "t13" +; CHECK-SPIRV: Name [[#T14:]] "t14" +; CHECK-SPIRV: Name [[#T15:]] "t15" +; CHECK-SPIRV: Name [[#T16:]] "t16" +; CHECK-SPIRV: Name [[#T17:]] "t17" +; CHECK-SPIRV: Name [[#T18:]] "t18" +; CHECK-SPIRV: Name [[#T19:]] "t19" +; CHECK-SPIRV: Name [[#T20:]] "t20" +; CHECK-SPIRV: Name [[#T21:]] "t21" +; CHECK-SPIRV: Name [[#T22:]] "t22" +; CHECK-SPIRV: Name [[#T23:]] "t23" +; CHECK-SPIRV: Name [[#T24:]] "t24" +; CHECK-SPIRV: Name [[#T25:]] "t25" +; CHECK-SPIRV: Name [[#T26:]] "t26" +; CHECK-SPIRV: Name [[#T27:]] "t27" +; CHECK-SPIRV: Name [[#T28:]] "t28" +; CHECK-SPIRV: Name [[#T29:]] "t29" +; CHECK-SPIRV: Name [[#T30:]] "t30" +; CHECK-SPIRV: Name [[#T31:]] "t31" +; CHECK-SPIRV: Name [[#T32:]] "t32" +; CHECK-SPIRV: Name [[#T33:]] "t33" +; CHECK-SPIRV: Name [[#T34:]] "t34" + +; CHECK-SPIRV: Decorate [[#T3]] FPMaxErrorDecorationINTEL 1056964608 +; CHECK-SPIRV: Decorate [[#T4]] FPMaxErrorDecorationINTEL 1065353216 +; CHECK-SPIRV: Decorate [[#T5]] FPMaxErrorDecorationINTEL 1065353216 +; CHECK-SPIRV: Decorate [[#T6]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T7]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T8]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T9]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T10]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T11]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T12]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T13]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T14]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T15]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T16]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T17]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T18]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T19]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T20]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T21]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T22]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T23]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T24]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T25]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T26]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T27]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T28]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T29]] FPMaxErrorDecorationINTEL 1075838976 +; CHECK-SPIRV: Decorate [[#T30]] FPMaxErrorDecorationINTEL 1082130432 +; CHECK-SPIRV: Decorate [[#T31]] FPMaxErrorDecorationINTEL 1082130432 +; CHECK-SPIRV: Decorate [[#T32]] FPMaxErrorDecorationINTEL 1082130432 +; CHECK-SPIRV: Decorate [[#T33]] FPMaxErrorDecorationINTEL 1082130432 +; CHECK-SPIRV: Decorate [[#T34]] FPMaxErrorDecorationINTEL 1166016512 + +; CHECK-SPIRV: 3 TypeFloat [[#FTYPE:]] 32 + +; CHECK-SPIRV: FAdd [[#FTYPE]] [[#T1]] +; CHECK-SPIRV: FSub [[#FTYPE]] [[#T2]] +; CHECK-SPIRV: FMul [[#FTYPE]] [[#T3]] +; CHECK-SPIRV: FDiv [[#FTYPE]] [[#T4]] +; CHECK-SPIRV: FRem [[#FTYPE]] [[#T5]] +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T6]] [[#OCLEXTID]] sin +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T7]] [[#OCLEXTID]] cos +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T8]] [[#OCLEXTID]] tan +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T9]] [[#OCLEXTID]] sinh +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T10]] [[#OCLEXTID]] cosh +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T11]] [[#OCLEXTID]] tanh +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T12]] [[#OCLEXTID]] asin +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T13]] [[#OCLEXTID]] acos +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T14]] [[#OCLEXTID]] atan +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T15]] [[#OCLEXTID]] asinh +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T16]] [[#OCLEXTID]] acosh +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T17]] [[#OCLEXTID]] atanh +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T18]] [[#OCLEXTID]] exp +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T19]] [[#OCLEXTID]] exp2 +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T20]] [[#OCLEXTID]] exp10 +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T21]] [[#OCLEXTID]] expm1 +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T22]] [[#OCLEXTID]] log +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T23]] [[#OCLEXTID]] log2 +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T24]] [[#OCLEXTID]] log10 +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T25]] [[#OCLEXTID]] log1p +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T26]] [[#OCLEXTID]] sqrt +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T27]] [[#OCLEXTID]] rsqrt +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T28]] [[#OCLEXTID]] erf +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T29]] [[#OCLEXTID]] erfc +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T30]] [[#OCLEXTID]] atan2 +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T31]] [[#OCLEXTID]] ldexp +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T32]] [[#OCLEXTID]] pow +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T33]] [[#OCLEXTID]] hypot +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T34]] [[#OCLEXTID]] sincos target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" target triple = "spir64-unknown-unknown" define void @test_fp_max_error_decoration(float %f1, float %f2, float %f3) { entry: +; CHECK-LLVM-NOT: fadd float %f1, %f2, !fpbuiltin-max-error +; CHECK-LLVM-NOT: fsub float %f1, %f2, !fpbuiltin-max-error +; CHECK-LLVM: fmul float %f1, %f2, !fpbuiltin-max-error ![[#ME1:]] +; CHECK-LLVM: fdiv float %f1, %f2, !fpbuiltin-max-error ![[#ME2:]] +; CHECK-LLVM: frem float %f1, %f2, !fpbuiltin-max-error ![[#ME2]] %t1 = call float @llvm.fpbuiltin.fadd.f32(float %f1, float %f2) %t2 = call float @llvm.fpbuiltin.fsub.f32(float %f1, float %f2) %t3 = call float @llvm.fpbuiltin.fmul.f32(float %f1, float %f2) #0 %t4 = call float @llvm.fpbuiltin.fdiv.f32(float %f1, float %f2) #1 %t5 = call float @llvm.fpbuiltin.frem.f32(float %f1, float %f2) #1 +; CHECK-LLVM: call spir_func float @_Z3sinf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3:]] +; CHECK-LLVM: call spir_func float @_Z3cosf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM: call spir_func float @_Z3tanf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] %t6 = call float @llvm.fpbuiltin.sin.f32(float %f1) #2 %t7 = call float @llvm.fpbuiltin.cos.f32(float %f1) #2 %t8 = call float @llvm.fpbuiltin.tan.f32(float %f1) #2 +; CHECK-LLVM: call spir_func float @_Z4sinhf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM: call spir_func float @_Z4coshf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM: call spir_func float @_Z4tanhf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] %t9 = call float @llvm.fpbuiltin.sinh.f32(float %f1) #2 %t10 = call float @llvm.fpbuiltin.cosh.f32(float %f1) #2 %t11 = call float @llvm.fpbuiltin.tanh.f32(float %f1) #2 +; CHECK-LLVM: call spir_func float @_Z4asinf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM: call spir_func float @_Z4acosf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM: call spir_func float @_Z4atanf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] %t12 = call float @llvm.fpbuiltin.asin.f32(float %f1) #2 %t13 = call float @llvm.fpbuiltin.acos.f32(float %f1) #2 %t14 = call float @llvm.fpbuiltin.atan.f32(float %f1) #2 +; CHECK-LLVM:15 = call spir_func float @_Z5asinhf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM:16 = call spir_func float @_Z5acoshf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM:17 = call spir_func float @_Z5atanhf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] %t15 = call float @llvm.fpbuiltin.asinh.f32(float %f1) #2 %t16 = call float @llvm.fpbuiltin.acosh.f32(float %f1) #2 %t17 = call float @llvm.fpbuiltin.atanh.f32(float %f1) #2 +; CHECK-LLVM:18 = call spir_func float @_Z3expf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM:19 = call spir_func float @_Z4exp2f(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM:20 = call spir_func float @_Z5exp10f(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM:21 = call spir_func float @_Z5expm1f(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] %t18 = call float @llvm.fpbuiltin.exp.f32(float %f1) #2 %t19 = call float @llvm.fpbuiltin.exp2.f32(float %f1) #2 %t20 = call float @llvm.fpbuiltin.exp10.f32(float %f1) #2 %t21 = call float @llvm.fpbuiltin.expm1.f32(float %f1) #2 +; CHECK-LLVM: call spir_func float @_Z3logf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM: call spir_func float @_Z4log2f(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM: call spir_func float @_Z5log10f(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM: call spir_func float @_Z5log1pf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] %t22 = call float @llvm.fpbuiltin.log.f32(float %f1) #2 %t23 = call float @llvm.fpbuiltin.log2.f32(float %f1) #2 %t24 = call float @llvm.fpbuiltin.log10.f32(float %f1) #2 %t25 = call float @llvm.fpbuiltin.log1p.f32(float %f1) #2 +; CHECK-LLVM: call spir_func float @_Z4sqrtf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM: call spir_func float @_Z5rsqrtf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM: call spir_func float @_Z3erff(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM: call spir_func float @_Z4erfcf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] %t26 = call float @llvm.fpbuiltin.sqrt.f32(float %f1) #2 %t27 = call float @llvm.fpbuiltin.rsqrt.f32(float %f1) #2 %t28 = call float @llvm.fpbuiltin.erf.f32(float %f1) #2 %t29 = call float @llvm.fpbuiltin.erfc.f32(float %f1) #2 +; CHECK-LLVM: call spir_func float @_Z5atan2ff(float %f1, float %f2) {{.*}} !fpbuiltin-max-error ![[#ME4:]] +; CHECK-LLVM: call spir_func float @_Z5ldexpff(float %f1, float %f2) {{.*}} !fpbuiltin-max-error ![[#ME4]] +; CHECK-LLVM: call spir_func float @_Z3powff(float %f1, float %f2) {{.*}} !fpbuiltin-max-error ![[#ME4]] +; CHECK-LLVM: call spir_func float @_Z5hypotff(float %f1, float %f2) #0, !fpbuiltin-max-error ![[#ME4]] %t30 = call float @llvm.fpbuiltin.atan2.f32(float %f1, float %f2) #3 %t31 = call float @llvm.fpbuiltin.ldexp.f32(float %f1, float %f2) #3 %t32 = call float @llvm.fpbuiltin.pow.f32(float %f1, float %f2) #3 %t33 = call float @llvm.fpbuiltin.hypot.f32(float %f1, float %f2) #3 +; CHECK-LLVM: call spir_func float @_Z6sincosfff(float %f1, float %f2, float %f3) {{.*}} !fpbuiltin-max-error ![[#ME5:]] %t34 = call float @llvm.fpbuiltin.sincos.f32(float %f1, float %f2, float %f3) #4 ret void } @@ -98,6 +238,11 @@ declare float @llvm.fpbuiltin.ldexp.f32(float, float) declare float @llvm.fpbuiltin.sincos.f32(float, float, float) +; CHECK-LLVM: ![[#ME1]] = !{!"0.500000"} +; CHECK-LLVM: ![[#ME2]] = !{!"1.000000"} +; CHECK-LLVM: ![[#ME3]] = !{!"2.500000"} +; CHECK-LLVM: ![[#ME4]] = !{!"4.000000"} +; CHECK-LLVM: ![[#ME5]] = !{!"4096.000000"} attributes #0 = { "fpbuiltin-max-error"="0.5" } attributes #1 = { "fpbuiltin-max-error"="1.0" } attributes #2 = { "fpbuiltin-max-error"="2.5" } From e1d07755001bd3ecaebf47ed079cd1e9bc74dc03 Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Sun, 18 Jun 2023 18:43:48 -0700 Subject: [PATCH 03/13] formatting Signed-off-by: Arvind Sudarsanam --- lib/SPIRV/SPIRVReader.cpp | 8 +- lib/SPIRV/SPIRVWriter.cpp | 197 +++++++++++++++++++------------------- lib/SPIRV/SPIRVWriter.h | 9 +- 3 files changed, 112 insertions(+), 102 deletions(-) diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 849190947f..8ba451bb20 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -3868,11 +3868,13 @@ bool SPIRVToLLVM::transDecoration(SPIRVValue *BV, Value *V) { SPIRVWord ID; if (Instruction *I = dyn_cast(V)) if (BV->hasDecorate(DecorationFPMaxErrorDecorationINTEL, 0, &ID)) { - auto Literals = BV->getDecorationLiterals(DecorationFPMaxErrorDecorationINTEL); + auto Literals = + BV->getDecorationLiterals(DecorationFPMaxErrorDecorationINTEL); assert(Literals.size() == 1 && - "FP Max Error decoration shall have 1 operand"); + "FP Max Error decoration shall have 1 operand"); auto f = convertSPIRVWordToFloat(Literals[0]); - MDNode* N = MDNode::get(*Context, MDString::get(*Context, std::to_string(f))); + MDNode *N = + MDNode::get(*Context, MDString::get(*Context, std::to_string(f))); I->setMetadata("fpbuiltin-max-error", N); return true; } diff --git a/lib/SPIRV/SPIRVWriter.cpp b/lib/SPIRV/SPIRVWriter.cpp index 8133c38217..a61ddfa372 100644 --- a/lib/SPIRV/SPIRVWriter.cpp +++ b/lib/SPIRV/SPIRVWriter.cpp @@ -3541,8 +3541,10 @@ SPIRVInstruction *addFPBuiltinDecoration(SPIRVModule *BM, IntrinsicInst *II, if (IsLLVMFPBuiltin && AllowFPMaxError) if (II->getAttributes().hasFnAttr("fpbuiltin-max-error")) { double f = 0.0; - II->getAttributes().getFnAttr("fpbuiltin-max-error") - .getValueAsString().getAsDouble(f); + II->getAttributes() + .getFnAttr("fpbuiltin-max-error") + .getValueAsString() + .getAsDouble(f); I->addDecorate(DecorationFPMaxErrorDecorationINTEL, convertFloatToSPIRVWord(f)); } @@ -4498,17 +4500,16 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II, } return Result; } - default: if (auto BVar = transFPBuiltinIntrinsicInst(II, BB)) return BVar; - if (BM->isUnknownIntrinsicAllowed(II)) { + if (BM->isUnknownIntrinsicAllowed(II)) return BM->addCallInst( transFunctionDecl(II->getCalledFunction()), transArguments(II, BB, SPIRVEntry::createUnique(OpFunctionCall).get()), BB); - } else + else // Other LLVM intrinsics shouldn't get to SPIRV, because they // can't be represented in SPIRV or aren't implemented yet. BM->SPIRVCK( @@ -4524,18 +4525,20 @@ LLVMToSPIRVBase::getFPBuiltinType(IntrinsicInst *II, StringRef &OpName) { return FPBuiltinType::UNKNOWN; Name.consume_front("llvm.fpbuiltin."); OpName = Name.split('.').first; - FPBuiltinType Type = StringSwitch(OpName) - .Cases("fadd", "fsub", "fmul", "fdiv", "frem", FPBuiltinType::REGULAR_MATH) - .Cases("sin", "cos", "tan", FPBuiltinType::EXT_1OPS) - .Cases("sinh", "cosh", "tanh", FPBuiltinType::EXT_1OPS) - .Cases("asin", "acos", "atan", FPBuiltinType::EXT_1OPS) - .Cases("asinh", "acosh", "atanh", FPBuiltinType::EXT_1OPS) - .Cases("exp", "exp2", "exp10", "expm1", FPBuiltinType::EXT_1OPS) - .Cases("log", "log2", "log10", "log1p", FPBuiltinType::EXT_1OPS) - .Cases("sqrt", "rsqrt", "erf", "erfc", FPBuiltinType::EXT_1OPS) - .Cases("atan2", "pow", "hypot", "ldexp", FPBuiltinType::EXT_2OPS) - .Case("sincos", FPBuiltinType::EXT_3OPS) - .Default(FPBuiltinType::UNKNOWN); + FPBuiltinType Type = + StringSwitch(OpName) + .Cases("fadd", "fsub", "fmul", "fdiv", "frem", + FPBuiltinType::REGULAR_MATH) + .Cases("sin", "cos", "tan", FPBuiltinType::EXT_1OPS) + .Cases("sinh", "cosh", "tanh", FPBuiltinType::EXT_1OPS) + .Cases("asin", "acos", "atan", FPBuiltinType::EXT_1OPS) + .Cases("asinh", "acosh", "atanh", FPBuiltinType::EXT_1OPS) + .Cases("exp", "exp2", "exp10", "expm1", FPBuiltinType::EXT_1OPS) + .Cases("log", "log2", "log10", "log1p", FPBuiltinType::EXT_1OPS) + .Cases("sqrt", "rsqrt", "erf", "erfc", FPBuiltinType::EXT_1OPS) + .Cases("atan2", "pow", "hypot", "ldexp", FPBuiltinType::EXT_2OPS) + .Case("sincos", FPBuiltinType::EXT_3OPS) + .Default(FPBuiltinType::UNKNOWN); return Type; } @@ -4544,86 +4547,86 @@ SPIRVValue *LLVMToSPIRVBase::transFPBuiltinIntrinsicInst(IntrinsicInst *II, StringRef OpName; auto FPBuiltinType = getFPBuiltinType(II, OpName); switch (FPBuiltinType) { - case FPBuiltinType::REGULAR_MATH: { - auto BinOp = StringSwitch(OpName) - .Case("fadd", OpFAdd) - .Case("fsub", OpFSub) - .Case("fmul", OpFMul) - .Case("fdiv", OpFDiv) - .Case("frem", OpFRem) - .Default(OpUndef); - auto BI = BM->addBinaryInst(BinOp, transType(II->getType()), - transValue(II->getArgOperand(0), BB), - transValue(II->getArgOperand(1), BB), BB); - return addFPBuiltinDecoration(BM, II, BI); - } - case FPBuiltinType::EXT_1OPS: { - if (!checkTypeForSPIRVExtendedInstLowering(II, BM)) - break; - SPIRVType *STy = transType(II->getType()); - std::vector Ops(1, transValue(II->getArgOperand(0), BB)); - auto ExtOp = StringSwitch(OpName) - .Case("sin", OpenCLLIB::Sin) - .Case("cos", OpenCLLIB::Cos) - .Case("tan", OpenCLLIB::Tan) - .Case("sinh", OpenCLLIB::Sinh) - .Case("cosh", OpenCLLIB::Cosh) - .Case("tanh", OpenCLLIB::Tanh) - .Case("asin", OpenCLLIB::Asin) - .Case("acos", OpenCLLIB::Acos) - .Case("atan", OpenCLLIB::Atan) - .Case("asinh", OpenCLLIB::Asinh) - .Case("acosh", OpenCLLIB::Acosh) - .Case("atanh", OpenCLLIB::Atanh) - .Case("exp", OpenCLLIB::Exp) - .Case("exp2", OpenCLLIB::Exp2) - .Case("exp10", OpenCLLIB::Exp10) - .Case("expm1", OpenCLLIB::Expm1) - .Case("log", OpenCLLIB::Log) - .Case("log2", OpenCLLIB::Log2) - .Case("log10", OpenCLLIB::Log10) - .Case("log1p", OpenCLLIB::Log1p) - .Case("sqrt", OpenCLLIB::Sqrt) - .Case("rsqrt", OpenCLLIB::Rsqrt) - .Case("erf", OpenCLLIB::Erf) - .Case("erfc", OpenCLLIB::Erfc) - .Default(SPIRVWORD_MAX); - auto BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, - Ops, BB); - return addFPBuiltinDecoration(BM, II, BI); - } - case FPBuiltinType::EXT_2OPS: { - if (!checkTypeForSPIRVExtendedInstLowering(II, BM)) - break; - SPIRVType *STy = transType(II->getType()); - std::vector Ops{transValue(II->getArgOperand(0), BB), - transValue(II->getArgOperand(1), BB)}; - auto ExtOp = StringSwitch(OpName) - .Case("atan2", OpenCLLIB::Atan2) - .Case("hypot", OpenCLLIB::Hypot) - .Case("pow", OpenCLLIB::Pow) - .Case("ldexp", OpenCLLIB::Ldexp) - .Default(SPIRVWORD_MAX); - auto BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, - Ops, BB); - return addFPBuiltinDecoration(BM, II, BI); - } - case FPBuiltinType::EXT_3OPS: { - if (!checkTypeForSPIRVExtendedInstLowering(II, BM)) - break; - SPIRVType *STy = transType(II->getType()); - std::vector Ops{transValue(II->getArgOperand(0), BB), - transValue(II->getArgOperand(1), BB), - transValue(II->getArgOperand(2), BB)}; - auto ExtOp = StringSwitch(OpName) - .Case("sincos", OpenCLLIB::Sincos) - .Default(SPIRVWORD_MAX); - auto BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, - Ops, BB); - return addFPBuiltinDecoration(BM, II, BI); - } - default: - return nullptr; + case FPBuiltinType::REGULAR_MATH: { + auto BinOp = StringSwitch(OpName) + .Case("fadd", OpFAdd) + .Case("fsub", OpFSub) + .Case("fmul", OpFMul) + .Case("fdiv", OpFDiv) + .Case("frem", OpFRem) + .Default(OpUndef); + auto BI = BM->addBinaryInst(BinOp, transType(II->getType()), + transValue(II->getArgOperand(0), BB), + transValue(II->getArgOperand(1), BB), BB); + return addFPBuiltinDecoration(BM, II, BI); + } + case FPBuiltinType::EXT_1OPS: { + if (!checkTypeForSPIRVExtendedInstLowering(II, BM)) + break; + SPIRVType *STy = transType(II->getType()); + std::vector Ops(1, transValue(II->getArgOperand(0), BB)); + auto ExtOp = StringSwitch(OpName) + .Case("sin", OpenCLLIB::Sin) + .Case("cos", OpenCLLIB::Cos) + .Case("tan", OpenCLLIB::Tan) + .Case("sinh", OpenCLLIB::Sinh) + .Case("cosh", OpenCLLIB::Cosh) + .Case("tanh", OpenCLLIB::Tanh) + .Case("asin", OpenCLLIB::Asin) + .Case("acos", OpenCLLIB::Acos) + .Case("atan", OpenCLLIB::Atan) + .Case("asinh", OpenCLLIB::Asinh) + .Case("acosh", OpenCLLIB::Acosh) + .Case("atanh", OpenCLLIB::Atanh) + .Case("exp", OpenCLLIB::Exp) + .Case("exp2", OpenCLLIB::Exp2) + .Case("exp10", OpenCLLIB::Exp10) + .Case("expm1", OpenCLLIB::Expm1) + .Case("log", OpenCLLIB::Log) + .Case("log2", OpenCLLIB::Log2) + .Case("log10", OpenCLLIB::Log10) + .Case("log1p", OpenCLLIB::Log1p) + .Case("sqrt", OpenCLLIB::Sqrt) + .Case("rsqrt", OpenCLLIB::Rsqrt) + .Case("erf", OpenCLLIB::Erf) + .Case("erfc", OpenCLLIB::Erfc) + .Default(SPIRVWORD_MAX); + auto BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, + Ops, BB); + return addFPBuiltinDecoration(BM, II, BI); + } + case FPBuiltinType::EXT_2OPS: { + if (!checkTypeForSPIRVExtendedInstLowering(II, BM)) + break; + SPIRVType *STy = transType(II->getType()); + std::vector Ops{transValue(II->getArgOperand(0), BB), + transValue(II->getArgOperand(1), BB)}; + auto ExtOp = StringSwitch(OpName) + .Case("atan2", OpenCLLIB::Atan2) + .Case("hypot", OpenCLLIB::Hypot) + .Case("pow", OpenCLLIB::Pow) + .Case("ldexp", OpenCLLIB::Ldexp) + .Default(SPIRVWORD_MAX); + auto BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, + Ops, BB); + return addFPBuiltinDecoration(BM, II, BI); + } + case FPBuiltinType::EXT_3OPS: { + if (!checkTypeForSPIRVExtendedInstLowering(II, BM)) + break; + SPIRVType *STy = transType(II->getType()); + std::vector Ops{transValue(II->getArgOperand(0), BB), + transValue(II->getArgOperand(1), BB), + transValue(II->getArgOperand(2), BB)}; + auto ExtOp = StringSwitch(OpName) + .Case("sincos", OpenCLLIB::Sincos) + .Default(SPIRVWORD_MAX); + auto BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, + Ops, BB); + return addFPBuiltinDecoration(BM, II, BI); + } + default: + return nullptr; } return nullptr; } diff --git a/lib/SPIRV/SPIRVWriter.h b/lib/SPIRV/SPIRVWriter.h index daeedbf5cc..2c11e15b91 100644 --- a/lib/SPIRV/SPIRVWriter.h +++ b/lib/SPIRV/SPIRVWriter.h @@ -108,8 +108,13 @@ class LLVMToSPIRVBase : protected BuiltinCallHelper { bool transBuiltinSet(); bool isKnownIntrinsic(Intrinsic::ID Id); SPIRVValue *transIntrinsicInst(IntrinsicInst *Intrinsic, SPIRVBasicBlock *BB); - enum class FPBuiltinType {REGULAR_MATH, EXT_1OPS, EXT_2OPS, EXT_3OPS, - UNKNOWN}; + enum class FPBuiltinType { + REGULAR_MATH, + EXT_1OPS, + EXT_2OPS, + EXT_3OPS, + UNKNOWN + }; FPBuiltinType getFPBuiltinType(IntrinsicInst *II, StringRef &); SPIRVValue *transFPBuiltinIntrinsicInst(IntrinsicInst *II, SPIRVBasicBlock *BB); From 340d5304dc006b08d0b83bbf1ca4eb1441fc9ce5 Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Thu, 13 Jul 2023 15:51:57 -0700 Subject: [PATCH 04/13] Add attributes for some math builtin functions and add metadata for basic math functions (add/sub/mul/div/rem) Signed-off-by: Arvind Sudarsanam --- lib/SPIRV/SPIRVBuiltinHelper.cpp | 1 + lib/SPIRV/SPIRVReader.cpp | 12 +++- .../SPV_INTEL_fp_max_error/IntelFPMaxError.ll | 72 +++++++++---------- 3 files changed, 47 insertions(+), 38 deletions(-) diff --git a/lib/SPIRV/SPIRVBuiltinHelper.cpp b/lib/SPIRV/SPIRVBuiltinHelper.cpp index 57b73cf7e0..55132e673c 100644 --- a/lib/SPIRV/SPIRVBuiltinHelper.cpp +++ b/lib/SPIRV/SPIRVBuiltinHelper.cpp @@ -103,6 +103,7 @@ Value *BuiltinCallMutator::doConversion() { Builder.Insert(addCallInst(CI->getModule(), FuncName, ReturnTy, Args, &Attrs, nullptr, Mangler.get())); NewCall->copyMetadata(*CI); + NewCall->setAttributes(CI->getAttributes()); Value *Result = MutateRet ? MutateRet(Builder, NewCall) : NewCall; Result->takeName(CI); if (!CI->getType()->isVoidTy()) diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 8ba451bb20..324f104b61 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -3873,9 +3873,17 @@ bool SPIRVToLLVM::transDecoration(SPIRVValue *BV, Value *V) { assert(Literals.size() == 1 && "FP Max Error decoration shall have 1 operand"); auto f = convertSPIRVWordToFloat(Literals[0]); - MDNode *N = + if (CallInst *CI = dyn_cast(I)) { + // Add atribute + auto A = llvm::Attribute::get(*Context, "fpbuiltin-max-error", + std::to_string(f)); + CI->addFnAttr(A); + } else { + // Add metadata + MDNode *N = MDNode::get(*Context, MDString::get(*Context, std::to_string(f))); - I->setMetadata("fpbuiltin-max-error", N); + I->setMetadata("fpbuiltin-max-error", N); + } return true; } diff --git a/test/extensions/INTEL/SPV_INTEL_fp_max_error/IntelFPMaxError.ll b/test/extensions/INTEL/SPV_INTEL_fp_max_error/IntelFPMaxError.ll index 4a7cf5d7a9..8d1b00bf14 100644 --- a/test/extensions/INTEL/SPV_INTEL_fp_max_error/IntelFPMaxError.ll +++ b/test/extensions/INTEL/SPV_INTEL_fp_max_error/IntelFPMaxError.ll @@ -113,7 +113,7 @@ ; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T31]] [[#OCLEXTID]] ldexp ; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T32]] [[#OCLEXTID]] pow ; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T33]] [[#OCLEXTID]] hypot -; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T34]] [[#OCLEXTID]] sincos +; CHECK-SPIRV: ExtInst [[#FTYPE]] [[#T34]] [[#OCLEXTID]] hypot target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" target triple = "spir64-unknown-unknown" @@ -131,72 +131,73 @@ entry: %t4 = call float @llvm.fpbuiltin.fdiv.f32(float %f1, float %f2) #1 %t5 = call float @llvm.fpbuiltin.frem.f32(float %f1, float %f2) #1 -; CHECK-LLVM: call spir_func float @_Z3sinf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3:]] -; CHECK-LLVM: call spir_func float @_Z3cosf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] -; CHECK-LLVM: call spir_func float @_Z3tanf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM: call spir_func float @_Z3sinf(float %f1) #[[#AT3:]] +; CHECK-LLVM: call spir_func float @_Z3cosf(float %f1) #[[#AT3]] +; CHECK-LLVM: call spir_func float @_Z3tanf(float %f1) #[[#AT3]] %t6 = call float @llvm.fpbuiltin.sin.f32(float %f1) #2 %t7 = call float @llvm.fpbuiltin.cos.f32(float %f1) #2 %t8 = call float @llvm.fpbuiltin.tan.f32(float %f1) #2 -; CHECK-LLVM: call spir_func float @_Z4sinhf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] -; CHECK-LLVM: call spir_func float @_Z4coshf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] -; CHECK-LLVM: call spir_func float @_Z4tanhf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM: call spir_func float @_Z4sinhf(float %f1) #[[#AT3]] +; CHECK-LLVM: call spir_func float @_Z4coshf(float %f1) #[[#AT3]] +; CHECK-LLVM: call spir_func float @_Z4tanhf(float %f1) #[[#AT3]] %t9 = call float @llvm.fpbuiltin.sinh.f32(float %f1) #2 %t10 = call float @llvm.fpbuiltin.cosh.f32(float %f1) #2 %t11 = call float @llvm.fpbuiltin.tanh.f32(float %f1) #2 -; CHECK-LLVM: call spir_func float @_Z4asinf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] -; CHECK-LLVM: call spir_func float @_Z4acosf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] -; CHECK-LLVM: call spir_func float @_Z4atanf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM: call spir_func float @_Z4asinf(float %f1) #[[#AT3]] +; CHECK-LLVM: call spir_func float @_Z4acosf(float %f1) #[[#AT3]] +; CHECK-LLVM: call spir_func float @_Z4atanf(float %f1) #[[#AT3]] %t12 = call float @llvm.fpbuiltin.asin.f32(float %f1) #2 %t13 = call float @llvm.fpbuiltin.acos.f32(float %f1) #2 %t14 = call float @llvm.fpbuiltin.atan.f32(float %f1) #2 -; CHECK-LLVM:15 = call spir_func float @_Z5asinhf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] -; CHECK-LLVM:16 = call spir_func float @_Z5acoshf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] -; CHECK-LLVM:17 = call spir_func float @_Z5atanhf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM:15 = call spir_func float @_Z5asinhf(float %f1) #[[#AT3]] +; CHECK-LLVM:16 = call spir_func float @_Z5acoshf(float %f1) #[[#AT3]] +; CHECK-LLVM:17 = call spir_func float @_Z5atanhf(float %f1) #[[#AT3]] %t15 = call float @llvm.fpbuiltin.asinh.f32(float %f1) #2 %t16 = call float @llvm.fpbuiltin.acosh.f32(float %f1) #2 %t17 = call float @llvm.fpbuiltin.atanh.f32(float %f1) #2 -; CHECK-LLVM:18 = call spir_func float @_Z3expf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] -; CHECK-LLVM:19 = call spir_func float @_Z4exp2f(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] -; CHECK-LLVM:20 = call spir_func float @_Z5exp10f(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] -; CHECK-LLVM:21 = call spir_func float @_Z5expm1f(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM:18 = call spir_func float @_Z3expf(float %f1) #[[#AT3]] +; CHECK-LLVM:19 = call spir_func float @_Z4exp2f(float %f1) #[[#AT3]] +; CHECK-LLVM:20 = call spir_func float @_Z5exp10f(float %f1) #[[#AT3]] +; CHECK-LLVM:21 = call spir_func float @_Z5expm1f(float %f1) #[[#AT3]] %t18 = call float @llvm.fpbuiltin.exp.f32(float %f1) #2 %t19 = call float @llvm.fpbuiltin.exp2.f32(float %f1) #2 %t20 = call float @llvm.fpbuiltin.exp10.f32(float %f1) #2 %t21 = call float @llvm.fpbuiltin.expm1.f32(float %f1) #2 -; CHECK-LLVM: call spir_func float @_Z3logf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] -; CHECK-LLVM: call spir_func float @_Z4log2f(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] -; CHECK-LLVM: call spir_func float @_Z5log10f(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] -; CHECK-LLVM: call spir_func float @_Z5log1pf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM: call spir_func float @_Z3logf(float %f1) #[[#AT3]] +; CHECK-LLVM: call spir_func float @_Z4log2f(float %f1) #[[#AT3]] +; CHECK-LLVM: call spir_func float @_Z5log10f(float %f1) #[[#AT3]] +; CHECK-LLVM: call spir_func float @_Z5log1pf(float %f1) #[[#AT3]] %t22 = call float @llvm.fpbuiltin.log.f32(float %f1) #2 %t23 = call float @llvm.fpbuiltin.log2.f32(float %f1) #2 %t24 = call float @llvm.fpbuiltin.log10.f32(float %f1) #2 %t25 = call float @llvm.fpbuiltin.log1p.f32(float %f1) #2 -; CHECK-LLVM: call spir_func float @_Z4sqrtf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] -; CHECK-LLVM: call spir_func float @_Z5rsqrtf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] -; CHECK-LLVM: call spir_func float @_Z3erff(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] -; CHECK-LLVM: call spir_func float @_Z4erfcf(float %f1) {{.*}} !fpbuiltin-max-error ![[#ME3]] +; CHECK-LLVM: call spir_func float @_Z4sqrtf(float %f1) #[[#AT3]] +; CHECK-LLVM: call spir_func float @_Z5rsqrtf(float %f1) #[[#AT3]] +; CHECK-LLVM: call spir_func float @_Z3erff(float %f1) #[[#AT3]] +; CHECK-LLVM: call spir_func float @_Z4erfcf(float %f1) #[[#AT3]] %t26 = call float @llvm.fpbuiltin.sqrt.f32(float %f1) #2 %t27 = call float @llvm.fpbuiltin.rsqrt.f32(float %f1) #2 %t28 = call float @llvm.fpbuiltin.erf.f32(float %f1) #2 %t29 = call float @llvm.fpbuiltin.erfc.f32(float %f1) #2 -; CHECK-LLVM: call spir_func float @_Z5atan2ff(float %f1, float %f2) {{.*}} !fpbuiltin-max-error ![[#ME4:]] -; CHECK-LLVM: call spir_func float @_Z5ldexpff(float %f1, float %f2) {{.*}} !fpbuiltin-max-error ![[#ME4]] -; CHECK-LLVM: call spir_func float @_Z3powff(float %f1, float %f2) {{.*}} !fpbuiltin-max-error ![[#ME4]] -; CHECK-LLVM: call spir_func float @_Z5hypotff(float %f1, float %f2) #0, !fpbuiltin-max-error ![[#ME4]] +; CHECK-LLVM: call spir_func float @_Z5atan2ff(float %f1, float %f2) #[[#AT4:]] +; CHECK-LLVM: call spir_func float @_Z5ldexpff(float %f1, float %f2) #[[#AT4]] +; CHECK-LLVM: call spir_func float @_Z3powff(float %f1, float %f2) #[[#AT4]] +; CHECK-LLVM: call spir_func float @_Z5hypotff(float %f1, float %f2) #[[#AT4]] %t30 = call float @llvm.fpbuiltin.atan2.f32(float %f1, float %f2) #3 %t31 = call float @llvm.fpbuiltin.ldexp.f32(float %f1, float %f2) #3 %t32 = call float @llvm.fpbuiltin.pow.f32(float %f1, float %f2) #3 %t33 = call float @llvm.fpbuiltin.hypot.f32(float %f1, float %f2) #3 + + ; CHECK-LLVM: call spir_func float @_Z5hypotff(float %f1, float %f2) #[[#AT5:]] + %t34 = call float @llvm.fpbuiltin.hypot.f32(float %f1, float %f2) #4 -; CHECK-LLVM: call spir_func float @_Z6sincosfff(float %f1, float %f2, float %f3) {{.*}} !fpbuiltin-max-error ![[#ME5:]] - %t34 = call float @llvm.fpbuiltin.sincos.f32(float %f1, float %f2, float %f3) #4 ret void } @@ -236,13 +237,12 @@ declare float @llvm.fpbuiltin.hypot.f32(float, float) declare float @llvm.fpbuiltin.pow.f32(float, float) declare float @llvm.fpbuiltin.ldexp.f32(float, float) -declare float @llvm.fpbuiltin.sincos.f32(float, float, float) - +; CHECK-LLVM: attributes #[[#AT3]] = {{{.*}} "fpbuiltin-max-error"="2.5{{0+}}" {{.*}}} +; CHECK-LLVM: attributes #[[#AT4]] = {{{.*}} "fpbuiltin-max-error"="4.0{{0+}}" {{.*}}} +; CHECK-LLVM: attributes #[[#AT5]] = {{{.*}} "fpbuiltin-max-error"="4096.0{{0+}}" {{.*}}} ; CHECK-LLVM: ![[#ME1]] = !{!"0.500000"} ; CHECK-LLVM: ![[#ME2]] = !{!"1.000000"} -; CHECK-LLVM: ![[#ME3]] = !{!"2.500000"} -; CHECK-LLVM: ![[#ME4]] = !{!"4.000000"} -; CHECK-LLVM: ![[#ME5]] = !{!"4096.000000"} + attributes #0 = { "fpbuiltin-max-error"="0.5" } attributes #1 = { "fpbuiltin-max-error"="1.0" } attributes #2 = { "fpbuiltin-max-error"="2.5" } From 20bd965df1c5098374c409bd7a9be2607b67dc51 Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Wed, 19 Jul 2023 13:11:24 -0700 Subject: [PATCH 05/13] Update SPIRV-Headers tag Signed-off-by: Arvind Sudarsanam --- spirv-headers-tag.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spirv-headers-tag.conf b/spirv-headers-tag.conf index f262541102..221c847ceb 100644 --- a/spirv-headers-tag.conf +++ b/spirv-headers-tag.conf @@ -1 +1 @@ -1feaf4414eb2b353764d01d88f8aa4bcc67b60db +88d56db61c3a53451a4299b5a6811fb9a994eb32 From 22f367b4efb2e0b9d4b987a97701622d69d49214 Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Thu, 20 Jul 2023 09:29:30 -0700 Subject: [PATCH 06/13] fix clang-tidy issues Signed-off-by: Arvind Sudarsanam --- lib/SPIRV/SPIRVReader.cpp | 20 ++++++++++++-------- lib/SPIRV/SPIRVWriter.cpp | 38 +++++++++++++++++++++----------------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 220fa7ec74..e62b2712f1 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -3863,15 +3863,19 @@ void SPIRVToLLVM::transVarDecorationsToMetadata(SPIRVValue *BV, Value *V) { } } -static float convertSPIRVWordToFloat(SPIRVWord spir) { +namespace { + +static float convertSPIRVWordToFloat(SPIRVWord Spir) { union { - float f; - SPIRVWord spir; + float F; + SPIRVWord Spir; } FPMaxError; - FPMaxError.spir = spir; - return FPMaxError.f; + FPMaxError.Spir = Spir; + return FPMaxError.F; } +} // namespace + bool SPIRVToLLVM::transDecoration(SPIRVValue *BV, Value *V) { SPIRVWord ID; if (Instruction *I = dyn_cast(V)) @@ -3880,16 +3884,16 @@ bool SPIRVToLLVM::transDecoration(SPIRVValue *BV, Value *V) { BV->getDecorationLiterals(DecorationFPMaxErrorDecorationINTEL); assert(Literals.size() == 1 && "FP Max Error decoration shall have 1 operand"); - auto f = convertSPIRVWordToFloat(Literals[0]); + auto F = convertSPIRVWordToFloat(Literals[0]); if (CallInst *CI = dyn_cast(I)) { // Add atribute auto A = llvm::Attribute::get(*Context, "fpbuiltin-max-error", - std::to_string(f)); + std::to_string(F)); CI->addFnAttr(A); } else { // Add metadata MDNode *N = - MDNode::get(*Context, MDString::get(*Context, std::to_string(f))); + MDNode::get(*Context, MDString::get(*Context, std::to_string(F))); I->setMetadata("fpbuiltin-max-error", N); } return true; diff --git a/lib/SPIRV/SPIRVWriter.cpp b/lib/SPIRV/SPIRVWriter.cpp index 4f2ca333d5..2e503bf3dd 100644 --- a/lib/SPIRV/SPIRVWriter.cpp +++ b/lib/SPIRV/SPIRVWriter.cpp @@ -106,6 +106,19 @@ using namespace llvm; using namespace SPIRV; using namespace OCLUtil; +namespace { + +static SPIRVWord convertFloatToSPIRVWord(float F) { + union { + float F; + SPIRVWord Spir; + } FPMaxError; + FPMaxError.F = F; + return FPMaxError.Spir; +} + +} // namespace + namespace SPIRV { static void foreachKernelArgMD( @@ -161,15 +174,6 @@ static void translateSEVDecoration(Attribute Sev, SPIRVValue *Val) { Val->addDecorate(DecorationSingleElementVectorINTEL); } -static SPIRVWord convertFloatToSPIRVWord(float f) { - union { - float f; - SPIRVWord spir; - } FPMaxError; - FPMaxError.f = f; - return FPMaxError.spir; -} - LLVMToSPIRVBase::LLVMToSPIRVBase(SPIRVModule *SMod) : BuiltinCallHelper(ManglingRules::None), M(nullptr), Ctx(nullptr), BM(SMod), SrcLang(0), SrcLangVer(0) { @@ -3540,13 +3544,13 @@ SPIRVInstruction *addFPBuiltinDecoration(SPIRVModule *BM, IntrinsicInst *II, // Add a new decoration for llvm.builtin intrinsics, if needed if (IsLLVMFPBuiltin && AllowFPMaxError) if (II->getAttributes().hasFnAttr("fpbuiltin-max-error")) { - double f = 0.0; + double F = 0.0; II->getAttributes() .getFnAttr("fpbuiltin-max-error") .getValueAsString() - .getAsDouble(f); + .getAsDouble(F); I->addDecorate(DecorationFPMaxErrorDecorationINTEL, - convertFloatToSPIRVWord(f)); + convertFloatToSPIRVWord(F)); } return I; } @@ -4497,7 +4501,7 @@ SPIRVValue *LLVMToSPIRVBase::transIntrinsicInst(IntrinsicInst *II, return Result; } default: - if (auto BVar = transFPBuiltinIntrinsicInst(II, BB)) + if (auto *BVar = transFPBuiltinIntrinsicInst(II, BB)) return BVar; if (BM->isUnknownIntrinsicAllowed(II)) return BM->addCallInst( @@ -4551,7 +4555,7 @@ SPIRVValue *LLVMToSPIRVBase::transFPBuiltinIntrinsicInst(IntrinsicInst *II, .Case("fdiv", OpFDiv) .Case("frem", OpFRem) .Default(OpUndef); - auto BI = BM->addBinaryInst(BinOp, transType(II->getType()), + auto *BI = BM->addBinaryInst(BinOp, transType(II->getType()), transValue(II->getArgOperand(0), BB), transValue(II->getArgOperand(1), BB), BB); return addFPBuiltinDecoration(BM, II, BI); @@ -4587,7 +4591,7 @@ SPIRVValue *LLVMToSPIRVBase::transFPBuiltinIntrinsicInst(IntrinsicInst *II, .Case("erf", OpenCLLIB::Erf) .Case("erfc", OpenCLLIB::Erfc) .Default(SPIRVWORD_MAX); - auto BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, + auto *BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, Ops, BB); return addFPBuiltinDecoration(BM, II, BI); } @@ -4603,7 +4607,7 @@ SPIRVValue *LLVMToSPIRVBase::transFPBuiltinIntrinsicInst(IntrinsicInst *II, .Case("pow", OpenCLLIB::Pow) .Case("ldexp", OpenCLLIB::Ldexp) .Default(SPIRVWORD_MAX); - auto BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, + auto *BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, Ops, BB); return addFPBuiltinDecoration(BM, II, BI); } @@ -4617,7 +4621,7 @@ SPIRVValue *LLVMToSPIRVBase::transFPBuiltinIntrinsicInst(IntrinsicInst *II, auto ExtOp = StringSwitch(OpName) .Case("sincos", OpenCLLIB::Sincos) .Default(SPIRVWORD_MAX); - auto BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, + auto *BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, Ops, BB); return addFPBuiltinDecoration(BM, II, BI); } From c20e4265391b233fba5817cb6700f3402cd91117 Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Thu, 20 Jul 2023 09:55:49 -0700 Subject: [PATCH 07/13] fix clang-format changes Signed-off-by: Arvind Sudarsanam --- lib/SPIRV/SPIRVReader.cpp | 2 +- lib/SPIRV/SPIRVWriter.cpp | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index e62b2712f1..d4ff59fc8d 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -3893,7 +3893,7 @@ bool SPIRVToLLVM::transDecoration(SPIRVValue *BV, Value *V) { } else { // Add metadata MDNode *N = - MDNode::get(*Context, MDString::get(*Context, std::to_string(F))); + MDNode::get(*Context, MDString::get(*Context, std::to_string(F))); I->setMetadata("fpbuiltin-max-error", N); } return true; diff --git a/lib/SPIRV/SPIRVWriter.cpp b/lib/SPIRV/SPIRVWriter.cpp index 2e503bf3dd..2589ea7865 100644 --- a/lib/SPIRV/SPIRVWriter.cpp +++ b/lib/SPIRV/SPIRVWriter.cpp @@ -3555,7 +3555,6 @@ SPIRVInstruction *addFPBuiltinDecoration(SPIRVModule *BM, IntrinsicInst *II, return I; } - // Performs mapping of LLVM IR rounding mode to SPIR-V rounding mode // Value *V is metadata argument of // llvm.experimental.constrained.* intrinsics @@ -4556,8 +4555,8 @@ SPIRVValue *LLVMToSPIRVBase::transFPBuiltinIntrinsicInst(IntrinsicInst *II, .Case("frem", OpFRem) .Default(OpUndef); auto *BI = BM->addBinaryInst(BinOp, transType(II->getType()), - transValue(II->getArgOperand(0), BB), - transValue(II->getArgOperand(1), BB), BB); + transValue(II->getArgOperand(0), BB), + transValue(II->getArgOperand(1), BB), BB); return addFPBuiltinDecoration(BM, II, BI); } case FPBuiltinType::EXT_1OPS: { @@ -4592,7 +4591,7 @@ SPIRVValue *LLVMToSPIRVBase::transFPBuiltinIntrinsicInst(IntrinsicInst *II, .Case("erfc", OpenCLLIB::Erfc) .Default(SPIRVWORD_MAX); auto *BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, - Ops, BB); + Ops, BB); return addFPBuiltinDecoration(BM, II, BI); } case FPBuiltinType::EXT_2OPS: { @@ -4608,7 +4607,7 @@ SPIRVValue *LLVMToSPIRVBase::transFPBuiltinIntrinsicInst(IntrinsicInst *II, .Case("ldexp", OpenCLLIB::Ldexp) .Default(SPIRVWORD_MAX); auto *BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, - Ops, BB); + Ops, BB); return addFPBuiltinDecoration(BM, II, BI); } case FPBuiltinType::EXT_3OPS: { @@ -4622,7 +4621,7 @@ SPIRVValue *LLVMToSPIRVBase::transFPBuiltinIntrinsicInst(IntrinsicInst *II, .Case("sincos", OpenCLLIB::Sincos) .Default(SPIRVWORD_MAX); auto *BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, - Ops, BB); + Ops, BB); return addFPBuiltinDecoration(BM, II, BI); } default: From 1f7a4ab6a8218fe0d67a07d9e42da21bee496f5c Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Fri, 21 Jul 2023 17:55:40 -0700 Subject: [PATCH 08/13] update spirv headers tag Signed-off-by: Arvind Sudarsanam --- spirv-headers-tag.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spirv-headers-tag.conf b/spirv-headers-tag.conf index 221c847ceb..e28f5847a6 100644 --- a/spirv-headers-tag.conf +++ b/spirv-headers-tag.conf @@ -1 +1 @@ -88d56db61c3a53451a4299b5a6811fb9a994eb32 +51b106461707f46d962554efe1bf56dee28958a3 From bc3eeac9473721cc8c41d7491bf9670c760ce0df Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Fri, 28 Jul 2023 18:23:38 -0700 Subject: [PATCH 09/13] Address review comments Signed-off-by: Arvind Sudarsanam --- lib/SPIRV/SPIRVReader.cpp | 2 +- lib/SPIRV/SPIRVWriter.cpp | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 9bc15f4910..ce9ddaf064 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -3893,7 +3893,7 @@ bool SPIRVToLLVM::transDecoration(SPIRVValue *BV, Value *V) { "FP Max Error decoration shall have 1 operand"); auto F = convertSPIRVWordToFloat(Literals[0]); if (CallInst *CI = dyn_cast(I)) { - // Add atribute + // Add attribute auto A = llvm::Attribute::get(*Context, "fpbuiltin-max-error", std::to_string(F)); CI->addFnAttr(A); diff --git a/lib/SPIRV/SPIRVWriter.cpp b/lib/SPIRV/SPIRVWriter.cpp index 0f5a1d31c8..d2ff562bfc 100644 --- a/lib/SPIRV/SPIRVWriter.cpp +++ b/lib/SPIRV/SPIRVWriter.cpp @@ -4538,8 +4538,10 @@ LLVMToSPIRVBase::getFPBuiltinType(IntrinsicInst *II, StringRef &OpName) { SPIRVValue *LLVMToSPIRVBase::transFPBuiltinIntrinsicInst(IntrinsicInst *II, SPIRVBasicBlock *BB) { StringRef OpName; - auto FPBuiltinType = getFPBuiltinType(II, OpName); - switch (FPBuiltinType) { + auto FPBuiltinTypeVal = getFPBuiltinType(II, OpName); + if (FPBuiltinTypeVal == FPBuiltinType::UNKNOWN) + return nullptr; + switch (FPBuiltinTypeVal) { case FPBuiltinType::REGULAR_MATH: { auto BinOp = StringSwitch(OpName) .Case("fadd", OpFAdd) @@ -4584,6 +4586,7 @@ SPIRVValue *LLVMToSPIRVBase::transFPBuiltinIntrinsicInst(IntrinsicInst *II, .Case("erf", OpenCLLIB::Erf) .Case("erfc", OpenCLLIB::Erfc) .Default(SPIRVWORD_MAX); + assert(ExtOp != SPIRVWORD_MAX); auto *BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, Ops, BB); return addFPBuiltinDecoration(BM, II, BI); @@ -4600,6 +4603,7 @@ SPIRVValue *LLVMToSPIRVBase::transFPBuiltinIntrinsicInst(IntrinsicInst *II, .Case("pow", OpenCLLIB::Pow) .Case("ldexp", OpenCLLIB::Ldexp) .Default(SPIRVWORD_MAX); + assert(ExtOp != SPIRVWORD_MAX); auto *BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, Ops, BB); return addFPBuiltinDecoration(BM, II, BI); @@ -4614,6 +4618,7 @@ SPIRVValue *LLVMToSPIRVBase::transFPBuiltinIntrinsicInst(IntrinsicInst *II, auto ExtOp = StringSwitch(OpName) .Case("sincos", OpenCLLIB::Sincos) .Default(SPIRVWORD_MAX); + assert(ExtOp != SPIRVWORD_MAX); auto *BI = BM->addExtInst(STy, BM->getExtInstSetId(SPIRVEIS_OpenCL), ExtOp, Ops, BB); return addFPBuiltinDecoration(BM, II, BI); From eaa85733ac7fcdcb34b2a4954ea2e50aac625b7d Mon Sep 17 00:00:00 2001 From: Arvind Sudarsanam Date: Fri, 28 Jul 2023 18:26:20 -0700 Subject: [PATCH 10/13] Address more review comments Signed-off-by: Arvind Sudarsanam --- lib/SPIRV/SPIRVWriter.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/SPIRV/SPIRVWriter.cpp b/lib/SPIRV/SPIRVWriter.cpp index d2ff562bfc..5661f63558 100644 --- a/lib/SPIRV/SPIRVWriter.cpp +++ b/lib/SPIRV/SPIRVWriter.cpp @@ -3533,10 +3533,9 @@ SPIRVInstruction *addFPBuiltinDecoration(SPIRVModule *BM, IntrinsicInst *II, SPIRVInstruction *I) { const bool AllowFPMaxError = BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_fp_max_error); - bool IsLLVMFPBuiltin = - II->getCalledFunction()->getName().startswith("llvm.fpbuiltin"); + assert(II->getCalledFunction()->getName().startswith("llvm.fpbuiltin")); // Add a new decoration for llvm.builtin intrinsics, if needed - if (IsLLVMFPBuiltin && AllowFPMaxError) + if (AllowFPMaxError) if (II->getAttributes().hasFnAttr("fpbuiltin-max-error")) { double F = 0.0; II->getAttributes() From 1303aa5a23237961b5b7fc35d5aa43d29ddea49a Mon Sep 17 00:00:00 2001 From: "Sudarsanam, Arvind" Date: Thu, 31 Aug 2023 07:27:07 -0700 Subject: [PATCH 11/13] Update test Signed-off-by: Sudarsanam, Arvind --- test/extensions/INTEL/SPV_INTEL_fp_max_error/IntelFPMaxError.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/extensions/INTEL/SPV_INTEL_fp_max_error/IntelFPMaxError.ll b/test/extensions/INTEL/SPV_INTEL_fp_max_error/IntelFPMaxError.ll index 8d1b00bf14..bc50f4fb40 100644 --- a/test/extensions/INTEL/SPV_INTEL_fp_max_error/IntelFPMaxError.ll +++ b/test/extensions/INTEL/SPV_INTEL_fp_max_error/IntelFPMaxError.ll @@ -3,7 +3,7 @@ ; RUN: llvm-spirv %t.spv -to-text -o %t.spt ; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV -; RUN: llvm-spirv -r -emit-opaque-pointers %t.spv -o %t.rev.bc +; RUN: llvm-spirv -r %t.spv -o %t.rev.bc ; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM ; CHECK-SPIRV: Capability FPMaxErrorINTEL From 95f019077b325c7ef61ba1a43244882d559fc671 Mon Sep 17 00:00:00 2001 From: "Sudarsanam, Arvind" Date: Thu, 31 Aug 2023 08:07:40 -0700 Subject: [PATCH 12/13] Address one of the review comments Signed-off-by: Sudarsanam, Arvind --- lib/SPIRV/SPIRVReader.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 34bef96d46..a3d2cd647e 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -3899,9 +3899,8 @@ static float convertSPIRVWordToFloat(SPIRVWord Spir) { return FPMaxError.F; } -} // namespace - -bool SPIRVToLLVM::transDecoration(SPIRVValue *BV, Value *V) { +static bool transFPMaxErrorDecoration(SPIRVValue *BV, Value *V, + LLVMContext *Context) { SPIRVWord ID; if (Instruction *I = dyn_cast(V)) if (BV->hasDecorate(DecorationFPMaxErrorDecorationINTEL, 0, &ID)) { @@ -3923,6 +3922,13 @@ bool SPIRVToLLVM::transDecoration(SPIRVValue *BV, Value *V) { } return true; } + return false; +} +} // namespace + +bool SPIRVToLLVM::transDecoration(SPIRVValue *BV, Value *V) { + if (transFPMaxErrorDecoration(BV, V, Context)) + return true; if (!transAlign(BV, V)) return false; From 2f40dbfd441cbec99e561238af424ae16495728b Mon Sep 17 00:00:00 2001 From: "Sudarsanam, Arvind" Date: Tue, 5 Sep 2023 06:25:49 -0700 Subject: [PATCH 13/13] Fix clang-format issue Signed-off-by: Sudarsanam, Arvind --- lib/SPIRV/SPIRVReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp index 95c5187a06..12ecf70ac3 100644 --- a/lib/SPIRV/SPIRVReader.cpp +++ b/lib/SPIRV/SPIRVReader.cpp @@ -3905,7 +3905,7 @@ static float convertSPIRVWordToFloat(SPIRVWord Spir) { } static bool transFPMaxErrorDecoration(SPIRVValue *BV, Value *V, - LLVMContext *Context) { + LLVMContext *Context) { SPIRVWord ID; if (Instruction *I = dyn_cast(V)) if (BV->hasDecorate(DecorationFPMaxErrorDecorationINTEL, 0, &ID)) {