Repository: llvm/llvm-project
File: llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp (C++)

Code before:
    /// There is no exp10 in GLSL. Use exp10(x) = exp2(x * log2(10)) instead
    /// log2(10) ~= 3.3219280948874

    if (ResType->getOpcode() != SPIRV::OpTypeVector &&
        ResType->getOpcode() != SPIRV::OpTypeFloat)
      return false;

    MachineIRBuilder MIRBuilder(I);

    SPIRVTypeInst SpirvScalarType = ResType->getOpcode() == SPIRV::OpTypeVector
                                        ? SPIRVTypeInst(GR.getSPIRVTypeForVReg(
                                              ResType->getOperand(1).getReg()))
                                        : ResType;

    Register ConstReg = GR.buildConstantFP(APFloat(3.3219280948874f),
                                           MIRBuilder, SpirvScalarType);
    Register ArgReg = MRI->createVirtualRegister(GR.getRegClass(ResType));
    auto Opcode = ResType->getOpcode() == SPIRV::OpTypeVector
                      ? SPIRV::OpVectorTimesScalar
                      : SPIRV::OpFMulS;

    if (!selectOpWithSrcs(ArgReg, ResType, I,
                          {ConstReg, I.getOperand(1).getReg()}, Opcode))
      return false;
    return selectExtInstWithSrcs(
        ResVReg, ResType, I, std::vector<Register>({ArgReg}),
        {{SPIRV::InstructionSet::GLSL_std_450, GL::Exp2}});
  }

  return false;
}

Register SPIRVInstructionSelector::buildZerosVal(SPIRVTypeInst ResType,
                                                 MachineInstr &I) const {
  // OpenCL uses nulls for Zero. In HLSL we don't use null constants.
  bool ZeroAsNull = !STI.isShader();
  if (ResType->getOpcode() == SPIRV::OpTypeVector)
    return GR.getOrCreateConstVector(0UL, I, ResType, TII, ZeroAsNull);
  return GR.getOrCreateConstInt(0, I, ResType, TII, ZeroAsNull);
}

bool SPIRVInstructionSelector::isScalarOrVectorIntConstantZero(
    Register Reg) const {
  SPIRVTypeInst Type = GR.getSPIRVTypeForVReg(Reg);
  if (!Type)
    return false;
  SPIRVTypeInst CompType = GR.getScalarOrVectorComponentType(Type);
  if (!CompType || CompType->getOpcode() != SPIRV::OpTypeInt)
    return false;

  auto IsZero = [this](Register Reg) {

Review comment (suggestion):
I think you can remove the `std::vector` since it's now an `ArrayRef`

Code after:
  // OpenCL uses nulls for Zero. In HLSL we don't use null constants.
  bool ZeroAsNull = !STI.isShader();
  if (ResType->getOpcode() == SPIRV::OpTypeVector)
    return GR.getOrCreateConstVector(0UL, I, ResType, TII, ZeroAsNull);
  return GR.getOrCreateConstInt(0, I, ResType, TII, ZeroAsNull);
}

bool SPIRVInstructionSelector::isScalarOrVectorIntConstantZero(
    Register Reg) const {
  SPIRVTypeInst Type = GR.getSPIRVTypeForVReg(Reg);
  if (!Type)
    return false;
  SPIRVTypeInst CompType = GR.getScalarOrVectorComponentType(Type);
  if (!CompType || CompType->getOpcode() != SPIRV::OpTypeInt)
    return false;

  auto IsZero = [this](Register Reg) {
    MachineInstr *Def = getDefInstrMaybeConstant(Reg, MRI);
    if (!Def)
      return false;

    if (Def->getOpcode() == SPIRV::OpConstantNull)
      return true;

    if (Def->getOpcode() == TargetOpcode::G_CONSTANT ||
        Def->getOpcode() == SPIRV::OpConstantI)
      return getIConstVal(Reg, MRI) == 0;

    return false;
  };

  if (IsZero(Reg))
    return true;

  MachineInstr *Def = MRI->getVRegDef(Reg);
  if (!Def)
    return false;

  if (Def->getOpcode() == TargetOpcode::G_BUILD_VECTOR ||
      (Def->getOpcode() == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS &&
       cast<GIntrinsic>(Def)->getIntrinsicID() ==
           Intrinsic::spv_const_composite)) {
    unsigned StartOp = Def->getOpcode() == TargetOpcode::G_BUILD_VECTOR ? 1 : 2;
    for (unsigned i = StartOp; i < Def->getNumOperands(); ++i) {
      if (!IsZero(Def->getOperand(i).getReg()))
        return false;
    }
    return true;
  }

  return false;