From 09e8c96dcda884f0329bc91ffe4c753bc3431649 Mon Sep 17 00:00:00 2001 From: Natalie Chouinard Date: Wed, 20 Sep 2023 15:18:38 +0000 Subject: [PATCH 1/5] [SPIRV] Implement log10 for logical SPIR-V There is no log10 instruction in the GLSL Extended Instruction Set so to implement the HLSL log10 intrinsic when targeting Vulkan this change adds the logic to derive the result using the following formula: ``` log10(x) = log2(x) * (1 / log2(10)) = log2(x) * 0.30103 ``` --- llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 14 ++++- llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h | 2 +- .../Target/SPIRV/SPIRVInstructionSelector.cpp | 56 ++++++++++++++++++- llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp | 3 +- .../CodeGen/SPIRV/hlsl-intrinsics/log10.ll | 42 ++++++++++++++ 5 files changed, 111 insertions(+), 6 deletions(-) create mode 100644 llvm/test/CodeGen/SPIRV/hlsl-intrinsics/log10.ll diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp index d68454f26a802..68547e62abf82 100644 --- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp @@ -242,7 +242,7 @@ Register SPIRVGlobalRegistry::buildConstantInt(uint64_t Val, Register SPIRVGlobalRegistry::buildConstantFP(APFloat Val, MachineIRBuilder &MIRBuilder, - SPIRVType *SpvType) { + SPIRVType *SpvType, bool EmitIR) { auto &MF = MIRBuilder.getMF(); const Type *LLVMFPTy; if (SpvType) { @@ -260,8 +260,18 @@ Register SPIRVGlobalRegistry::buildConstantFP(APFloat Val, MF.getRegInfo().setRegClass(Res, &SPIRV::IDRegClass); assignTypeToVReg(LLVMFPTy, Res, MIRBuilder); DT.add(ConstFP, &MF, Res); - MIRBuilder.buildFConstant(Res, *ConstFP); + if (EmitIR) { + MIRBuilder.buildFConstant(Res, *ConstFP); + } else { + MachineInstrBuilder MIB; + assert(SpvType); + MIB = MIRBuilder.buildInstr(SPIRV::OpConstantF) + .addDef(Res) + .addUse(getSPIRVTypeID(SpvType)); + addNumImm(ConstFP->getValueAPF().bitcastToAPInt(), MIB); + } } + return Res; } diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h index 88769f84b3e50..304af2440f95a 100644 --- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h +++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h @@ -234,7 +234,7 @@ class SPIRVGlobalRegistry { Register getOrCreateConstInt(uint64_t Val, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII); Register buildConstantFP(APFloat Val, MachineIRBuilder &MIRBuilder, - SPIRVType *SpvType = nullptr); + SPIRVType *SpvType = nullptr, bool EmitIR = true); Register getOrCreateConsIntVector(uint64_t Val, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII); diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index 035989f2fe571..866bcb3cf5c9d 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -174,6 +174,9 @@ class SPIRVInstructionSelector : public InstructionSelector { bool selectExtInst(Register ResVReg, const SPIRVType *ResType, MachineInstr &I, const ExtInstList &ExtInsts) const; + bool selectLog10(Register ResVReg, const SPIRVType *ResType, + MachineInstr &I) const; + Register buildI32Constant(uint32_t Val, MachineInstr &I, const SPIRVType *ResType = nullptr) const; @@ -362,7 +365,7 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg, case TargetOpcode::G_FLOG2: return selectExtInst(ResVReg, ResType, I, CL::log2, GL::Log2); case TargetOpcode::G_FLOG10: - return selectExtInst(ResVReg, ResType, I, CL::log10); + return selectLog10(ResVReg, ResType, I); case TargetOpcode::G_FABS: return selectExtInst(ResVReg, ResType, I, CL::fabs, GL::FAbs); @@ -1562,6 +1565,57 @@ bool SPIRVInstructionSelector::selectGlobalValue( return Reg.isValid(); } +bool SPIRVInstructionSelector::selectLog10(Register ResVReg, + const SPIRVType *ResType, + MachineInstr &I) const { + if (STI.canUseExtInstSet(SPIRV::InstructionSet::OpenCL_std)) { + return selectExtInst(ResVReg, ResType, I, CL::log10); + } + + // There is no log10 instruction in the GLSL Extended Instruction set, so it + // is implemented as: + // log10(x) = log2(x) * (1 / log2(10)) + // = log2(x) * 0.30103 + + MachineIRBuilder MIRBuilder(I); + MachineBasicBlock &BB = *I.getParent(); + + // Build log2(x). + Register VarReg = MRI->createVirtualRegister(&SPIRV::IDRegClass); + bool Result = + BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpExtInst)) + .addDef(VarReg) + .addUse(GR.getSPIRVTypeID(ResType)) + .addImm(static_cast(SPIRV::InstructionSet::GLSL_std_450)) + .addImm(GL::Log) + .add(I.getOperand(1)) + .constrainAllUses(TII, TRI, RBI); + + // Build 0.30103. + assert(ResType->getOpcode() == SPIRV::OpTypeVector || + ResType->getOpcode() == SPIRV::OpTypeFloat); + // TODO: Add matrix implementeation once supported by the HLSL frontend. + const SPIRVType *SpirvScalarType = + ResType->getOpcode() == SPIRV::OpTypeVector + ? GR.getSPIRVTypeForVReg(ResType->getOperand(1).getReg()) + : ResType; + Register ScaleReg = + GR.buildConstantFP(APFloat(0.30103f), MIRBuilder, SpirvScalarType, false); + + // Multiply log2(x) by 0.30103 to get log10(x) result. + auto Opcode = ResType->getOpcode() == SPIRV::OpTypeVector + ? SPIRV::OpVectorTimesScalar + : SPIRV::OpFMulS; + Result &= BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode)) + .addDef(ResVReg) + .addUse(GR.getSPIRVTypeID(ResType)) + .addUse(VarReg) + .addUse(ScaleReg) + .constrainAllUses(TII, TRI, RBI); + + return Result; +} + namespace llvm { InstructionSelector * createSPIRVInstructionSelector(const SPIRVTargetMachine &TM, diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp index b0028f8c80a40..cffa0acd25226 100644 --- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp @@ -234,6 +234,7 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) { G_FEXP2, G_FLOG, G_FLOG2, + G_FLOG10, G_FABS, G_FMINNUM, G_FMAXNUM, @@ -259,8 +260,6 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) { allFloatScalarsAndVectors, allIntScalarsAndVectors); if (ST.canUseExtInstSet(SPIRV::InstructionSet::OpenCL_std)) { - getActionDefinitionsBuilder(G_FLOG10).legalFor(allFloatScalarsAndVectors); - getActionDefinitionsBuilder( {G_CTTZ, G_CTTZ_ZERO_UNDEF, G_CTLZ, G_CTLZ_ZERO_UNDEF}) .legalForCartesianProduct(allIntScalarsAndVectors, diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/log10.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/log10.ll new file mode 100644 index 0000000000000..7a3a611f5e7f1 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/log10.ll @@ -0,0 +1,42 @@ +; RUN: llc -O0 -mtriple=spirv-unknown-linux %s -o - | FileCheck %s + +; CHECK: OpExtInstImport "GLSL.std.450" + +; CHECK: %[[#float:]] = OpTypeFloat 32 +; CHECK: %[[#v4float:]] = OpTypeVector %[[#float]] 4 +; CHECK: %[[#float_0_30103001:]] = OpConstant %[[#float]] 0.30103000998497009 +; CHECK: %[[#_ptr_Function_v4float:]] = OpTypePointer Function %[[#v4float]] +; CHECK: %[[#_ptr_Function_float:]] = OpTypePointer Function %[[#float]] + +define void @main() { +entry: +; CHECK: %[[#f:]] = OpVariable %[[#_ptr_Function_float]] Function +; CHECK: %[[#logf:]] = OpVariable %[[#_ptr_Function_float]] Function +; CHECK: %[[#f4:]] = OpVariable %[[#_ptr_Function_v4float]] Function +; CHECK: %[[#logf4:]] = OpVariable %[[#_ptr_Function_v4float]] Function + %f = alloca float, align 4 + %logf = alloca float, align 4 + %f4 = alloca <4 x float>, align 16 + %logf4 = alloca <4 x float>, align 16 + +; CHECK: %[[#load:]] = OpLoad %[[#float]] %[[#f]] Aligned 4 +; CHECK: %[[#log2:]] = OpExtInst %[[#float]] %15 Log %[[#load]] +; CHECK: %[[#res:]] = OpFMul %[[#float]] %[[#log2]] %[[#float_0_30103001]] +; CHECK: OpStore %[[#logf]] %[[#res]] Aligned 4 + %0 = load float, ptr %f, align 4 + %elt.log10 = call float @llvm.log10.f32(float %0) + store float %elt.log10, ptr %logf, align 4 + +; CHECK: %[[#load:]] = OpLoad %[[#v4float]] %[[#f4]] Aligned 16 +; CHECK: %[[#log2:]] = OpExtInst %[[#v4float]] %15 Log %[[#load]] +; CHECK: %[[#res:]] = OpVectorTimesScalar %[[#v4float]] %[[#log2]] %[[#float_0_30103001]] +; CHECK: OpStore %[[#logf4]] %[[#res]] Aligned 16 + %1 = load <4 x float>, ptr %f4, align 16 + %elt.log101 = call <4 x float> @llvm.log10.v4f32(<4 x float> %1) + store <4 x float> %elt.log101, ptr %logf4, align 16 + + ret void +} + +declare float @llvm.log10.f32(float) +declare <4 x float> @llvm.log10.v4f32(<4 x float>) From 3b92adc970a765f0a430309f3197463dd5547d99 Mon Sep 17 00:00:00 2001 From: Natalie Chouinard Date: Wed, 27 Sep 2023 15:55:43 +0000 Subject: [PATCH 2/5] Use Log2 not Log --- llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp | 2 +- llvm/test/CodeGen/SPIRV/hlsl-intrinsics/log10.ll | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index 866bcb3cf5c9d..bae0a91efa917 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -1587,7 +1587,7 @@ bool SPIRVInstructionSelector::selectLog10(Register ResVReg, .addDef(VarReg) .addUse(GR.getSPIRVTypeID(ResType)) .addImm(static_cast(SPIRV::InstructionSet::GLSL_std_450)) - .addImm(GL::Log) + .addImm(GL::Log2) .add(I.getOperand(1)) .constrainAllUses(TII, TRI, RBI); diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/log10.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/log10.ll index 7a3a611f5e7f1..e7b00eb962f44 100644 --- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/log10.ll +++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/log10.ll @@ -1,6 +1,6 @@ ; RUN: llc -O0 -mtriple=spirv-unknown-linux %s -o - | FileCheck %s -; CHECK: OpExtInstImport "GLSL.std.450" +; CHECK: %[[#extinst:]] = OpExtInstImport "GLSL.std.450" ; CHECK: %[[#float:]] = OpTypeFloat 32 ; CHECK: %[[#v4float:]] = OpTypeVector %[[#float]] 4 @@ -20,7 +20,7 @@ entry: %logf4 = alloca <4 x float>, align 16 ; CHECK: %[[#load:]] = OpLoad %[[#float]] %[[#f]] Aligned 4 -; CHECK: %[[#log2:]] = OpExtInst %[[#float]] %15 Log %[[#load]] +; CHECK: %[[#log2:]] = OpExtInst %[[#float]] %[[#extinst]] Log2 %[[#load]] ; CHECK: %[[#res:]] = OpFMul %[[#float]] %[[#log2]] %[[#float_0_30103001]] ; CHECK: OpStore %[[#logf]] %[[#res]] Aligned 4 %0 = load float, ptr %f, align 4 @@ -28,7 +28,7 @@ entry: store float %elt.log10, ptr %logf, align 4 ; CHECK: %[[#load:]] = OpLoad %[[#v4float]] %[[#f4]] Aligned 16 -; CHECK: %[[#log2:]] = OpExtInst %[[#v4float]] %15 Log %[[#load]] +; CHECK: %[[#log2:]] = OpExtInst %[[#v4float]] %[[#extinst]] Log2 %[[#load]] ; CHECK: %[[#res:]] = OpVectorTimesScalar %[[#v4float]] %[[#log2]] %[[#float_0_30103001]] ; CHECK: OpStore %[[#logf4]] %[[#res]] Aligned 16 %1 = load <4 x float>, ptr %f4, align 16 From 0f957d18785dc1e5ad91cc8d1f5810bd81828476 Mon Sep 17 00:00:00 2001 From: Natalie Chouinard Date: Wed, 27 Sep 2023 15:57:02 +0000 Subject: [PATCH 3/5] Correct reg types --- llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp index 68547e62abf82..c9adf6c86929b 100644 --- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp @@ -256,9 +256,11 @@ Register SPIRVGlobalRegistry::buildConstantFP(APFloat Val, Register Res = DT.find(ConstFP, &MF); if (!Res.isValid()) { unsigned BitWidth = SpvType ? getScalarOrVectorBitWidth(SpvType) : 32; - Res = MF.getRegInfo().createGenericVirtualRegister(LLT::scalar(BitWidth)); + LLT LLTy = LLT::scalar(EmitIR ? BitWidth : 32); + Res = MF.getRegInfo().createGenericVirtualRegister(LLTy); MF.getRegInfo().setRegClass(Res, &SPIRV::IDRegClass); - assignTypeToVReg(LLVMFPTy, Res, MIRBuilder); + assignTypeToVReg(LLVMFPTy, Res, MIRBuilder, + SPIRV::AccessQualifier::ReadWrite, EmitIR); DT.add(ConstFP, &MF, Res); if (EmitIR) { MIRBuilder.buildFConstant(Res, *ConstFP); From bfb8a657709f05f1550ae23cb83b61af3042da57 Mon Sep 17 00:00:00 2001 From: Natalie Chouinard Date: Wed, 27 Sep 2023 16:38:55 +0000 Subject: [PATCH 4/5] Typo and TODO --- llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp | 2 +- llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index bae0a91efa917..d0dcc4fd4acbf 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -1594,7 +1594,7 @@ bool SPIRVInstructionSelector::selectLog10(Register ResVReg, // Build 0.30103. assert(ResType->getOpcode() == SPIRV::OpTypeVector || ResType->getOpcode() == SPIRV::OpTypeFloat); - // TODO: Add matrix implementeation once supported by the HLSL frontend. + // TODO: Add matrix implementation once supported by the HLSL frontend. const SPIRVType *SpirvScalarType = ResType->getOpcode() == SPIRV::OpTypeVector ? GR.getSPIRVTypeForVReg(ResType->getOperand(1).getReg()) diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp index cffa0acd25226..faaf7f0e25489 100644 --- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp @@ -229,6 +229,10 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) { // Control-flow. In some cases (e.g. constants) s1 may be promoted to s32. getActionDefinitionsBuilder(G_BRCOND).legalFor({s1, s32}); + // TODO: Review the target OpenCL and GLSL Extended Instruction Set specs to + // tighten these requirements. Many of these math functions are only legal on + // specific bitwidths, so they are not selectable for + // allFloatScalarsAndVectors. getActionDefinitionsBuilder({G_FPOW, G_FEXP, G_FEXP2, From 4cccd5f35e13a1a1d8eec1fca5e09e47fd0803aa Mon Sep 17 00:00:00 2001 From: Natalie Chouinard Date: Thu, 28 Sep 2023 15:28:33 +0000 Subject: [PATCH 5/5] Always emit SPIR-V MIR for buildConstantFP --- llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 37 +++++++------------ llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h | 2 +- .../Target/SPIRV/SPIRVInstructionSelector.cpp | 2 +- 3 files changed, 16 insertions(+), 25 deletions(-) diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp index c9adf6c86929b..dbfad5b15750a 100644 --- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp @@ -242,36 +242,27 @@ Register SPIRVGlobalRegistry::buildConstantInt(uint64_t Val, Register SPIRVGlobalRegistry::buildConstantFP(APFloat Val, MachineIRBuilder &MIRBuilder, - SPIRVType *SpvType, bool EmitIR) { + SPIRVType *SpvType) { auto &MF = MIRBuilder.getMF(); - const Type *LLVMFPTy; - if (SpvType) { - LLVMFPTy = getTypeForSPIRVType(SpvType); - assert(LLVMFPTy->isFloatingPointTy()); - } else { - LLVMFPTy = IntegerType::getFloatTy(MF.getFunction().getContext()); + auto &Ctx = MF.getFunction().getContext(); + if (!SpvType) { + const Type *LLVMFPTy = Type::getFloatTy(Ctx); + SpvType = getOrCreateSPIRVType(LLVMFPTy, MIRBuilder); } // Find a constant in DT or build a new one. - const auto ConstFP = ConstantFP::get(LLVMFPTy->getContext(), Val); + const auto ConstFP = ConstantFP::get(Ctx, Val); Register Res = DT.find(ConstFP, &MF); if (!Res.isValid()) { - unsigned BitWidth = SpvType ? getScalarOrVectorBitWidth(SpvType) : 32; - LLT LLTy = LLT::scalar(EmitIR ? BitWidth : 32); - Res = MF.getRegInfo().createGenericVirtualRegister(LLTy); + Res = MF.getRegInfo().createGenericVirtualRegister(LLT::scalar(32)); MF.getRegInfo().setRegClass(Res, &SPIRV::IDRegClass); - assignTypeToVReg(LLVMFPTy, Res, MIRBuilder, - SPIRV::AccessQualifier::ReadWrite, EmitIR); + assignSPIRVTypeToVReg(SpvType, Res, MF); DT.add(ConstFP, &MF, Res); - if (EmitIR) { - MIRBuilder.buildFConstant(Res, *ConstFP); - } else { - MachineInstrBuilder MIB; - assert(SpvType); - MIB = MIRBuilder.buildInstr(SPIRV::OpConstantF) - .addDef(Res) - .addUse(getSPIRVTypeID(SpvType)); - addNumImm(ConstFP->getValueAPF().bitcastToAPInt(), MIB); - } + + MachineInstrBuilder MIB; + MIB = MIRBuilder.buildInstr(SPIRV::OpConstantF) + .addDef(Res) + .addUse(getSPIRVTypeID(SpvType)); + addNumImm(ConstFP->getValueAPF().bitcastToAPInt(), MIB); } return Res; diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h index 304af2440f95a..88769f84b3e50 100644 --- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h +++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h @@ -234,7 +234,7 @@ class SPIRVGlobalRegistry { Register getOrCreateConstInt(uint64_t Val, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII); Register buildConstantFP(APFloat Val, MachineIRBuilder &MIRBuilder, - SPIRVType *SpvType = nullptr, bool EmitIR = true); + SPIRVType *SpvType = nullptr); Register getOrCreateConsIntVector(uint64_t Val, MachineInstr &I, SPIRVType *SpvType, const SPIRVInstrInfo &TII); diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp index d0dcc4fd4acbf..c672b88091e66 100644 --- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp @@ -1600,7 +1600,7 @@ bool SPIRVInstructionSelector::selectLog10(Register ResVReg, ? GR.getSPIRVTypeForVReg(ResType->getOperand(1).getReg()) : ResType; Register ScaleReg = - GR.buildConstantFP(APFloat(0.30103f), MIRBuilder, SpirvScalarType, false); + GR.buildConstantFP(APFloat(0.30103f), MIRBuilder, SpirvScalarType); // Multiply log2(x) by 0.30103 to get log10(x) result. auto Opcode = ResType->getOpcode() == SPIRV::OpTypeVector