summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2016-09-21 12:57:45 +0000
committerTim Northover <tnorthover@apple.com>2016-09-21 12:57:45 +0000
commit9a46718378550a33236ba73dcf6a7df31e01c27a (patch)
treeb729c89df8292f04cfe57d64ad980f459a7a72ec /llvm/lib/CodeGen
parent862758ec14741db27ef4594b1ba26ce5825de8a6 (diff)
downloadbcm5719-llvm-9a46718378550a33236ba73dcf6a7df31e01c27a.tar.gz
bcm5719-llvm-9a46718378550a33236ba73dcf6a7df31e01c27a.zip
GlobalISel: produce correct code for signext/zeroext ABI flags.
We still don't really have an equivalent of "AssertXExt" in DAG, so we don't exploit the guarantees on the receiving side yet, but this should produce conservatively correct code on iOS ABIs. llvm-svn: 282069
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/CallLowering.cpp71
-rw-r--r--llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp7
-rw-r--r--llvm/lib/CodeGen/LowLevelType.cpp18
3 files changed, 89 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
index de63280fd71..578556cc8bb 100644
--- a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
@@ -16,18 +16,28 @@
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Target/TargetLowering.h"
using namespace llvm;
bool CallLowering::lowerCall(
MachineIRBuilder &MIRBuilder, const CallInst &CI, unsigned ResReg,
ArrayRef<unsigned> ArgRegs, std::function<unsigned()> GetCalleeReg) const {
+ auto &DL = CI.getParent()->getParent()->getParent()->getDataLayout();
+
// First step is to marshall all the function's parameters into the correct
// physregs and memory locations. Gather the sequence of argument types that
// we'll pass to the assigner function.
- SmallVector<Type *, 8> ArgTys;
- for (auto &Arg : CI.arg_operands())
- ArgTys.push_back(Arg->getType());
+ SmallVector<ArgInfo, 8> OrigArgs;
+ unsigned i = 0;
+ for (auto &Arg : CI.arg_operands()) {
+ ArgInfo OrigArg{ArgRegs[i], Arg->getType(), ISD::ArgFlagsTy{}};
+ setArgFlags(OrigArg, i + 1, DL, CI);
+ OrigArgs.push_back(OrigArg);
+ ++i;
+ }
MachineOperand Callee = MachineOperand::CreateImm(0);
if (Function *F = CI.getCalledFunction())
@@ -35,5 +45,58 @@ bool CallLowering::lowerCall(
else
Callee = MachineOperand::CreateReg(GetCalleeReg(), false);
- return lowerCall(MIRBuilder, Callee, CI.getType(), ResReg, ArgTys, ArgRegs);
+ ArgInfo OrigRet{ResReg, CI.getType(), ISD::ArgFlagsTy{}};
+ if (!OrigRet.Ty->isVoidTy())
+ setArgFlags(OrigRet, AttributeSet::ReturnIndex, DL, CI);
+
+ return lowerCall(MIRBuilder, Callee, OrigRet, OrigArgs);
}
+
+template <typename FuncInfoTy>
+void CallLowering::setArgFlags(CallLowering::ArgInfo &Arg, unsigned OpIdx,
+ const DataLayout &DL,
+ const FuncInfoTy &FuncInfo) const {
+ const AttributeSet &Attrs = FuncInfo.getAttributes();
+ if (Attrs.hasAttribute(OpIdx, Attribute::ZExt))
+ Arg.Flags.setZExt();
+ if (Attrs.hasAttribute(OpIdx, Attribute::SExt))
+ Arg.Flags.setSExt();
+ if (Attrs.hasAttribute(OpIdx, Attribute::InReg))
+ Arg.Flags.setInReg();
+ if (Attrs.hasAttribute(OpIdx, Attribute::StructRet))
+ Arg.Flags.setSRet();
+ if (Attrs.hasAttribute(OpIdx, Attribute::SwiftSelf))
+ Arg.Flags.setSwiftSelf();
+ if (Attrs.hasAttribute(OpIdx, Attribute::SwiftError))
+ Arg.Flags.setSwiftError();
+ if (Attrs.hasAttribute(OpIdx, Attribute::ByVal))
+ Arg.Flags.setByVal();
+ if (Attrs.hasAttribute(OpIdx, Attribute::InAlloca))
+ Arg.Flags.setInAlloca();
+
+ if (Arg.Flags.isByVal() || Arg.Flags.isInAlloca()) {
+ Type *ElementTy = cast<PointerType>(Arg.Ty)->getElementType();
+ Arg.Flags.setByValSize(DL.getTypeAllocSize(ElementTy));
+ // For ByVal, alignment should be passed from FE. BE will guess if
+ // this info is not there but there are cases it cannot get right.
+ unsigned FrameAlign;
+ if (FuncInfo.getParamAlignment(OpIdx))
+ FrameAlign = FuncInfo.getParamAlignment(OpIdx);
+ else
+ FrameAlign = getTLI()->getByValTypeAlignment(ElementTy, DL);
+ Arg.Flags.setByValAlign(FrameAlign);
+ }
+ if (Attrs.hasAttribute(OpIdx, Attribute::Nest))
+ Arg.Flags.setNest();
+ Arg.Flags.setOrigAlign(DL.getABITypeAlignment(Arg.Ty));
+}
+
+template void
+CallLowering::setArgFlags<Function>(CallLowering::ArgInfo &Arg, unsigned OpIdx,
+ const DataLayout &DL,
+ const Function &FuncInfo) const;
+
+template void
+CallLowering::setArgFlags<CallInst>(CallLowering::ArgInfo &Arg, unsigned OpIdx,
+ const DataLayout &DL,
+ const CallInst &FuncInfo) const;
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
index ede2bc23393..d6368b3d969 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
@@ -109,9 +109,10 @@ MachineLegalizeHelper::libcall(MachineInstr &MI) {
const char *Name =
TLI.getLibcallName(Size == 64 ? RTLIB::REM_F64 : RTLIB::REM_F32);
- CLI.lowerCall(MIRBuilder, MachineOperand::CreateES(Name), Ty,
- MI.getOperand(0).getReg(), {Ty, Ty},
- {MI.getOperand(1).getReg(), MI.getOperand(2).getReg()});
+ CLI.lowerCall(
+ MIRBuilder, MachineOperand::CreateES(Name),
+ {MI.getOperand(0).getReg(), Ty},
+ {{MI.getOperand(1).getReg(), Ty}, {MI.getOperand(2).getReg(), Ty}});
MI.eraseFromParent();
return Legalized;
}
diff --git a/llvm/lib/CodeGen/LowLevelType.cpp b/llvm/lib/CodeGen/LowLevelType.cpp
index fd235f2cfd1..d74b7306e0f 100644
--- a/llvm/lib/CodeGen/LowLevelType.cpp
+++ b/llvm/lib/CodeGen/LowLevelType.cpp
@@ -40,6 +40,24 @@ LLT::LLT(Type &Ty, const DataLayout &DL) {
}
}
+LLT::LLT(MVT VT) {
+ if (VT.isVector()) {
+ SizeInBits = VT.getVectorElementType().getSizeInBits();
+ ElementsOrAddrSpace = VT.getVectorNumElements();
+ Kind = ElementsOrAddrSpace == 1 ? Scalar : Vector;
+ } else if (VT.isValid()) {
+ // Aggregates are no different from real scalars as far as GlobalISel is
+ // concerned.
+ Kind = Scalar;
+ SizeInBits = VT.getSizeInBits();
+ ElementsOrAddrSpace = 1;
+ assert(SizeInBits != 0 && "invalid zero-sized type");
+ } else {
+ Kind = Invalid;
+ SizeInBits = ElementsOrAddrSpace = 0;
+ }
+}
+
void LLT::print(raw_ostream &OS) const {
if (isVector())
OS << "<" << ElementsOrAddrSpace << " x s" << SizeInBits << ">";
OpenPOWER on IntegriCloud