Fix two classes of bugs:

1. x86 backend rejected (&gv+c) for the 'i' constraint when in static mode.
  2. the matcher didn't correctly reject and accept some global addresses.
     the right predicate is GVRequiresExtraLoad, not "relomodel = pic".


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36670 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2007-05-03 16:52:29 +00:00
parent 388488d604
commit dc43a88b81

View File

@ -4734,25 +4734,49 @@ isOperandValidForConstraint(SDOperand Op, char Constraint, SelectionDAG &DAG) {
return Op; return Op;
} }
return SDOperand(0,0); return SDOperand(0,0);
case 'i': case 'i': {
// Literal immediates are always ok. // Literal immediates are always ok.
if (isa<ConstantSDNode>(Op)) return Op; if (isa<ConstantSDNode>(Op)) return Op;
// If we are in non-pic codegen mode, we allow the address of a global to // If we are in non-pic codegen mode, we allow the address of a global (with
// be used with 'i'. // an optional displacement) to be used with 'i'.
if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op)) { GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op);
if (getTargetMachine().getRelocationModel() == Reloc::PIC_) int64_t Offset = 0;
// Match either (GA) or (GA+C)
if (GA) {
Offset = GA->getOffset();
} else if (Op.getOpcode() == ISD::ADD) {
ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
GA = dyn_cast<GlobalAddressSDNode>(Op.getOperand(0));
if (C && GA) {
Offset = GA->getOffset()+C->getValue();
} else {
C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
GA = dyn_cast<GlobalAddressSDNode>(Op.getOperand(0));
if (C && GA)
Offset = GA->getOffset()+C->getValue();
else
C = 0, GA = 0;
}
}
if (GA) {
// If addressing this global requires a load (e.g. in PIC mode), we can't
// match.
if (Subtarget->GVRequiresExtraLoad(GA->getGlobal(), getTargetMachine(),
false))
return SDOperand(0, 0); return SDOperand(0, 0);
if (GA->getOpcode() != ISD::TargetGlobalAddress)
Op = DAG.getTargetGlobalAddress(GA->getGlobal(), GA->getValueType(0), Op = DAG.getTargetGlobalAddress(GA->getGlobal(), GA->getValueType(0),
GA->getOffset()); Offset);
return Op; return Op;
} }
// Otherwise, not valid for this mode. // Otherwise, not valid for this mode.
return SDOperand(0, 0); return SDOperand(0, 0);
} }
}
return TargetLowering::isOperandValidForConstraint(Op, Constraint, DAG); return TargetLowering::isOperandValidForConstraint(Op, Constraint, DAG);
} }