diff options
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp')
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp | 81 |
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(); |