mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-18 06:38:41 +00:00
Fix PR11985
- BlockAddress has no support of BA + offset form and there is no way to propagate that offset into machine operand; - Add BA + offset support and a new interface 'getTargetBlockAddress' to simplify target block address forming; - All targets are modified to use new interface and X86 backend is enhanced to support BA + offset addressing. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163743 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0d1bc5f916
commit
6c7ccaa3fd
@ -628,11 +628,11 @@ public:
|
|||||||
Op.setTargetFlags(TargetFlags);
|
Op.setTargetFlags(TargetFlags);
|
||||||
return Op;
|
return Op;
|
||||||
}
|
}
|
||||||
static MachineOperand CreateBA(const BlockAddress *BA,
|
static MachineOperand CreateBA(const BlockAddress *BA, int64_t Offset,
|
||||||
unsigned char TargetFlags = 0) {
|
unsigned char TargetFlags = 0) {
|
||||||
MachineOperand Op(MachineOperand::MO_BlockAddress);
|
MachineOperand Op(MachineOperand::MO_BlockAddress);
|
||||||
Op.Contents.OffsetedInfo.Val.BA = BA;
|
Op.Contents.OffsetedInfo.Val.BA = BA;
|
||||||
Op.setOffset(0); // Offset is always 0.
|
Op.setOffset(Offset);
|
||||||
Op.setTargetFlags(TargetFlags);
|
Op.setTargetFlags(TargetFlags);
|
||||||
return Op;
|
return Op;
|
||||||
}
|
}
|
||||||
|
@ -437,7 +437,13 @@ public:
|
|||||||
SDValue getRegisterMask(const uint32_t *RegMask);
|
SDValue getRegisterMask(const uint32_t *RegMask);
|
||||||
SDValue getEHLabel(DebugLoc dl, SDValue Root, MCSymbol *Label);
|
SDValue getEHLabel(DebugLoc dl, SDValue Root, MCSymbol *Label);
|
||||||
SDValue getBlockAddress(const BlockAddress *BA, EVT VT,
|
SDValue getBlockAddress(const BlockAddress *BA, EVT VT,
|
||||||
bool isTarget = false, unsigned char TargetFlags = 0);
|
int64_t Offset = 0, bool isTarget = false,
|
||||||
|
unsigned char TargetFlags = 0);
|
||||||
|
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT,
|
||||||
|
int64_t Offset = 0,
|
||||||
|
unsigned char TargetFlags = 0) {
|
||||||
|
return getBlockAddress(BA, VT, Offset, true, TargetFlags);
|
||||||
|
}
|
||||||
|
|
||||||
SDValue getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N) {
|
SDValue getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N) {
|
||||||
return getNode(ISD::CopyToReg, dl, MVT::Other, Chain,
|
return getNode(ISD::CopyToReg, dl, MVT::Other, Chain,
|
||||||
|
@ -1483,15 +1483,17 @@ public:
|
|||||||
|
|
||||||
class BlockAddressSDNode : public SDNode {
|
class BlockAddressSDNode : public SDNode {
|
||||||
const BlockAddress *BA;
|
const BlockAddress *BA;
|
||||||
|
int64_t Offset;
|
||||||
unsigned char TargetFlags;
|
unsigned char TargetFlags;
|
||||||
friend class SelectionDAG;
|
friend class SelectionDAG;
|
||||||
BlockAddressSDNode(unsigned NodeTy, EVT VT, const BlockAddress *ba,
|
BlockAddressSDNode(unsigned NodeTy, EVT VT, const BlockAddress *ba,
|
||||||
unsigned char Flags)
|
int64_t o, unsigned char Flags)
|
||||||
: SDNode(NodeTy, DebugLoc(), getSDVTList(VT)),
|
: SDNode(NodeTy, DebugLoc(), getSDVTList(VT)),
|
||||||
BA(ba), TargetFlags(Flags) {
|
BA(ba), Offset(o), TargetFlags(Flags) {
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
const BlockAddress *getBlockAddress() const { return BA; }
|
const BlockAddress *getBlockAddress() const { return BA; }
|
||||||
|
int64_t getOffset() const { return Offset; }
|
||||||
unsigned char getTargetFlags() const { return TargetFlags; }
|
unsigned char getTargetFlags() const { return TargetFlags; }
|
||||||
|
|
||||||
static bool classof(const BlockAddressSDNode *) { return true; }
|
static bool classof(const BlockAddressSDNode *) { return true; }
|
||||||
|
@ -198,7 +198,8 @@ bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {
|
|||||||
return !strcmp(getSymbolName(), Other.getSymbolName()) &&
|
return !strcmp(getSymbolName(), Other.getSymbolName()) &&
|
||||||
getOffset() == Other.getOffset();
|
getOffset() == Other.getOffset();
|
||||||
case MachineOperand::MO_BlockAddress:
|
case MachineOperand::MO_BlockAddress:
|
||||||
return getBlockAddress() == Other.getBlockAddress();
|
return getBlockAddress() == Other.getBlockAddress() &&
|
||||||
|
getOffset() == Other.getOffset();
|
||||||
case MO_RegisterMask:
|
case MO_RegisterMask:
|
||||||
return getRegMask() == Other.getRegMask();
|
return getRegMask() == Other.getRegMask();
|
||||||
case MachineOperand::MO_MCSymbol:
|
case MachineOperand::MO_MCSymbol:
|
||||||
@ -239,7 +240,7 @@ hash_code llvm::hash_value(const MachineOperand &MO) {
|
|||||||
MO.getOffset());
|
MO.getOffset());
|
||||||
case MachineOperand::MO_BlockAddress:
|
case MachineOperand::MO_BlockAddress:
|
||||||
return hash_combine(MO.getType(), MO.getTargetFlags(),
|
return hash_combine(MO.getType(), MO.getTargetFlags(),
|
||||||
MO.getBlockAddress());
|
MO.getBlockAddress(), MO.getOffset());
|
||||||
case MachineOperand::MO_RegisterMask:
|
case MachineOperand::MO_RegisterMask:
|
||||||
return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask());
|
return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask());
|
||||||
case MachineOperand::MO_Metadata:
|
case MachineOperand::MO_Metadata:
|
||||||
@ -362,6 +363,7 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const {
|
|||||||
case MachineOperand::MO_BlockAddress:
|
case MachineOperand::MO_BlockAddress:
|
||||||
OS << '<';
|
OS << '<';
|
||||||
WriteAsOperand(OS, getBlockAddress(), /*PrintType=*/false);
|
WriteAsOperand(OS, getBlockAddress(), /*PrintType=*/false);
|
||||||
|
if (getOffset()) OS << "+" << getOffset();
|
||||||
OS << '>';
|
OS << '>';
|
||||||
break;
|
break;
|
||||||
case MachineOperand::MO_RegisterMask:
|
case MachineOperand::MO_RegisterMask:
|
||||||
|
@ -410,6 +410,7 @@ void InstrEmitter::AddOperand(MachineInstr *MI, SDValue Op,
|
|||||||
ES->getTargetFlags()));
|
ES->getTargetFlags()));
|
||||||
} else if (BlockAddressSDNode *BA = dyn_cast<BlockAddressSDNode>(Op)) {
|
} else if (BlockAddressSDNode *BA = dyn_cast<BlockAddressSDNode>(Op)) {
|
||||||
MI->addOperand(MachineOperand::CreateBA(BA->getBlockAddress(),
|
MI->addOperand(MachineOperand::CreateBA(BA->getBlockAddress(),
|
||||||
|
BA->getOffset(),
|
||||||
BA->getTargetFlags()));
|
BA->getTargetFlags()));
|
||||||
} else if (TargetIndexSDNode *TI = dyn_cast<TargetIndexSDNode>(Op)) {
|
} else if (TargetIndexSDNode *TI = dyn_cast<TargetIndexSDNode>(Op)) {
|
||||||
MI->addOperand(MachineOperand::CreateTargetIndex(TI->getIndex(),
|
MI->addOperand(MachineOperand::CreateTargetIndex(TI->getIndex(),
|
||||||
|
@ -494,8 +494,10 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) {
|
|||||||
}
|
}
|
||||||
case ISD::TargetBlockAddress:
|
case ISD::TargetBlockAddress:
|
||||||
case ISD::BlockAddress: {
|
case ISD::BlockAddress: {
|
||||||
ID.AddPointer(cast<BlockAddressSDNode>(N)->getBlockAddress());
|
const BlockAddressSDNode *BA = cast<BlockAddressSDNode>(N);
|
||||||
ID.AddInteger(cast<BlockAddressSDNode>(N)->getTargetFlags());
|
ID.AddPointer(BA->getBlockAddress());
|
||||||
|
ID.AddInteger(BA->getOffset());
|
||||||
|
ID.AddInteger(BA->getTargetFlags());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} // end switch (N->getOpcode())
|
} // end switch (N->getOpcode())
|
||||||
@ -1470,6 +1472,7 @@ SDValue SelectionDAG::getEHLabel(DebugLoc dl, SDValue Root, MCSymbol *Label) {
|
|||||||
|
|
||||||
|
|
||||||
SDValue SelectionDAG::getBlockAddress(const BlockAddress *BA, EVT VT,
|
SDValue SelectionDAG::getBlockAddress(const BlockAddress *BA, EVT VT,
|
||||||
|
int64_t Offset,
|
||||||
bool isTarget,
|
bool isTarget,
|
||||||
unsigned char TargetFlags) {
|
unsigned char TargetFlags) {
|
||||||
unsigned Opc = isTarget ? ISD::TargetBlockAddress : ISD::BlockAddress;
|
unsigned Opc = isTarget ? ISD::TargetBlockAddress : ISD::BlockAddress;
|
||||||
@ -1477,12 +1480,14 @@ SDValue SelectionDAG::getBlockAddress(const BlockAddress *BA, EVT VT,
|
|||||||
FoldingSetNodeID ID;
|
FoldingSetNodeID ID;
|
||||||
AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0);
|
AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0);
|
||||||
ID.AddPointer(BA);
|
ID.AddPointer(BA);
|
||||||
|
ID.AddInteger(Offset);
|
||||||
ID.AddInteger(TargetFlags);
|
ID.AddInteger(TargetFlags);
|
||||||
void *IP = 0;
|
void *IP = 0;
|
||||||
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
|
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
|
||||||
return SDValue(E, 0);
|
return SDValue(E, 0);
|
||||||
|
|
||||||
SDNode *N = new (NodeAllocator) BlockAddressSDNode(Opc, VT, BA, TargetFlags);
|
SDNode *N = new (NodeAllocator) BlockAddressSDNode(Opc, VT, BA, Offset,
|
||||||
|
TargetFlags);
|
||||||
CSEMap.InsertNode(N, IP);
|
CSEMap.InsertNode(N, IP);
|
||||||
AllNodes.push_back(N);
|
AllNodes.push_back(N);
|
||||||
return SDValue(N, 0);
|
return SDValue(N, 0);
|
||||||
|
@ -475,11 +475,16 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
|
|||||||
OS << "<" << *M->getMemOperand() << ">";
|
OS << "<" << *M->getMemOperand() << ">";
|
||||||
} else if (const BlockAddressSDNode *BA =
|
} else if (const BlockAddressSDNode *BA =
|
||||||
dyn_cast<BlockAddressSDNode>(this)) {
|
dyn_cast<BlockAddressSDNode>(this)) {
|
||||||
|
int64_t offset = BA->getOffset();
|
||||||
OS << "<";
|
OS << "<";
|
||||||
WriteAsOperand(OS, BA->getBlockAddress()->getFunction(), false);
|
WriteAsOperand(OS, BA->getBlockAddress()->getFunction(), false);
|
||||||
OS << ", ";
|
OS << ", ";
|
||||||
WriteAsOperand(OS, BA->getBlockAddress()->getBasicBlock(), false);
|
WriteAsOperand(OS, BA->getBlockAddress()->getBasicBlock(), false);
|
||||||
OS << ">";
|
OS << ">";
|
||||||
|
if (offset > 0)
|
||||||
|
OS << " + " << offset;
|
||||||
|
else
|
||||||
|
OS << " " << offset;
|
||||||
if (unsigned int TF = BA->getTargetFlags())
|
if (unsigned int TF = BA->getTargetFlags())
|
||||||
OS << " [TF=" << TF << ']';
|
OS << " [TF=" << TF << ']';
|
||||||
}
|
}
|
||||||
|
@ -274,8 +274,8 @@ bool MSP430DAGToDAGISel::SelectAddr(SDValue N,
|
|||||||
else if (AM.JT != -1)
|
else if (AM.JT != -1)
|
||||||
Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i16, 0/*AM.SymbolFlags*/);
|
Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i16, 0/*AM.SymbolFlags*/);
|
||||||
else if (AM.BlockAddr)
|
else if (AM.BlockAddr)
|
||||||
Disp = CurDAG->getBlockAddress(AM.BlockAddr, MVT::i32,
|
Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, 0,
|
||||||
true, 0/*AM.SymbolFlags*/);
|
0/*AM.SymbolFlags*/);
|
||||||
else
|
else
|
||||||
Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i16);
|
Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i16);
|
||||||
|
|
||||||
|
@ -655,7 +655,7 @@ SDValue MSP430TargetLowering::LowerBlockAddress(SDValue Op,
|
|||||||
SelectionDAG &DAG) const {
|
SelectionDAG &DAG) const {
|
||||||
DebugLoc dl = Op.getDebugLoc();
|
DebugLoc dl = Op.getDebugLoc();
|
||||||
const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
|
const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
|
||||||
SDValue Result = DAG.getBlockAddress(BA, getPointerTy(), /*isTarget=*/true);
|
SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy());
|
||||||
|
|
||||||
return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);
|
return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);
|
||||||
}
|
}
|
||||||
|
@ -1620,8 +1620,8 @@ SDValue MipsTargetLowering::LowerBlockAddress(SDValue Op,
|
|||||||
|
|
||||||
if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) {
|
if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) {
|
||||||
// %hi/%lo relocation
|
// %hi/%lo relocation
|
||||||
SDValue BAHi = DAG.getBlockAddress(BA, MVT::i32, true, MipsII::MO_ABS_HI);
|
SDValue BAHi = DAG.getTargetBlockAddress(BA, MVT::i32, 0, MipsII::MO_ABS_HI);
|
||||||
SDValue BALo = DAG.getBlockAddress(BA, MVT::i32, true, MipsII::MO_ABS_LO);
|
SDValue BALo = DAG.getTargetBlockAddress(BA, MVT::i32, 0, MipsII::MO_ABS_LO);
|
||||||
SDValue Hi = DAG.getNode(MipsISD::Hi, dl, MVT::i32, BAHi);
|
SDValue Hi = DAG.getNode(MipsISD::Hi, dl, MVT::i32, BAHi);
|
||||||
SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, BALo);
|
SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, BALo);
|
||||||
return DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, Lo);
|
return DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, Lo);
|
||||||
@ -1630,10 +1630,10 @@ SDValue MipsTargetLowering::LowerBlockAddress(SDValue Op,
|
|||||||
EVT ValTy = Op.getValueType();
|
EVT ValTy = Op.getValueType();
|
||||||
unsigned GOTFlag = HasMips64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT;
|
unsigned GOTFlag = HasMips64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT;
|
||||||
unsigned OFSTFlag = HasMips64 ? MipsII::MO_GOT_OFST : MipsII::MO_ABS_LO;
|
unsigned OFSTFlag = HasMips64 ? MipsII::MO_GOT_OFST : MipsII::MO_ABS_LO;
|
||||||
SDValue BAGOTOffset = DAG.getBlockAddress(BA, ValTy, true, GOTFlag);
|
SDValue BAGOTOffset = DAG.getTargetBlockAddress(BA, ValTy, 0, GOTFlag);
|
||||||
BAGOTOffset = DAG.getNode(MipsISD::Wrapper, dl, ValTy,
|
BAGOTOffset = DAG.getNode(MipsISD::Wrapper, dl, ValTy,
|
||||||
GetGlobalReg(DAG, ValTy), BAGOTOffset);
|
GetGlobalReg(DAG, ValTy), BAGOTOffset);
|
||||||
SDValue BALOOffset = DAG.getBlockAddress(BA, ValTy, true, OFSTFlag);
|
SDValue BALOOffset = DAG.getTargetBlockAddress(BA, ValTy, 0, OFSTFlag);
|
||||||
SDValue Load = DAG.getLoad(ValTy, dl, DAG.getEntryNode(), BAGOTOffset,
|
SDValue Load = DAG.getLoad(ValTy, dl, DAG.getEntryNode(), BAGOTOffset,
|
||||||
MachinePointerInfo(), false, false, false, 0);
|
MachinePointerInfo(), false, false, false, 0);
|
||||||
SDValue Lo = DAG.getNode(MipsISD::Lo, dl, ValTy, BALOOffset);
|
SDValue Lo = DAG.getNode(MipsISD::Lo, dl, ValTy, BALOOffset);
|
||||||
|
@ -1264,8 +1264,8 @@ SDValue PPCTargetLowering::LowerBlockAddress(SDValue Op,
|
|||||||
|
|
||||||
unsigned MOHiFlag, MOLoFlag;
|
unsigned MOHiFlag, MOLoFlag;
|
||||||
bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag);
|
bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag);
|
||||||
SDValue TgtBAHi = DAG.getBlockAddress(BA, PtrVT, /*isTarget=*/true, MOHiFlag);
|
SDValue TgtBAHi = DAG.getTargetBlockAddress(BA, PtrVT, 0, MOHiFlag);
|
||||||
SDValue TgtBALo = DAG.getBlockAddress(BA, PtrVT, /*isTarget=*/true, MOLoFlag);
|
SDValue TgtBALo = DAG.getTargetBlockAddress(BA, PtrVT, 0, MOLoFlag);
|
||||||
return LowerLabelRef(TgtBAHi, TgtBALo, isPIC, DAG);
|
return LowerLabelRef(TgtBAHi, TgtBALo, isPIC, DAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,13 +246,15 @@ namespace {
|
|||||||
else if (AM.CP)
|
else if (AM.CP)
|
||||||
Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i32,
|
Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i32,
|
||||||
AM.Align, AM.Disp, AM.SymbolFlags);
|
AM.Align, AM.Disp, AM.SymbolFlags);
|
||||||
else if (AM.ES)
|
else if (AM.ES) {
|
||||||
|
assert(!AM.Disp && "Non-zero displacement is ignored with ES.");
|
||||||
Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i32, AM.SymbolFlags);
|
Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i32, AM.SymbolFlags);
|
||||||
else if (AM.JT != -1)
|
} else if (AM.JT != -1) {
|
||||||
|
assert(!AM.Disp && "Non-zero displacement is ignored with JT.");
|
||||||
Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags);
|
Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags);
|
||||||
else if (AM.BlockAddr)
|
} else if (AM.BlockAddr)
|
||||||
Disp = CurDAG->getBlockAddress(AM.BlockAddr, MVT::i32,
|
Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, AM.Disp,
|
||||||
true, AM.SymbolFlags);
|
AM.SymbolFlags);
|
||||||
else
|
else
|
||||||
Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i32);
|
Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i32);
|
||||||
|
|
||||||
@ -654,10 +656,16 @@ bool X86DAGToDAGISel::MatchWrapper(SDValue N, X86ISelAddressMode &AM) {
|
|||||||
} else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) {
|
} else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) {
|
||||||
AM.JT = J->getIndex();
|
AM.JT = J->getIndex();
|
||||||
AM.SymbolFlags = J->getTargetFlags();
|
AM.SymbolFlags = J->getTargetFlags();
|
||||||
} else {
|
} else if (BlockAddressSDNode *BA = dyn_cast<BlockAddressSDNode>(N0)) {
|
||||||
AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress();
|
X86ISelAddressMode Backup = AM;
|
||||||
AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags();
|
AM.BlockAddr = BA->getBlockAddress();
|
||||||
|
AM.SymbolFlags = BA->getTargetFlags();
|
||||||
|
if (FoldOffsetIntoAddress(BA->getOffset(), AM)) {
|
||||||
|
AM = Backup;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
|
llvm_unreachable("Unhandled symbol reference node.");
|
||||||
|
|
||||||
if (N.getOpcode() == X86ISD::WrapperRIP)
|
if (N.getOpcode() == X86ISD::WrapperRIP)
|
||||||
AM.setBaseReg(CurDAG->getRegister(X86::RIP, MVT::i64));
|
AM.setBaseReg(CurDAG->getRegister(X86::RIP, MVT::i64));
|
||||||
@ -686,10 +694,12 @@ bool X86DAGToDAGISel::MatchWrapper(SDValue N, X86ISelAddressMode &AM) {
|
|||||||
} else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) {
|
} else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) {
|
||||||
AM.JT = J->getIndex();
|
AM.JT = J->getIndex();
|
||||||
AM.SymbolFlags = J->getTargetFlags();
|
AM.SymbolFlags = J->getTargetFlags();
|
||||||
} else {
|
} else if (BlockAddressSDNode *BA = dyn_cast<BlockAddressSDNode>(N0)) {
|
||||||
AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress();
|
AM.BlockAddr = BA->getBlockAddress();
|
||||||
AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags();
|
AM.Disp += BA->getOffset();
|
||||||
}
|
AM.SymbolFlags = BA->getTargetFlags();
|
||||||
|
} else
|
||||||
|
llvm_unreachable("Unhandled symbol reference node.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7368,9 +7368,10 @@ X86TargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const {
|
|||||||
Subtarget->ClassifyBlockAddressReference();
|
Subtarget->ClassifyBlockAddressReference();
|
||||||
CodeModel::Model M = getTargetMachine().getCodeModel();
|
CodeModel::Model M = getTargetMachine().getCodeModel();
|
||||||
const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
|
const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
|
||||||
|
int64_t Offset = cast<BlockAddressSDNode>(Op)->getOffset();
|
||||||
DebugLoc dl = Op.getDebugLoc();
|
DebugLoc dl = Op.getDebugLoc();
|
||||||
SDValue Result = DAG.getBlockAddress(BA, getPointerTy(),
|
SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy(), Offset,
|
||||||
/*isTarget=*/true, OpFlags);
|
OpFlags);
|
||||||
|
|
||||||
if (Subtarget->isPICStyleRIPRel() &&
|
if (Subtarget->isPICStyleRIPRel() &&
|
||||||
(M == CodeModel::Small || M == CodeModel::Kernel))
|
(M == CodeModel::Small || M == CodeModel::Kernel))
|
||||||
|
@ -298,7 +298,7 @@ LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const
|
|||||||
DebugLoc DL = Op.getDebugLoc();
|
DebugLoc DL = Op.getDebugLoc();
|
||||||
|
|
||||||
const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
|
const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
|
||||||
SDValue Result = DAG.getBlockAddress(BA, getPointerTy(), /*isTarget=*/true);
|
SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy());
|
||||||
|
|
||||||
return DAG.getNode(XCoreISD::PCRelativeWrapper, DL, getPointerTy(), Result);
|
return DAG.getNode(XCoreISD::PCRelativeWrapper, DL, getPointerTy(), Result);
|
||||||
}
|
}
|
||||||
|
19
test/CodeGen/X86/pr11985.ll
Normal file
19
test/CodeGen/X86/pr11985.ll
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=prescott | FileCheck %s
|
||||||
|
|
||||||
|
define float @foo(i8* nocapture %buf, float %a, float %b) nounwind uwtable {
|
||||||
|
entry:
|
||||||
|
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %buf, i8* blockaddress(@foo, %out), i64 22, i32 1, i1 false)
|
||||||
|
br label %out
|
||||||
|
|
||||||
|
out: ; preds = %entry
|
||||||
|
%add = fadd float %a, %b
|
||||||
|
ret float %add
|
||||||
|
; CHECK: foo
|
||||||
|
; CHECK: movw .L{{.*}}+20(%rip), %{{.*}}
|
||||||
|
; CHECK: movl .L{{.*}}+16(%rip), %{{.*}}
|
||||||
|
; CHECK: movq .L{{.*}}+8(%rip), %{{.*}}
|
||||||
|
; CHECK: movq .L{{.*}}(%rip), %{{.*}}
|
||||||
|
; CHECK: ret
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
|
Loading…
x
Reference in New Issue
Block a user