diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2019-02-04 19:15:50 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2019-02-04 19:15:50 +0000 |
commit | 74695311606163772d4a0cf53a619171f3c7d380 (patch) | |
tree | d9fd545a44bda21c5a3dcc94ce5671ac3962c0af /lib | |
parent | 9ac1c045584659055a0307e9176008b2fcf21c83 (diff) | |
download | llvm-74695311606163772d4a0cf53a619171f3c7d380.tar.gz |
GlobalISel: Fix CSE handling of buildConstant
This fixes two problems with CSE done in buildConstant. First, this
would hit an assert when used with a vector result type. Solve this by
allowing CSE on the vector elements, but not on the result vector for
now.
Second, this was also performing the CSE based on the input
ConstantInt pointer. The underlying buildConstant could potentially
convert the constant depending on the result type, giving in a
different ConstantInt*. Stop allowing the APInt and ConstantInt forms
from automatically casting to the result type to avoid any similar
problems in the future.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353077 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/GlobalISel/CSEMIRBuilder.cpp | 13 | ||||
-rw-r--r-- | lib/CodeGen/GlobalISel/MachineIRBuilder.cpp | 78 |
2 files changed, 51 insertions, 40 deletions
diff --git a/lib/CodeGen/GlobalISel/CSEMIRBuilder.cpp b/lib/CodeGen/GlobalISel/CSEMIRBuilder.cpp index 53675e8f83e..ed2c95c22ce 100644 --- a/lib/CodeGen/GlobalISel/CSEMIRBuilder.cpp +++ b/lib/CodeGen/GlobalISel/CSEMIRBuilder.cpp @@ -194,6 +194,12 @@ MachineInstrBuilder CSEMIRBuilder::buildConstant(const DstOp &Res, constexpr unsigned Opc = TargetOpcode::G_CONSTANT; if (!canPerformCSEForOpc(Opc)) return MachineIRBuilder::buildConstant(Res, Val); + + // For vectors, CSE the element only for now. + LLT Ty = Res.getLLTTy(*getMRI()); + if (Ty.isVector()) + return buildSplatVector(Res, buildConstant(Ty.getElementType(), Val)); + FoldingSetNodeID ID; GISelInstProfileBuilder ProfBuilder(ID, *getMRI()); void *InsertPos = nullptr; @@ -205,6 +211,7 @@ MachineInstrBuilder CSEMIRBuilder::buildConstant(const DstOp &Res, // Handle generating copies here. return generateCopiesIfRequired({Res}, MIB); } + MachineInstrBuilder NewMIB = MachineIRBuilder::buildConstant(Res, Val); return memoizeMI(NewMIB, InsertPos); } @@ -214,6 +221,12 @@ MachineInstrBuilder CSEMIRBuilder::buildFConstant(const DstOp &Res, constexpr unsigned Opc = TargetOpcode::G_FCONSTANT; if (!canPerformCSEForOpc(Opc)) return MachineIRBuilder::buildFConstant(Res, Val); + + // For vectors, CSE the element only for now. + LLT Ty = Res.getLLTTy(*getMRI()); + if (Ty.isVector()) + return buildSplatVector(Res, buildFConstant(Ty.getElementType(), Val)); + FoldingSetNodeID ID; GISelInstProfileBuilder ProfBuilder(ID, *getMRI()); void *InsertPos = nullptr; diff --git a/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp index 656352d1208..8fa818afd70 100644 --- a/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -244,38 +244,26 @@ MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res, const ConstantInt &Val) { LLT Ty = Res.getLLTTy(*getMRI()); LLT EltTy = Ty.getScalarType(); - - const ConstantInt *NewVal = &Val; - if (EltTy.getSizeInBits() != Val.getBitWidth()) { - NewVal = ConstantInt::get( - getMF().getFunction().getContext(), - Val.getValue().sextOrTrunc(EltTy.getSizeInBits())); - } + assert(EltTy.getScalarSizeInBits() == Val.getBitWidth() && + "creating constant with the wrong size"); 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 Const = buildInstr(TargetOpcode::G_CONSTANT) + .addDef(getMRI()->createGenericVirtualRegister(EltTy)) + .addCImm(&Val); + return buildSplatVector(Res, Const); } - auto MIB = buildInstr(TargetOpcode::G_CONSTANT); - Res.addDefToMIB(*getMRI(), MIB); - MIB.addCImm(NewVal); - return MIB; + auto Const = buildInstr(TargetOpcode::G_CONSTANT); + Res.addDefToMIB(*getMRI(), Const); + Const.addCImm(&Val); + return Const; } MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res, int64_t Val) { auto IntN = IntegerType::get(getMF().getFunction().getContext(), - Res.getLLTTy(*getMRI()).getSizeInBits()); + Res.getLLTTy(*getMRI()).getScalarSizeInBits()); ConstantInt *CI = ConstantInt::get(IntN, Val, true); return buildConstant(Res, *CI); } @@ -283,28 +271,32 @@ MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res, MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res, const ConstantFP &Val) { LLT Ty = Res.getLLTTy(*getMRI()); + LLT EltTy = Ty.getScalarType(); + + assert(APFloat::getSizeInBits(Val.getValueAPF().getSemantics()) + == EltTy.getSizeInBits() && + "creating fconstant with the wrong size"); 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 Const = buildInstr(TargetOpcode::G_FCONSTANT) + .addDef(getMRI()->createGenericVirtualRegister(EltTy)) + .addFPImm(&Val); + + return buildSplatVector(Res, Const); } - auto MIB = buildInstr(TargetOpcode::G_FCONSTANT); - Res.addDefToMIB(*getMRI(), MIB); - MIB.addFPImm(&Val); - return MIB; + auto Const = buildInstr(TargetOpcode::G_FCONSTANT); + Res.addDefToMIB(*getMRI(), Const); + Const.addFPImm(&Val); + return Const; +} + +MachineInstrBuilder MachineIRBuilder::buildConstant(const DstOp &Res, + const APInt &Val) { + ConstantInt *CI = ConstantInt::get(getMF().getFunction().getContext(), Val); + return buildConstant(Res, *CI); } MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res, @@ -312,7 +304,7 @@ MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res, LLT DstTy = Res.getLLTTy(*getMRI()); auto &Ctx = getMF().getFunction().getContext(); auto *CFP = - ConstantFP::get(Ctx, getAPFloatFromSize(Val, DstTy.getSizeInBits())); + ConstantFP::get(Ctx, getAPFloatFromSize(Val, DstTy.getScalarSizeInBits())); return buildFConstant(Res, *CFP); } @@ -557,6 +549,12 @@ MachineInstrBuilder MachineIRBuilder::buildBuildVector(const DstOp &Res, return buildInstr(TargetOpcode::G_BUILD_VECTOR, Res, TmpVec); } +MachineInstrBuilder MachineIRBuilder::buildSplatVector(const DstOp &Res, + const SrcOp &Src) { + SmallVector<SrcOp, 8> TmpVec(Res.getLLTTy(*getMRI()).getNumElements(), Src); + return buildInstr(TargetOpcode::G_BUILD_VECTOR, Res, TmpVec); +} + MachineInstrBuilder MachineIRBuilder::buildBuildVectorTrunc(const DstOp &Res, ArrayRef<unsigned> Ops) { |