From: Matt Arsenault Date: Tue, 22 Jan 2019 21:31:02 +0000 (+0000) Subject: GlobalISel: Make buildConstant handle vectors X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6633705a455580de00e0deb0dae630a9373004c9;p=llvm GlobalISel: Make buildConstant handle vectors Produce a splat build_vector similar to how SelectionDAG::getConstant does. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351880 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Support/LowLevelTypeImpl.h b/include/llvm/Support/LowLevelTypeImpl.h index da411714da0..cfa830cd6a3 100644 --- a/include/llvm/Support/LowLevelTypeImpl.h +++ b/include/llvm/Support/LowLevelTypeImpl.h @@ -103,6 +103,10 @@ public: return getScalarSizeInBits() * getNumElements(); } + LLT getScalarType() const { + return isVector() ? getElementType() : *this; + } + unsigned getScalarSizeInBits() const { assert(RawData != 0 && "Invalid Type"); if (!IsVector) { diff --git a/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp index 6248a49317c..99e768e8ed2 100644 --- a/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -242,11 +242,28 @@ MachineInstrBuilder MachineIRBuilder::buildCopy(const DstOp &Res, 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::buildConstant(const DstOp &Res, 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); diff --git a/unittests/CodeGen/GlobalISel/CMakeLists.txt b/unittests/CodeGen/GlobalISel/CMakeLists.txt index 32bbd561ff8..3778ff47d0d 100644 --- a/unittests/CodeGen/GlobalISel/CMakeLists.txt +++ b/unittests/CodeGen/GlobalISel/CMakeLists.txt @@ -10,8 +10,9 @@ set(LLVM_LINK_COMPONENTS ) add_llvm_unittest(GlobalISelTests - LegalizerInfoTest.cpp - PatternMatchTest.cpp - LegalizerHelperTest.cpp - CSETest.cpp - ) + CSETest.cpp + LegalizerHelperTest.cpp + LegalizerInfoTest.cpp + MachineIRBuilderTest.cpp + PatternMatchTest.cpp + ) diff --git a/unittests/CodeGen/GlobalISel/GISelMITest.h b/unittests/CodeGen/GlobalISel/GISelMITest.h index 709e373e9ff..33621cf2935 100644 --- a/unittests/CodeGen/GlobalISel/GISelMITest.h +++ b/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. diff --git a/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp b/unittests/CodeGen/GlobalISel/MachineIRBuilderTest.cpp new file mode 100644 index 00000000000..dae67f7a061 --- /dev/null +++ b/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)); +}