aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp81
1 files changed, 44 insertions, 37 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
index 9cf5b257a00a..b4b389a7b956 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
@@ -734,8 +734,8 @@ void HexagonDAGToDAGISel::SelectFrameIndex(SDNode *N) {
MachineFrameInfo &MFI = MF->getFrameInfo();
const HexagonFrameLowering *HFI = HST->getFrameLowering();
int FX = cast<FrameIndexSDNode>(N)->getIndex();
- unsigned StkA = HFI->getStackAlignment();
- unsigned MaxA = MFI.getMaxAlignment();
+ Align StkA = HFI->getStackAlign();
+ Align MaxA = MFI.getMaxAlign();
SDValue FI = CurDAG->getTargetFrameIndex(FX, MVT::i32);
SDLoc DL(N);
SDValue Zero = CurDAG->getTargetConstant(0, DL, MVT::i32);
@@ -787,10 +787,18 @@ void HexagonDAGToDAGISel::SelectVAlign(SDNode *N) {
MVT::i64, Ops);
// Shift right by "(Addr & 0x3) * 8" bytes.
+ SDNode *C;
SDValue M0 = CurDAG->getTargetConstant(0x18, dl, MVT::i32);
SDValue M1 = CurDAG->getTargetConstant(0x03, dl, MVT::i32);
- SDNode *C = CurDAG->getMachineNode(Hexagon::S4_andi_asl_ri, dl, MVT::i32,
- M0, N->getOperand(2), M1);
+ if (HST->useCompound()) {
+ C = CurDAG->getMachineNode(Hexagon::S4_andi_asl_ri, dl, MVT::i32,
+ M0, N->getOperand(2), M1);
+ } else {
+ SDNode *T = CurDAG->getMachineNode(Hexagon::S2_asl_i_r, dl, MVT::i32,
+ N->getOperand(2), M1);
+ C = CurDAG->getMachineNode(Hexagon::A2_andir, dl, MVT::i32,
+ SDValue(T, 0), M0);
+ }
SDNode *S = CurDAG->getMachineNode(Hexagon::S2_lsr_r_p, dl, MVT::i64,
SDValue(R, 0), SDValue(C, 0));
SDValue E = CurDAG->getTargetExtractSubreg(Hexagon::isub_lo, dl, ResTy,
@@ -1179,7 +1187,7 @@ void HexagonDAGToDAGISel::ppHoistZextI1(std::vector<SDNode*> &&Nodes) {
Ops[i] = U->getOperand(i);
EVT BVT = Ops[I1N].getValueType();
- SDLoc dl(U);
+ const SDLoc &dl(U);
SDValue C0 = DAG.getConstant(0, dl, BVT);
SDValue C1 = DAG.getConstant(1, dl, BVT);
SDValue If0, If1;
@@ -1197,8 +1205,15 @@ void HexagonDAGToDAGISel::ppHoistZextI1(std::vector<SDNode*> &&Nodes) {
Ops[I1N] = C1;
If1 = DAG.getNode(UseOpc, dl, UVT, Ops);
}
- SDValue Sel = DAG.getNode(ISD::SELECT, dl, UVT, OpI1, If1, If0);
- DAG.ReplaceAllUsesWith(U, Sel.getNode());
+ // We're generating a SELECT way after legalization, so keep the types
+ // simple.
+ unsigned UW = UVT.getSizeInBits();
+ EVT SVT = (UW == 32 || UW == 64) ? MVT::getIntegerVT(UW) : UVT;
+ SDValue Sel = DAG.getNode(ISD::SELECT, dl, SVT, OpI1,
+ DAG.getBitcast(SVT, If1),
+ DAG.getBitcast(SVT, If0));
+ SDValue Ret = DAG.getBitcast(UVT, Sel);
+ DAG.ReplaceAllUsesWith(U, Ret.getNode());
}
}
}
@@ -1260,7 +1275,7 @@ void HexagonDAGToDAGISel::PreprocessISelDAG() {
}
}
-void HexagonDAGToDAGISel::EmitFunctionEntryCode() {
+void HexagonDAGToDAGISel::emitFunctionEntryCode() {
auto &HST = MF->getSubtarget<HexagonSubtarget>();
auto &HFI = *HST.getFrameLowering();
if (!HFI.needsAligna(*MF))
@@ -1269,9 +1284,9 @@ void HexagonDAGToDAGISel::EmitFunctionEntryCode() {
MachineFrameInfo &MFI = MF->getFrameInfo();
MachineBasicBlock *EntryBB = &MF->front();
unsigned AR = FuncInfo->CreateReg(MVT::i32);
- unsigned EntryMaxA = MFI.getMaxAlignment();
+ Align EntryMaxA = MFI.getMaxAlign();
BuildMI(EntryBB, DebugLoc(), HII->get(Hexagon::PS_aligna), AR)
- .addImm(EntryMaxA);
+ .addImm(EntryMaxA.value());
MF->getInfo<HexagonMachineFunctionInfo>()->setStackAlignBaseVReg(AR);
}
@@ -1281,7 +1296,7 @@ void HexagonDAGToDAGISel::updateAligna() {
return;
auto *AlignaI = const_cast<MachineInstr*>(HFI.getAlignaInstr(*MF));
assert(AlignaI != nullptr);
- unsigned MaxA = MF->getFrameInfo().getMaxAlignment();
+ unsigned MaxA = MF->getFrameInfo().getMaxAlign().value();
if (AlignaI->getOperand(1).getImm() < MaxA)
AlignaI->getOperand(1).setImm(MaxA);
}
@@ -1300,28 +1315,28 @@ bool HexagonDAGToDAGISel::SelectAddrFI(SDValue &N, SDValue &R) {
}
inline bool HexagonDAGToDAGISel::SelectAddrGA(SDValue &N, SDValue &R) {
- return SelectGlobalAddress(N, R, false, 0);
+ return SelectGlobalAddress(N, R, false, Align(1));
}
inline bool HexagonDAGToDAGISel::SelectAddrGP(SDValue &N, SDValue &R) {
- return SelectGlobalAddress(N, R, true, 0);
+ return SelectGlobalAddress(N, R, true, Align(1));
}
inline bool HexagonDAGToDAGISel::SelectAnyImm(SDValue &N, SDValue &R) {
- return SelectAnyImmediate(N, R, 0);
+ return SelectAnyImmediate(N, R, Align(1));
}
inline bool HexagonDAGToDAGISel::SelectAnyImm0(SDValue &N, SDValue &R) {
- return SelectAnyImmediate(N, R, 0);
+ return SelectAnyImmediate(N, R, Align(1));
}
inline bool HexagonDAGToDAGISel::SelectAnyImm1(SDValue &N, SDValue &R) {
- return SelectAnyImmediate(N, R, 1);
+ return SelectAnyImmediate(N, R, Align(2));
}
inline bool HexagonDAGToDAGISel::SelectAnyImm2(SDValue &N, SDValue &R) {
- return SelectAnyImmediate(N, R, 2);
+ return SelectAnyImmediate(N, R, Align(4));
}
inline bool HexagonDAGToDAGISel::SelectAnyImm3(SDValue &N, SDValue &R) {
- return SelectAnyImmediate(N, R, 3);
+ return SelectAnyImmediate(N, R, Align(8));
}
inline bool HexagonDAGToDAGISel::SelectAnyInt(SDValue &N, SDValue &R) {
@@ -1333,17 +1348,13 @@ inline bool HexagonDAGToDAGISel::SelectAnyInt(SDValue &N, SDValue &R) {
}
bool HexagonDAGToDAGISel::SelectAnyImmediate(SDValue &N, SDValue &R,
- uint32_t LogAlign) {
- auto IsAligned = [LogAlign] (uint64_t V) -> bool {
- return alignTo(V, (uint64_t)1 << LogAlign) == V;
- };
-
+ Align Alignment) {
switch (N.getOpcode()) {
case ISD::Constant: {
if (N.getValueType() != MVT::i32)
return false;
int32_t V = cast<const ConstantSDNode>(N)->getZExtValue();
- if (!IsAligned(V))
+ if (!isAligned(Alignment, V))
return false;
R = CurDAG->getTargetConstant(V, SDLoc(N), N.getValueType());
return true;
@@ -1351,37 +1362,34 @@ bool HexagonDAGToDAGISel::SelectAnyImmediate(SDValue &N, SDValue &R,
case HexagonISD::JT:
case HexagonISD::CP:
// These are assumed to always be aligned at least 8-byte boundary.
- if (LogAlign > 3)
+ if (Alignment > Align(8))
return false;
R = N.getOperand(0);
return true;
case ISD::ExternalSymbol:
// Symbols may be aligned at any boundary.
- if (LogAlign > 0)
+ if (Alignment > Align(1))
return false;
R = N;
return true;
case ISD::BlockAddress:
// Block address is always aligned at least 4-byte boundary.
- if (LogAlign > 2 || !IsAligned(cast<BlockAddressSDNode>(N)->getOffset()))
+ if (Alignment > Align(4) ||
+ !isAligned(Alignment, cast<BlockAddressSDNode>(N)->getOffset()))
return false;
R = N;
return true;
}
- if (SelectGlobalAddress(N, R, false, LogAlign) ||
- SelectGlobalAddress(N, R, true, LogAlign))
+ if (SelectGlobalAddress(N, R, false, Alignment) ||
+ SelectGlobalAddress(N, R, true, Alignment))
return true;
return false;
}
bool HexagonDAGToDAGISel::SelectGlobalAddress(SDValue &N, SDValue &R,
- bool UseGP, uint32_t LogAlign) {
- auto IsAligned = [LogAlign] (uint64_t V) -> bool {
- return alignTo(V, (uint64_t)1 << LogAlign) == V;
- };
-
+ bool UseGP, Align Alignment) {
switch (N.getOpcode()) {
case ISD::ADD: {
SDValue N0 = N.getOperand(0);
@@ -1392,10 +1400,9 @@ bool HexagonDAGToDAGISel::SelectGlobalAddress(SDValue &N, SDValue &R,
if (!UseGP && GAOpc != HexagonISD::CONST32)
return false;
if (ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1)) {
- SDValue Addr = N0.getOperand(0);
- // For the purpose of alignment, sextvalue and zextvalue are the same.
- if (!IsAligned(Const->getZExtValue()))
+ if (!isAligned(Alignment, Const->getZExtValue()))
return false;
+ SDValue Addr = N0.getOperand(0);
if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Addr)) {
if (GA->getOpcode() == ISD::TargetGlobalAddress) {
uint64_t NewOff = GA->getOffset() + (uint64_t)Const->getSExtValue();