From: Chris Lattner Date: Thu, 3 May 2007 16:54:34 +0000 (+0000) Subject: Allow i/s to match (gv+c). This fixes CodeGen/PowerPC/2007-05-03-InlineAsm-S-Constra... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=75c7d2bd551acd1ad4f0f58b763ec8840f1d9c34;p=oota-llvm.git Allow i/s to match (gv+c). This fixes CodeGen/PowerPC/2007-05-03-InlineAsm-S-Constraint.ll and PR1382 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36672 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 90cf86f23c5..1a8a4bc349f 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1915,22 +1915,43 @@ SDOperand TargetLowering::isOperandValidForConstraint(SDOperand Op, case 'i': // Simple Integer or Relocatable Constant case 'n': // Simple Integer case 's': // Relocatable Constant - case 'X': // Allows any operand. - // These are okay if the operand is either a global variable address or a - // simple immediate value. If we have one of these, map to the TargetXXX - // version so that the value itself doesn't get selected. - if (ConstantSDNode *C = dyn_cast(Op)) { + case 'X': { // Allows any operand. + // These operands are interested in values of the form (GV+C), where C may + // be folded in as an offset of GV, or it may be explicitly added. Also, it + // is possible and fine if either GV or C are missing. + ConstantSDNode *C = dyn_cast(Op); + GlobalAddressSDNode *GA = dyn_cast(Op); + + // If we have "(add GV, C)", pull out GV/C + if (Op.getOpcode() == ISD::ADD) { + C = dyn_cast(Op.getOperand(1)); + GA = dyn_cast(Op.getOperand(0)); + if (C == 0 || GA == 0) { + C = dyn_cast(Op.getOperand(0)); + GA = dyn_cast(Op.getOperand(1)); + } + if (C == 0 || GA == 0) + C = 0, GA = 0; + } + + // If we find a valid operand, map to the TargetXXX version so that the + // value itself doesn't get selected. + if (GA) { // Either &GV or &GV+C + if (ConstraintLetter != 'n') { + int64_t Offs = GA->getOffset(); + if (C) Offs += C->getValue(); + return DAG.getTargetGlobalAddress(GA->getGlobal(), Op.getValueType(), + Offs); + } + } + if (C) { // just C, no GV. // Simple constants are not allowed for 's'. if (ConstraintLetter != 's') return DAG.getTargetConstant(C->getValue(), Op.getValueType()); } - if (GlobalAddressSDNode *GA = dyn_cast(Op)) { - if (ConstraintLetter != 'n') - return DAG.getTargetGlobalAddress(GA->getGlobal(), Op.getValueType(), - GA->getOffset()); - } break; } + } return SDOperand(0,0); }