Index: include/llvm/Support/LowLevelTypeImpl.h =================================================================== --- include/llvm/Support/LowLevelTypeImpl.h +++ include/llvm/Support/LowLevelTypeImpl.h @@ -103,6 +103,10 @@ return getScalarSizeInBits() * getNumElements(); } + LLT getScalarType() const { + return isVector() ? getElementType() : *this; + } + unsigned getScalarSizeInBits() const { assert(RawData != 0 && "Invalid Type"); if (!IsVector) { Index: lib/CodeGen/GlobalISel/MachineIRBuilder.cpp =================================================================== --- lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -242,11 +242,28 @@ MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res, const ConstantInt &Val) { LLT Ty = Res.getLLTTy(*getMRI()); + LLT EltTy = Ty.getScalarType(); const ConstantInt *NewVal = &Val; - if (Ty.getScalarSizeInBits() != Val.getBitWidth()) - NewVal = ConstantInt::get(getMF().getFunction().getContext(), - Val.getValue().sextOrTrunc(Ty.getSizeInBits())); + if (EltTy.getSizeInBits() != Val.getBitWidth()) { + NewVal = ConstantInt::get( + getMF().getFunction().getContext(), + Val.getValue().sextOrTrunc(EltTy.getSizeInBits())); + } + + if (Ty.isVector()) { + unsigned EltReg = getMRI()->createGenericVirtualRegister(EltTy); + buildInstr(TargetOpcode::G_CONSTANT) + .addDef(EltReg) + .addCImm(NewVal); + + auto MIB = buildInstr(TargetOpcode::G_BUILD_VECTOR); + Res.addDefToMIB(*getMRI(), MIB); + + for (unsigned I = 0, E = Ty.getNumElements(); I != E; ++I) + MIB.addUse(EltReg); + return MIB; + } auto MIB = buildInstr(TargetOpcode::G_CONSTANT); Res.addDefToMIB(*getMRI(), MIB); @@ -264,7 +281,24 @@ MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res, const ConstantFP &Val) { - assert(!Res.getLLTTy(*getMRI()).isPointer() && "invalid operand type"); + LLT Ty = Res.getLLTTy(*getMRI()); + + assert(!Ty.isPointer() && "invalid operand type"); + + if (Ty.isVector()) { + unsigned EltReg + = getMRI()->createGenericVirtualRegister(Ty.getElementType()); + buildInstr(TargetOpcode::G_FCONSTANT) + .addDef(EltReg) + .addFPImm(&Val); + + auto MIB = buildInstr(TargetOpcode::G_BUILD_VECTOR); + Res.addDefToMIB(*getMRI(), MIB); + + for (unsigned I = 0, E = Ty.getNumElements(); I != E; ++I) + MIB.addUse(EltReg); + return MIB; + } auto MIB = buildInstr(TargetOpcode::G_FCONSTANT); Res.addDefToMIB(*getMRI(), MIB); Index: unittests/CodeGen/GlobalISel/CMakeLists.txt =================================================================== --- unittests/CodeGen/GlobalISel/CMakeLists.txt +++ unittests/CodeGen/GlobalISel/CMakeLists.txt @@ -10,8 +10,9 @@ ) add_llvm_unittest(GlobalISelTests - LegalizerInfoTest.cpp - PatternMatchTest.cpp - LegalizerHelperTest.cpp - CSETest.cpp - ) + CSETest.cpp + LegalizerHelperTest.cpp + LegalizerInfoTest.cpp + MachineIRBuilderTest.cpp + PatternMatchTest.cpp + ) Index: unittests/CodeGen/GlobalISel/GISelMITest.h =================================================================== --- unittests/CodeGen/GlobalISel/GISelMITest.h +++ unittests/CodeGen/GlobalISel/GISelMITest.h @@ -1,5 +1,4 @@ -//===- GISelMITest.h -//-----------------------------------------------===// +//===- GISelMITest.h --------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. Index: unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp =================================================================== --- /dev/null +++ unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp @@ -0,0 +1,36 @@ +//===- MachineIRBuilderTest.cpp -------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "GISelMITest.h" +#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" + +TEST_F(GISelMITest, TestBuildConstantFConstant) { + if (!TM) + return; + + MachineIRBuilder B(*MF); + B.setInsertPt(*EntryMBB, EntryMBB->begin()); + + B.buildConstant(LLT::scalar(32), 42); + B.buildFConstant(LLT::scalar(32), 1.0); + + B.buildConstant(LLT::vector(2, 32), 99); + B.buildFConstant(LLT::vector(2, 32), 2.0); + + auto CheckStr = R"( + CHECK: [[CONST0:%[0-9]+]]:_(s32) = G_CONSTANT i32 42 + CHECK: [[FCONST0:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.000000e+00 + CHECK: [[CONST1:%[0-9]+]]:_(s32) = G_CONSTANT i32 99 + CHECK: [[VEC0:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[CONST1]]:_(s32), [[CONST1]]:_(s32) + CHECK: [[FCONST1:%[0-9]+]]:_(s32) = G_FCONSTANT double 2.000000e+00 + CHECK: [[VEC1:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[FCONST1]]:_(s32), [[FCONST1]]:_(s32) + + )"; + + ASSERT_TRUE(CheckMachineFunction(*MF, CheckStr)); +}