From: Colin LeMahieu Date: Mon, 9 Mar 2015 21:19:02 +0000 (+0000) Subject: [Hexagon] Reverting r231699 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c2d30aebf31ebbd5996624e2161ebb50ed1bc524;p=oota-llvm.git [Hexagon] Reverting r231699 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@231703 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp index bec3455dfc2..fb056b50430 100644 --- a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp +++ b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp @@ -332,6 +332,73 @@ static unsigned doesIntrinsicReturnPredicate(unsigned ID) } } +static bool OffsetFitsS11(EVT MemType, int64_t Offset) { + if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) { + return true; + } + if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) { + return true; + } + if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) { + return true; + } + if (MemType == MVT::i8 && isInt<11>(Offset)) { + return true; + } + return false; +} + + +// +// Try to lower loads of GlobalAdresses into base+offset loads. Custom +// lowering for GlobalAddress nodes has already turned it into a +// CONST32. +// +SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl) { + SDValue Chain = LD->getChain(); + SDNode* Const32 = LD->getBasePtr().getNode(); + unsigned Opcode = 0; + + if (Const32->getOpcode() == HexagonISD::CONST32 && + ISD::isNormalLoad(LD)) { + SDValue Base = Const32->getOperand(0); + EVT LoadedVT = LD->getMemoryVT(); + int64_t Offset = cast(Base)->getOffset(); + if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) { + MVT PointerTy = getTargetLowering()->getPointerTy(); + const GlobalValue* GV = + cast(Base)->getGlobal(); + SDValue TargAddr = + CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0); + SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set, + dl, PointerTy, + TargAddr); + // Figure out base + offset opcode + if (LoadedVT == MVT::i64) Opcode = Hexagon::L2_loadrd_io; + else if (LoadedVT == MVT::i32) Opcode = Hexagon::L2_loadri_io; + else if (LoadedVT == MVT::i16) Opcode = Hexagon::L2_loadrh_io; + else if (LoadedVT == MVT::i8) Opcode = Hexagon::L2_loadrb_io; + else llvm_unreachable("unknown memory type"); + + // Build indexed load. + SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy); + SDNode* Result = CurDAG->getMachineNode(Opcode, dl, + LD->getValueType(0), + MVT::Other, + SDValue(NewBase,0), + TargetConstOff, + Chain); + MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); + MemOp[0] = LD->getMemOperand(); + cast(Result)->setMemRefs(MemOp, MemOp + 1); + ReplaceUses(LD, Result); + return Result; + } + } + + return SelectCode(LD); +} + SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode, @@ -582,7 +649,7 @@ SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) { if (AM != ISD::UNINDEXED) { result = SelectIndexedLoad(LD, dl); } else { - result = SelectCode(LD); + result = SelectBaseOffsetLoad(LD, dl); } return result; @@ -658,6 +725,60 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) { } +SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST, + SDLoc dl) { + SDValue Chain = ST->getChain(); + SDNode* Const32 = ST->getBasePtr().getNode(); + SDValue Value = ST->getValue(); + unsigned Opcode = 0; + + // Try to lower stores of GlobalAdresses into indexed stores. Custom + // lowering for GlobalAddress nodes has already turned it into a + // CONST32. Avoid truncating stores for the moment. Post-inc stores + // do the same. Don't think there's a reason for it, so will file a + // bug to fix. + if ((Const32->getOpcode() == HexagonISD::CONST32) && + !(Value.getValueType() == MVT::i64 && ST->isTruncatingStore())) { + SDValue Base = Const32->getOperand(0); + if (Base.getOpcode() == ISD::TargetGlobalAddress) { + EVT StoredVT = ST->getMemoryVT(); + int64_t Offset = cast(Base)->getOffset(); + if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) { + MVT PointerTy = getTargetLowering()->getPointerTy(); + const GlobalValue* GV = + cast(Base)->getGlobal(); + SDValue TargAddr = + CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0); + SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set, + dl, PointerTy, + TargAddr); + + // Figure out base + offset opcode + if (StoredVT == MVT::i64) Opcode = Hexagon::S2_storerd_io; + else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_io; + else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_io; + else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_io; + else llvm_unreachable("unknown memory type"); + + SDValue Ops[] = {SDValue(NewBase,0), + CurDAG->getTargetConstant(Offset,PointerTy), + Value, Chain}; + // build indexed store + SDNode* Result = CurDAG->getMachineNode(Opcode, dl, + MVT::Other, Ops); + MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); + MemOp[0] = ST->getMemOperand(); + cast(Result)->setMemRefs(MemOp, MemOp + 1); + ReplaceUses(ST, Result); + return Result; + } + } + } + + return SelectCode(ST); +} + + SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) { SDLoc dl(N); StoreSDNode *ST = cast(N); @@ -668,7 +789,7 @@ SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) { return SelectIndexedStore(ST, dl); } - return SelectCode(ST); + return SelectBaseOffsetStore(ST, dl); } SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) { diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td index 5794a5a6d83..2654a5dfdfc 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/lib/Target/Hexagon/HexagonInstrInfo.td @@ -4805,19 +4805,31 @@ def CONST32 : CONSTLDInst<(outs IntRegs:$dst), (ins globaladdress:$global), (load (HexagonCONST32 tglobaltlsaddr:$global)))]>; let isReMaterializable = 1, isMoveImm = 1 in +def CONST32_set : LDInst2<(outs IntRegs:$dst), (ins globaladdress:$global), + "$dst = CONST32(#$global)", + [(set (i32 IntRegs:$dst), + (HexagonCONST32 tglobaladdr:$global))]>; + +let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in def CONST32_set_jt : CONSTLDInst<(outs IntRegs:$dst), (ins jumptablebase:$jt), "$dst = CONST32(#$jt)", [(set (i32 IntRegs:$dst), (HexagonCONST32 tjumptable:$jt))]>; +let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in +def CONST32GP_set : LDInst2<(outs IntRegs:$dst), (ins globaladdress:$global), + "$dst = CONST32(#$global)", + [(set (i32 IntRegs:$dst), + (HexagonCONST32_GP tglobaladdr:$global))]>; + let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in def CONST32_Int_Real : CONSTLDInst<(outs IntRegs:$dst), (ins i32imm:$global), "$dst = CONST32(#$global)", [(set (i32 IntRegs:$dst), imm:$global) ]>; -// Map TLS addressses to a CONST32 instruction -def: Pat<(HexagonCONST32 tglobaltlsaddr:$addr), (A2_tfrsi s16Ext:$addr)>; -def: Pat<(HexagonCONST32 bbl:$label), (A2_tfrsi s16Ext:$label)>; +// Map BlockAddress lowering to CONST32_Int_Real +def : Pat<(HexagonCONST32_GP tblockaddress:$addr), + (CONST32_Int_Real tblockaddress:$addr)>; let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in def CONST32_Label : LDInst2<(outs IntRegs:$dst), (ins bblabel:$label), diff --git a/test/CodeGen/Hexagon/struct_args_large.ll b/test/CodeGen/Hexagon/struct_args_large.ll index 1438d73eacf..db87d9e81db 100644 --- a/test/CodeGen/Hexagon/struct_args_large.ll +++ b/test/CodeGen/Hexagon/struct_args_large.ll @@ -1,5 +1,4 @@ -; XFAIL: -; RUN: llc -march=hexagon < %s | FileCheck %s +; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s ; CHECK: r[[T0:[0-9]+]] = CONST32(#s2) ; CHECK: memw(r29+#0) = r{{.}} ; CHECK: memw(r29+#8) = r{{.}}