diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp | 18 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 23 |
2 files changed, 24 insertions, 17 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp index eee59f1..d44eee0 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -743,14 +743,16 @@ bool AArch64DAGToDAGISel::SelectAddrModeIndexed(SDValue N, unsigned Size, if (!GAN) return true; - const GlobalValue *GV = GAN->getGlobal(); - unsigned Alignment = GV->getAlignment(); - Type *Ty = GV->getValueType(); - if (Alignment == 0 && Ty->isSized()) - Alignment = DL.getABITypeAlignment(Ty); - - if (Alignment >= Size) - return true; + if (GAN->getOffset() % Size == 0) { + const GlobalValue *GV = GAN->getGlobal(); + unsigned Alignment = GV->getAlignment(); + Type *Ty = GV->getValueType(); + if (Alignment == 0 && Ty->isSized()) + Alignment = DL.getABITypeAlignment(Ty); + + if (Alignment >= Size) + return true; + } } if (CurDAG->isBaseWithConstantOffset(N)) { diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 28edcc2..546da27 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -3675,7 +3675,8 @@ AArch64TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, SDValue AArch64TargetLowering::getTargetNode(GlobalAddressSDNode *N, EVT Ty, SelectionDAG &DAG, unsigned Flag) const { - return DAG.getTargetGlobalAddress(N->getGlobal(), SDLoc(N), Ty, 0, Flag); + return DAG.getTargetGlobalAddress(N->getGlobal(), SDLoc(N), Ty, + N->getOffset(), Flag); } SDValue AArch64TargetLowering::getTargetNode(JumpTableSDNode *N, EVT Ty, @@ -3749,9 +3750,9 @@ SDValue AArch64TargetLowering::LowerGlobalAddress(SDValue Op, : AArch64II::MO_NO_FLAG); unsigned char OpFlags = Subtarget->ClassifyGlobalReference(GV, getTargetMachine()); - - assert(cast<GlobalAddressSDNode>(Op)->getOffset() == 0 && - "unexpected offset in global node"); + if (OpFlags != AArch64II::MO_NO_FLAG) + assert(cast<GlobalAddressSDNode>(Op)->getOffset() == 0 && + "unexpected offset in global node"); // This also catches the large code model case for Darwin. if ((OpFlags & AArch64II::MO_GOT) != 0) { @@ -4989,11 +4990,15 @@ SDValue AArch64TargetLowering::LowerShiftLeftParts(SDValue Op, bool AArch64TargetLowering::isOffsetFoldingLegal( const GlobalAddressSDNode *GA) const { - DEBUG(dbgs() << "Skipping offset folding global address: "); - DEBUG(GA->dump()); - DEBUG(dbgs() << "AArch64 doesn't support folding offsets into global " - "addresses\n"); - return false; + // FIXME: Only ELF can represent the full range of possible addends here, as + // the format stores the addend in a 64-bit field. With Mach-O the equivalent + // field is 24 bits, and with COFF it is 21 bits. To make this work with the + // other object formats we will need to arrange to prevent the addend from + // going out of bounds. + if (!getTargetMachine().getTargetTriple().isOSBinFormatELF()) + return false; + return Subtarget->ClassifyGlobalReference( + GA->getGlobal(), getTargetMachine()) == AArch64II::MO_NO_FLAG; } bool AArch64TargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const { |