diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -209,14 +209,15 @@ private: void Select(SDNode *N) override; - bool foldOffsetIntoAddress(uint64_t Offset, X86ISelAddressMode &AM); + bool foldOffsetIntoAddress(uint64_t Offset, X86ISelAddressMode &AM, + bool ForceSymbolicDisp = false); bool matchLoadInAddress(LoadSDNode *N, X86ISelAddressMode &AM); - bool matchWrapper(SDValue N, X86ISelAddressMode &AM); + bool matchWrapper(SDValue N, X86ISelAddressMode &AM, bool &HasSymbolicDisp); bool matchAddress(SDValue N, X86ISelAddressMode &AM); bool matchVectorAddress(SDValue N, X86ISelAddressMode &AM); bool matchAdd(SDValue &N, X86ISelAddressMode &AM, unsigned Depth); bool matchAddressRecursively(SDValue N, X86ISelAddressMode &AM, - unsigned Depth); + unsigned Depth, bool &HasSymbolicDisp); bool matchAddressBase(SDValue N, X86ISelAddressMode &AM); bool selectAddr(SDNode *Parent, SDValue N, SDValue &Base, SDValue &Scale, SDValue &Index, SDValue &Disp, @@ -1408,7 +1409,8 @@ } bool X86DAGToDAGISel::foldOffsetIntoAddress(uint64_t Offset, - X86ISelAddressMode &AM) { + X86ISelAddressMode &AM, + bool HasSymbolicDisp) { // If there's no offset to fold, we don't need to do any work. if (Offset == 0) return false; @@ -1420,8 +1422,8 @@ int64_t Val = AM.Disp + Offset; CodeModel::Model M = TM.getCodeModel(); if (Subtarget->is64Bit()) { - if (!X86::isOffsetSuitableForCodeModel(Val, M, - AM.hasSymbolicDisplacement())) + if (!X86::isOffsetSuitableForCodeModel( + Val, M, HasSymbolicDisp || AM.hasSymbolicDisplacement())) return true; // In addition to the checks required for a register base, check that // we do not try to use an unsafe Disp with a frame index. @@ -1431,7 +1433,6 @@ } AM.Disp = Val; return false; - } bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *N, X86ISelAddressMode &AM){ @@ -1465,7 +1466,8 @@ /// Try to match X86ISD::Wrapper and X86ISD::WrapperRIP nodes into an addressing /// mode. These wrap things that will resolve down into a symbol reference. /// If no match is possible, this returns true, otherwise it returns false. -bool X86DAGToDAGISel::matchWrapper(SDValue N, X86ISelAddressMode &AM) { +bool X86DAGToDAGISel::matchWrapper(SDValue N, X86ISelAddressMode &AM, + bool &HasSymbolicDisp) { // If the addressing mode already has a symbol as the displacement, we can // never match another symbol. if (AM.hasSymbolicDisplacement()) @@ -1532,13 +1534,15 @@ AM.setBaseReg(CurDAG->getRegister(X86::RIP, MVT::i64)); // Commit the changes now that we know this fold is safe. + HasSymbolicDisp = true; return false; } /// Add the specified node to the specified addressing mode, returning true if /// it cannot be done. This just pattern matches for the addressing mode. bool X86DAGToDAGISel::matchAddress(SDValue N, X86ISelAddressMode &AM) { - if (matchAddressRecursively(N, AM, 0)) + bool HasSymbolicDisp = false; + if (matchAddressRecursively(N, AM, 0, HasSymbolicDisp)) return true; // Post-processing: Convert lea(,%reg,2) to lea(%reg,%reg), which has @@ -1577,15 +1581,19 @@ // it if it gets CSE'd with a different node. HandleSDNode Handle(N); + bool HasSymbolicDisp = AM.hasSymbolicDisplacement(); X86ISelAddressMode Backup = AM; - if (!matchAddressRecursively(N.getOperand(0), AM, Depth+1) && - !matchAddressRecursively(Handle.getValue().getOperand(1), AM, Depth+1)) + if (!matchAddressRecursively(N.getOperand(0), AM, Depth + 1, HasSymbolicDisp) && + !matchAddressRecursively(Handle.getValue().getOperand(1), AM, Depth + 1, + HasSymbolicDisp)) return false; AM = Backup; // Try again after commuting the operands. - if (!matchAddressRecursively(Handle.getValue().getOperand(1), AM, Depth+1) && - !matchAddressRecursively(Handle.getValue().getOperand(0), AM, Depth+1)) + if (!matchAddressRecursively(Handle.getValue().getOperand(1), AM, Depth + 1, + HasSymbolicDisp) && + !matchAddressRecursively(Handle.getValue().getOperand(0), AM, Depth + 1, + HasSymbolicDisp)) return false; AM = Backup; @@ -1908,7 +1916,8 @@ } bool X86DAGToDAGISel::matchAddressRecursively(SDValue N, X86ISelAddressMode &AM, - unsigned Depth) { + unsigned Depth, + bool &HasSymbolicDisp) { SDLoc dl(N); LLVM_DEBUG({ dbgs() << "MatchAddress: "; @@ -1947,14 +1956,14 @@ } case ISD::Constant: { uint64_t Val = cast(N)->getSExtValue(); - if (!foldOffsetIntoAddress(Val, AM)) + if (!foldOffsetIntoAddress(Val, AM, HasSymbolicDisp)) return false; break; } case X86ISD::Wrapper: case X86ISD::WrapperRIP: - if (!matchWrapper(N, AM)) + if (!matchWrapper(N, AM, HasSymbolicDisp)) return false; break; @@ -2086,7 +2095,9 @@ // Test if the LHS of the sub can be folded. X86ISelAddressMode Backup = AM; - if (matchAddressRecursively(N.getOperand(0), AM, Depth+1)) { + bool ForceSymbolicDisp = false; + if (matchAddressRecursively(N.getOperand(0), AM, Depth + 1, + ForceSymbolicDisp)) { N = Handle.getValue(); AM = Backup; break; @@ -2271,11 +2282,13 @@ return false; break; } - case X86ISD::Wrapper: - if (!matchWrapper(N, AM)) + case X86ISD::Wrapper: { + bool HasSymbolicDisp = false; + if (!matchWrapper(N, AM, HasSymbolicDisp)) return false; break; } + } return matchAddressBase(N, AM); }