summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp2
-rw-r--r--llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp4
-rw-r--r--llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp37
-rw-r--r--llvm/lib/Target/AArch64/AArch64CallLowering.cpp45
-rw-r--r--llvm/lib/Target/AArch64/AArch64CallLowering.h3
-rw-r--r--llvm/lib/Target/ARM/ARMCallLowering.cpp4
-rw-r--r--llvm/lib/Target/ARM/ARMInstructionSelector.cpp20
-rw-r--r--llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp6
-rw-r--r--llvm/lib/Target/X86/X86CallLowering.cpp25
-rw-r--r--llvm/lib/Target/X86/X86CallLowering.h3
10 files changed, 73 insertions, 76 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 6c403a8212a..0470b3af7f5 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -341,7 +341,7 @@ bool IRTranslator::translateExtractValue(const User &U,
uint64_t Offset = 8 * DL->getIndexedOffsetInType(Src->getType(), Indices);
unsigned Res = getOrCreateVReg(U);
- MIRBuilder.buildExtract(Res, Offset, getOrCreateVReg(*Src));
+ MIRBuilder.buildExtract(Res, getOrCreateVReg(*Src), Offset);
return true;
}
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index a8bc694dc17..d1f31607401 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -202,8 +202,8 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
if (OpSegSize != OpSize) {
// A genuine extract is needed.
OpSegReg = MRI.createGenericVirtualRegister(LLT::scalar(OpSegSize));
- MIRBuilder.buildExtract(OpSegReg, std::max(OpSegStart, (int64_t)0),
- OpReg);
+ MIRBuilder.buildExtract(OpSegReg, OpReg,
+ std::max(OpSegStart, (int64_t)0));
}
unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 1b7c7a6e52b..3614333037c 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -382,34 +382,25 @@ MachineInstrBuilder MachineIRBuilder::buildCast(unsigned Dst, unsigned Src) {
return buildInstr(Opcode).addDef(Dst).addUse(Src);
}
-MachineInstrBuilder MachineIRBuilder::buildExtract(ArrayRef<unsigned> Results,
- ArrayRef<uint64_t> Indices,
- unsigned Src) {
+MachineInstrBuilder MachineIRBuilder::buildExtract(unsigned Res, unsigned Src,
+ uint64_t Index) {
#ifndef NDEBUG
- assert(Results.size() == Indices.size() && "inconsistent number of regs");
- assert(!Results.empty() && "invalid trivial extract");
- assert(std::is_sorted(Indices.begin(), Indices.end()) &&
- "extract offsets must be in ascending order");
-
assert(MRI->getType(Src).isValid() && "invalid operand type");
- for (auto Res : Results)
- assert(MRI->getType(Res).isValid() && "invalid operand type");
+ assert(MRI->getType(Res).isValid() && "invalid operand type");
+ assert(Index + MRI->getType(Res).getSizeInBits() <=
+ MRI->getType(Src).getSizeInBits() &&
+ "extracting off end of register");
#endif
- auto MIB = BuildMI(getMF(), DL, getTII().get(TargetOpcode::G_EXTRACT));
- for (auto Res : Results)
- MIB.addDef(Res);
-
- MIB.addUse(Src);
-
- for (auto Idx : Indices)
- MIB.addImm(Idx);
-
- getMBB().insert(getInsertPt(), MIB);
- if (InsertedInstr)
- InsertedInstr(MIB);
+ if (MRI->getType(Res).getSizeInBits() == MRI->getType(Src).getSizeInBits()) {
+ assert(Index == 0 && "insertion past the end of a register");
+ return buildCast(Res, Src);
+ }
- return MIB;
+ return buildInstr(TargetOpcode::G_EXTRACT)
+ .addDef(Res)
+ .addUse(Src)
+ .addImm(Index);
}
MachineInstrBuilder
diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
index b1b98708753..4ccd6b68397 100644
--- a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
@@ -200,15 +200,8 @@ void AArch64CallLowering::splitToValueTypes(
OrigArg.Flags, OrigArg.IsFixed});
}
- SmallVector<uint64_t, 4> BitOffsets;
- for (auto Offset : Offsets)
- BitOffsets.push_back(Offset * 8);
-
- SmallVector<unsigned, 8> SplitRegs;
- for (auto I = &SplitArgs[FirstRegIdx]; I != SplitArgs.end(); ++I)
- SplitRegs.push_back(I->Reg);
-
- PerformArgSplit(SplitRegs, BitOffsets);
+ for (unsigned i = 0; i < Offsets.size(); ++i)
+ PerformArgSplit(SplitArgs[FirstRegIdx + i].Reg, Offsets[i] * 8);
}
bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
@@ -230,8 +223,8 @@ bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
SmallVector<ArgInfo, 8> SplitArgs;
splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
- [&](ArrayRef<unsigned> Regs, ArrayRef<uint64_t> Offsets) {
- MIRBuilder.buildExtract(Regs, Offsets, VReg);
+ [&](unsigned Reg, uint64_t Offset) {
+ MIRBuilder.buildExtract(Reg, VReg, Offset);
});
OutgoingArgHandler Handler(MIRBuilder, MRI, MIB, AssignFn, AssignFn);
@@ -256,10 +249,24 @@ bool AArch64CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
for (auto &Arg : Args) {
ArgInfo OrigArg{VRegs[i], Arg.getType()};
setArgFlags(OrigArg, i + 1, DL, F);
+ bool Split = false;
+ LLT Ty = MRI.getType(VRegs[i]);
+ unsigned Dst = VRegs[i];
+
splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
- [&](ArrayRef<unsigned> Regs, ArrayRef<uint64_t> Offsets) {
- MIRBuilder.buildSequence(VRegs[i], Regs, Offsets);
+ [&](unsigned Reg, uint64_t Offset) {
+ if (!Split) {
+ Split = true;
+ Dst = MRI.createGenericVirtualRegister(Ty);
+ MIRBuilder.buildUndef(Dst);
+ }
+ unsigned Tmp = MRI.createGenericVirtualRegister(Ty);
+ MIRBuilder.buildInsert(Tmp, Dst, Reg, Offset);
+ Dst = Tmp;
});
+
+ if (Dst != VRegs[i])
+ MIRBuilder.buildCopy(VRegs[i], Dst);
++i;
}
@@ -307,8 +314,8 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
SmallVector<ArgInfo, 8> SplitArgs;
for (auto &OrigArg : OrigArgs) {
splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
- [&](ArrayRef<unsigned> Regs, ArrayRef<uint64_t> Offsets) {
- MIRBuilder.buildExtract(Regs, Offsets, OrigArg.Reg);
+ [&](unsigned Reg, uint64_t Offset) {
+ MIRBuilder.buildExtract(Reg, OrigArg.Reg, Offset);
});
}
@@ -360,11 +367,9 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
SmallVector<uint64_t, 8> RegOffsets;
SmallVector<unsigned, 8> SplitRegs;
splitToValueTypes(OrigRet, SplitArgs, DL, MRI,
- [&](ArrayRef<unsigned> Regs, ArrayRef<uint64_t> Offsets) {
- std::copy(Offsets.begin(), Offsets.end(),
- std::back_inserter(RegOffsets));
- std::copy(Regs.begin(), Regs.end(),
- std::back_inserter(SplitRegs));
+ [&](unsigned Reg, uint64_t Offset) {
+ RegOffsets.push_back(Offset);
+ SplitRegs.push_back(Reg);
});
CallReturnHandler Handler(MIRBuilder, MRI, MIB, RetAssignFn);
diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.h b/llvm/lib/Target/AArch64/AArch64CallLowering.h
index 23c529ac139..ec4a1e7adc0 100644
--- a/llvm/lib/Target/AArch64/AArch64CallLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64CallLowering.h
@@ -46,8 +46,7 @@ private:
typedef std::function<void(MachineIRBuilder &, int, CCValAssign &)>
MemHandler;
- typedef std::function<void(ArrayRef<unsigned>, ArrayRef<uint64_t>)>
- SplitArgTy;
+ typedef std::function<void(unsigned, uint64_t)> SplitArgTy;
void splitToValueTypes(const ArgInfo &OrigArgInfo,
SmallVectorImpl<ArgInfo> &SplitArgs,
diff --git a/llvm/lib/Target/ARM/ARMCallLowering.cpp b/llvm/lib/Target/ARM/ARMCallLowering.cpp
index e034abe4222..01239e8a74c 100644
--- a/llvm/lib/Target/ARM/ARMCallLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMCallLowering.cpp
@@ -118,8 +118,8 @@ struct OutgoingValueHandler : public CallLowering::ValueHandler {
unsigned NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)),
MRI.createGenericVirtualRegister(LLT::scalar(32))};
-
- MIRBuilder.buildExtract(NewRegs, {0, 32}, Arg.Reg);
+ MIRBuilder.buildExtract(NewRegs[0], Arg.Reg, 0);
+ MIRBuilder.buildExtract(NewRegs[1], Arg.Reg, 32);
bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
if (!IsLittle)
diff --git a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
index d7e5220f924..8d224d6a70f 100644
--- a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
+++ b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
@@ -148,23 +148,19 @@ static bool selectExtract(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII,
(void)VReg0;
assert(MRI.getType(VReg0).getSizeInBits() == 32 &&
RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::GPRRegBankID &&
- "Unsupported operand for G_SEQUENCE");
+ "Unsupported operand for G_EXTRACT");
unsigned VReg1 = MIB->getOperand(1).getReg();
(void)VReg1;
- assert(MRI.getType(VReg1).getSizeInBits() == 32 &&
- RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID &&
- "Unsupported operand for G_SEQUENCE");
- unsigned VReg2 = MIB->getOperand(2).getReg();
- (void)VReg2;
- assert(MRI.getType(VReg2).getSizeInBits() == 64 &&
- RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::FPRRegBankID &&
- "Unsupported operand for G_SEQUENCE");
+ assert(MRI.getType(VReg1).getSizeInBits() == 64 &&
+ RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::FPRRegBankID &&
+ "Unsupported operand for G_EXTRACT");
+ assert(MIB->getOperand(2).getImm() % 32 == 0 &&
+ "Unsupported operand for G_EXTRACT");
// Remove the operands corresponding to the offsets.
- MIB->RemoveOperand(4);
- MIB->RemoveOperand(3);
+ MIB->getOperand(2).setImm(MIB->getOperand(2).getImm() / 32);
- MIB->setDesc(TII.get(ARM::VMOVRRD));
+ MIB->setDesc(TII.get(ARM::VGETLNi32));
MIB.add(predOps(ARMCC::AL));
return true;
diff --git a/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp b/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp
index 18ce7d454b8..8eb13235de1 100644
--- a/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp
@@ -263,12 +263,10 @@ ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
// We only support G_EXTRACT for splitting a double precision floating point
// value into two GPRs.
LLT Ty1 = MRI.getType(MI.getOperand(1).getReg());
- LLT Ty2 = MRI.getType(MI.getOperand(2).getReg());
- if (Ty.getSizeInBits() != 32 || Ty1.getSizeInBits() != 32 ||
- Ty2.getSizeInBits() != 64)
+ if (Ty.getSizeInBits() != 32 || Ty1.getSizeInBits() != 64 ||
+ MI.getOperand(2).getImm() % 32 != 0)
return InstructionMapping{};
OperandsMapping = getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx],
- &ARM::ValueMappings[ARM::GPR3OpsIdx],
&ARM::ValueMappings[ARM::DPR3OpsIdx],
nullptr, nullptr});
break;
diff --git a/llvm/lib/Target/X86/X86CallLowering.cpp b/llvm/lib/Target/X86/X86CallLowering.cpp
index 39c7e514791..dbb74249634 100644
--- a/llvm/lib/Target/X86/X86CallLowering.cpp
+++ b/llvm/lib/Target/X86/X86CallLowering.cpp
@@ -61,11 +61,8 @@ void X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg,
ArgInfo Info = ArgInfo{MRI.createGenericVirtualRegister(LLT{*PartTy, DL}),
PartTy, OrigArg.Flags};
SplitArgs.push_back(Info);
- BitOffsets.push_back(PartVT.getSizeInBits() * i);
- SplitRegs.push_back(Info.Reg);
+ PerformArgSplit(Info.Reg, PartVT.getSizeInBits() * i);
}
-
- PerformArgSplit(SplitRegs, BitOffsets);
}
namespace {
@@ -113,8 +110,8 @@ bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
SmallVector<ArgInfo, 8> SplitArgs;
splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
- [&](ArrayRef<unsigned> Regs, ArrayRef<uint64_t> Offsets) {
- MIRBuilder.buildExtract(Regs, Offsets, VReg);
+ [&](unsigned Reg, uint64_t Offset) {
+ MIRBuilder.buildExtract(Reg, VReg, Offset);
});
FuncReturnHandler Handler(MIRBuilder, MRI, MIB, RetCC_X86);
@@ -184,10 +181,22 @@ bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
for (auto &Arg : F.getArgumentList()) {
ArgInfo OrigArg(VRegs[Idx], Arg.getType());
setArgFlags(OrigArg, Idx + 1, DL, F);
+ LLT Ty = MRI.getType(VRegs[Idx]);
+ unsigned Dst = VRegs[Idx];
+ bool Split = false;
splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
- [&](ArrayRef<unsigned> Regs, ArrayRef<uint64_t> Offsets) {
- MIRBuilder.buildSequence(VRegs[Idx], Regs, Offsets);
+ [&](unsigned Reg, uint64_t Offset) {
+ if (!Split) {
+ Split = true;
+ Dst = MRI.createGenericVirtualRegister(Ty);
+ MIRBuilder.buildUndef(Dst);
+ }
+ unsigned Tmp = MRI.createGenericVirtualRegister(Ty);
+ MIRBuilder.buildInsert(Tmp, Dst, Reg, Offset);
+ Dst = Tmp;
});
+ if (Dst != VRegs[Idx])
+ MIRBuilder.buildCopy(VRegs[Idx], Dst);
Idx++;
}
diff --git a/llvm/lib/Target/X86/X86CallLowering.h b/llvm/lib/Target/X86/X86CallLowering.h
index 90da6c3d98f..204e6974c70 100644
--- a/llvm/lib/Target/X86/X86CallLowering.h
+++ b/llvm/lib/Target/X86/X86CallLowering.h
@@ -36,8 +36,7 @@ public:
ArrayRef<unsigned> VRegs) const override;
private:
/// A function of this type is used to perform value split action.
- typedef std::function<void(ArrayRef<unsigned>, ArrayRef<uint64_t>)>
- SplitArgTy;
+ typedef std::function<void(unsigned, uint64_t)> SplitArgTy;
void splitToValueTypes(const ArgInfo &OrigArgInfo,
SmallVectorImpl<ArgInfo> &SplitArgs,
OpenPOWER on IntegriCloud