GlobalISel: Make buildConstant handle vectors

Produce a splat build_vector similar to how
SelectionDAG::getConstant does.

llvm-svn: 351880
This commit is contained in:
Matt Arsenault 2019-01-22 21:31:02 +00:00
parent fea3731f37
commit 52133812f6
5 changed files with 85 additions and 11 deletions

View File

@ -103,6 +103,10 @@ public:
return getScalarSizeInBits() * getNumElements(); return getScalarSizeInBits() * getNumElements();
} }
LLT getScalarType() const {
return isVector() ? getElementType() : *this;
}
unsigned getScalarSizeInBits() const { unsigned getScalarSizeInBits() const {
assert(RawData != 0 && "Invalid Type"); assert(RawData != 0 && "Invalid Type");
if (!IsVector) { if (!IsVector) {

View File

@ -242,11 +242,28 @@ MachineInstrBuilder MachineIRBuilder::buildCopy(const DstOp &Res,
MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res, MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res,
const ConstantInt &Val) { const ConstantInt &Val) {
LLT Ty = Res.getLLTTy(*getMRI()); LLT Ty = Res.getLLTTy(*getMRI());
LLT EltTy = Ty.getScalarType();
const ConstantInt *NewVal = &Val; const ConstantInt *NewVal = &Val;
if (Ty.getScalarSizeInBits() != Val.getBitWidth()) if (EltTy.getSizeInBits() != Val.getBitWidth()) {
NewVal = ConstantInt::get(getMF().getFunction().getContext(), NewVal = ConstantInt::get(
Val.getValue().sextOrTrunc(Ty.getSizeInBits())); 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); auto MIB = buildInstr(TargetOpcode::G_CONSTANT);
Res.addDefToMIB(*getMRI(), MIB); Res.addDefToMIB(*getMRI(), MIB);
@ -264,7 +281,24 @@ MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res,
MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res, MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res,
const ConstantFP &Val) { 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); auto MIB = buildInstr(TargetOpcode::G_FCONSTANT);
Res.addDefToMIB(*getMRI(), MIB); Res.addDefToMIB(*getMRI(), MIB);

View File

@ -10,8 +10,9 @@ set(LLVM_LINK_COMPONENTS
) )
add_llvm_unittest(GlobalISelTests add_llvm_unittest(GlobalISelTests
LegalizerInfoTest.cpp CSETest.cpp
PatternMatchTest.cpp LegalizerHelperTest.cpp
LegalizerHelperTest.cpp LegalizerInfoTest.cpp
CSETest.cpp MachineIRBuilderTest.cpp
) PatternMatchTest.cpp
)

View File

@ -1,5 +1,4 @@
//===- GISelMITest.h //===- GISelMITest.h --------------------------------------------*- C++ -*-===//
//-----------------------------------------------===//
// //
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information. // See https://llvm.org/LICENSE.txt for license information.

View File

@ -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));
}