Hello<br><br>I think I found a typo while looking over your diff.<br><br>In X86ISelDAGToDAG.cpp <br><br>"(M == CodeModel::Small || CodeModel::Kernel)"<br>should be <br>"(M == CodeModel::Small || M == CodeModel::Kernel)"<br>
 IMHO.<br><br>Because otherwise the test is always true because CodeModel::Kernel has a non-zero value.<br><br><br>Marius Wachtler<br><br><br><div class="gmail_quote">On Thu, Aug 6, 2009 at 1:01 AM, Anton Korobeynikov <span dir="ltr"><<a href="mailto:asl@math.spbu.ru">asl@math.spbu.ru</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Author: asl<br>
Date: Wed Aug  5 18:01:26 2009<br>
New Revision: 78255<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=78255&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=78255&view=rev</a><br>
Log:<br>
Better handle kernel code model. Also, generalize the things and fix one<br>
subtle bug with small code model.<br>
<br>
Modified:<br>
    llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp<br>
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
    llvm/trunk/lib/Target/X86/X86ISelLowering.h<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=78255&r1=78254&r2=78255&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=78255&r1=78254&r2=78255&view=diff</a><br>

<br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)<br>
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Wed Aug  5 18:01:26 2009<br>
@@ -705,7 +705,7 @@<br>
 /// MatchWrapper - Try to match X86ISD::Wrapper and X86ISD::WrapperRIP nodes<br>
 /// into an addressing mode.  These wrap things that will resolve down into a<br>
 /// symbol reference.  If no match is possible, this returns true, otherwise it<br>
-/// returns false.<br>
+/// returns false.<br>
 bool X86DAGToDAGISel::MatchWrapper(SDValue N, X86ISelAddressMode &AM) {<br>
   // If the addressing mode already has a symbol as the displacement, we can<br>
   // never match another symbol.<br>
@@ -713,28 +713,27 @@<br>
     return true;<br>
<br>
   SDValue N0 = N.getOperand(0);<br>
-<br>
+  CodeModel::Model M = TM.getCodeModel();<br>
+<br>
   // Handle X86-64 rip-relative addresses.  We check this before checking direct<br>
   // folding because RIP is preferable to non-RIP accesses.<br>
   if (Subtarget->is64Bit() &&<br>
       // Under X86-64 non-small code model, GV (and friends) are 64-bits, so<br>
       // they cannot be folded into immediate fields.<br>
       // FIXME: This can be improved for kernel and other models?<br>
-      TM.getCodeModel() == CodeModel::Small &&<br>
-<br>
+      (M == CodeModel::Small || CodeModel::Kernel) &&<br>
       // Base and index reg must be 0 in order to use %rip as base and lowering<br>
       // must allow RIP.<br>
       !AM.hasBaseOrIndexReg() && N.getOpcode() == X86ISD::WrapperRIP) {<br>
-<br>
     if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) {<br>
       int64_t Offset = AM.Disp + G->getOffset();<br>
-      if (!isInt32(Offset)) return true;<br>
+      if (!X86::isOffsetSuitableForCodeModel(Offset, M)) return true;<br>
       AM.GV = G->getGlobal();<br>
       AM.Disp = Offset;<br>
       AM.SymbolFlags = G->getTargetFlags();<br>
     } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N0)) {<br>
       int64_t Offset = AM.Disp + CP->getOffset();<br>
-      if (!isInt32(Offset)) return true;<br>
+      if (!X86::isOffsetSuitableForCodeModel(Offset, M)) return true;<br>
       AM.CP = CP->getConstVal();<br>
       AM.Align = CP->getAlignment();<br>
       AM.Disp = Offset;<br>
@@ -747,7 +746,7 @@<br>
       AM.JT = J->getIndex();<br>
       AM.SymbolFlags = J->getTargetFlags();<br>
     }<br>
-<br>
+<br>
     if (N.getOpcode() == X86ISD::WrapperRIP)<br>
       AM.setBaseReg(CurDAG->getRegister(X86::RIP, MVT::i64));<br>
     return false;<br>
@@ -757,7 +756,7 @@<br>
   // X86-32 always and X86-64 when in -static -mcmodel=small mode.  In 64-bit<br>
   // mode, this results in a non-RIP-relative computation.<br>
   if (!Subtarget->is64Bit() ||<br>
-      (TM.getCodeModel() == CodeModel::Small &&<br>
+      ((M == CodeModel::Small || M == CodeModel::Kernel) &&<br>
        TM.getRelocationModel() == Reloc::Static)) {<br>
     if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) {<br>
       AM.GV = G->getGlobal();<br>
@@ -809,7 +808,9 @@<br>
   // Limit recursion.<br>
   if (Depth > 5)<br>
     return MatchAddressBase(N, AM);<br>
-<br>
+<br>
+  CodeModel::Model M = TM.getCodeModel();<br>
+<br>
   // If this is already a %rip relative address, we can only merge immediates<br>
   // into it.  Instead of handling this in every case, we handle it here.<br>
   // RIP relative addressing: %rip + 32-bit displacement!<br>
@@ -818,10 +819,11 @@<br>
     // displacements.  It isn't very important, but this should be fixed for<br>
     // consistency.<br>
     if (!<a href="http://AM.ES" target="_blank">AM.ES</a> && AM.JT != -1) return true;<br>
-<br>
+<br>
     if (ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(N)) {<br>
       int64_t Val = AM.Disp + Cst->getSExtValue();<br>
-      if (isInt32(Val)) {<br>
+      if (X86::isOffsetSuitableForCodeModel(Val, M,<br>
+                                            AM.hasSymbolicDisplacement())) {<br>
         AM.Disp = Val;<br>
         return false;<br>
       }<br>
@@ -833,7 +835,9 @@<br>
   default: break;<br>
   case ISD::Constant: {<br>
     uint64_t Val = cast<ConstantSDNode>(N)->getSExtValue();<br>
-    if (!is64Bit || isInt32(AM.Disp + Val)) {<br>
+    if (!is64Bit ||<br>
+        X86::isOffsetSuitableForCodeModel(AM.Disp + Val, M,<br>
+                                          AM.hasSymbolicDisplacement())) {<br>
       AM.Disp += Val;<br>
       return false;<br>
     }<br>
@@ -889,7 +893,9 @@<br>
           ConstantSDNode *AddVal =<br>
             cast<ConstantSDNode>(ShVal.getNode()->getOperand(1));<br>
           uint64_t Disp = AM.Disp + (AddVal->getSExtValue() << Val);<br>
-          if (!is64Bit || isInt32(Disp))<br>
+          if (!is64Bit ||<br>
+              X86::isOffsetSuitableForCodeModel(Disp, M,<br>
+                                                AM.hasSymbolicDisplacement()))<br>
             AM.Disp = Disp;<br>
           else<br>
             AM.IndexReg = ShVal;<br>
@@ -931,7 +937,9 @@<br>
               cast<ConstantSDNode>(MulVal.getNode()->getOperand(1));<br>
             uint64_t Disp = AM.Disp + AddVal->getSExtValue() *<br>
                                       CN->getZExtValue();<br>
-            if (!is64Bit || isInt32(Disp))<br>
+            if (!is64Bit ||<br>
+                X86::isOffsetSuitableForCodeModel(Disp, M,<br>
+                                                  AM.hasSymbolicDisplacement()))<br>
               AM.Disp = Disp;<br>
             else<br>
               Reg = N.getNode()->getOperand(0);<br>
@@ -1050,7 +1058,9 @@<br>
           // Address could not have picked a GV address for the displacement.<br>
           AM.GV == NULL &&<br>
           // On x86-64, the resultant disp must fit in 32-bits.<br>
-          (!is64Bit || isInt32(AM.Disp + Offset)) &&<br>
+          (!is64Bit ||<br>
+           X86::isOffsetSuitableForCodeModel(AM.Disp + Offset, M,<br>
+                                             AM.hasSymbolicDisplacement())) &&<br>
           // Check to see if the LHS & C is zero.<br>
           CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) {<br>
         AM.Disp += Offset;<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=78255&r1=78254&r2=78255&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=78255&r1=78254&r2=78255&view=diff</a><br>

<br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Aug  5 18:01:26 2009<br>
@@ -2126,6 +2126,36 @@<br>
 }<br>
<br>
<br>
+bool X86::isOffsetSuitableForCodeModel(int64_t Offset, CodeModel::Model M,<br>
+                                       bool hasSymbolicDisplacement) {<br>
+  // Offset should fit into 32 bit immediate field.<br>
+  if (!isInt32(Offset))<br>
+    return false;<br>
+<br>
+  // If we don't have a symbolic displacement - we don't have any extra<br>
+  // restrictions.<br>
+  if (!hasSymbolicDisplacement)<br>
+    return true;<br>
+<br>
+  // FIXME: Some tweaks might be needed for medium code model.<br>
+  if (M != CodeModel::Small && M != CodeModel::Kernel)<br>
+    return false;<br>
+<br>
+  // For small code model we assume that latest object is 16MB before end of 31<br>
+  // bits boundary. We may also accept pretty large negative constants knowing<br>
+  // that all objects are in the positive half of address space.<br>
+  if (M == CodeModel::Small && Offset < 16*1024*1024)<br>
+    return true;<br>
+<br>
+  // For kernel code model we know that all object resist in the negative half<br>
+  // of 32bits address space. We may not accept negative offsets, since they may<br>
+  // be just off and we may accept pretty large positive ones.<br>
+  if (M == CodeModel::Kernel && Offset > 0)<br>
+    return true;<br>
+<br>
+  return false;<br>
+}<br>
+<br>
 /// TranslateX86CC - do a one to one translation of a ISD::CondCode to the X86<br>
 /// specific condition code, returning the condition code and the LHS/RHS of the<br>
 /// comparison to make.<br>
@@ -4440,9 +4470,10 @@<br>
   // global base reg.<br>
   unsigned char OpFlag = 0;<br>
   unsigned WrapperKind = X86ISD::Wrapper;<br>
-<br>
+  CodeModel::Model M = getTargetMachine().getCodeModel();<br>
+<br>
   if (Subtarget->isPICStyleRIPRel() &&<br>
-      getTargetMachine().getCodeModel() == CodeModel::Small)<br>
+      (M == CodeModel::Small || M == CodeModel::Kernel))<br>
     WrapperKind = X86ISD::WrapperRIP;<br>
   else if (Subtarget->isPICStyleGOT())<br>
     OpFlag = X86II::MO_GOTOFF;<br>
@@ -4472,9 +4503,10 @@<br>
   // global base reg.<br>
   unsigned char OpFlag = 0;<br>
   unsigned WrapperKind = X86ISD::Wrapper;<br>
-<br>
+  CodeModel::Model M = getTargetMachine().getCodeModel();<br>
+<br>
   if (Subtarget->isPICStyleRIPRel() &&<br>
-      getTargetMachine().getCodeModel() == CodeModel::Small)<br>
+      (M == CodeModel::Small || M == CodeModel::Kernel))<br>
     WrapperKind = X86ISD::WrapperRIP;<br>
   else if (Subtarget->isPICStyleGOT())<br>
     OpFlag = X86II::MO_GOTOFF;<br>
@@ -4505,8 +4537,10 @@<br>
   // global base reg.<br>
   unsigned char OpFlag = 0;<br>
   unsigned WrapperKind = X86ISD::Wrapper;<br>
+  CodeModel::Model M = getTargetMachine().getCodeModel();<br>
+<br>
   if (Subtarget->isPICStyleRIPRel() &&<br>
-      getTargetMachine().getCodeModel() == CodeModel::Small)<br>
+      (M == CodeModel::Small || M == CodeModel::Kernel))<br>
     WrapperKind = X86ISD::WrapperRIP;<br>
   else if (Subtarget->isPICStyleGOT())<br>
     OpFlag = X86II::MO_GOTOFF;<br>
@@ -4540,8 +4574,10 @@<br>
   // offset if it is legal.<br>
   unsigned char OpFlags =<br>
     Subtarget->ClassifyGlobalReference(GV, getTargetMachine());<br>
+  CodeModel::Model M = getTargetMachine().getCodeModel();<br>
   SDValue Result;<br>
-  if (OpFlags == X86II::MO_NO_FLAG && isInt32(Offset)) {<br>
+  if (OpFlags == X86II::MO_NO_FLAG &&<br>
+      X86::isOffsetSuitableForCodeModel(Offset, M)) {<br>
     // A direct static reference to a global.<br>
     Result = DAG.getTargetGlobalAddress(GV, getPointerTy(), Offset);<br>
     Offset = 0;<br>
@@ -4550,7 +4586,7 @@<br>
   }<br>
<br>
   if (Subtarget->isPICStyleRIPRel() &&<br>
-      getTargetMachine().getCodeModel() == CodeModel::Small)<br>
+      (M == CodeModel::Small || M == CodeModel::Kernel))<br>
     Result = DAG.getNode(X86ISD::WrapperRIP, dl, getPointerTy(), Result);<br>
   else<br>
     Result = DAG.getNode(X86ISD::Wrapper, dl, getPointerTy(), Result);<br>
@@ -7049,32 +7085,28 @@<br>
 bool X86TargetLowering::isLegalAddressingMode(const AddrMode &AM,<br>
                                               const Type *Ty) const {<br>
   // X86 supports extremely general addressing modes.<br>
+  CodeModel::Model M = getTargetMachine().getCodeModel();<br>
<br>
   // X86 allows a sign-extended 32-bit immediate field as a displacement.<br>
-  if (AM.BaseOffs <= -(1LL << 32) || AM.BaseOffs >= (1LL << 32)-1)<br>
+  if (!X86::isOffsetSuitableForCodeModel(AM.BaseOffs, M, AM.BaseGV != NULL))<br>
     return false;<br>
<br>
   if (AM.BaseGV) {<br>
     unsigned GVFlags =<br>
       Subtarget->ClassifyGlobalReference(AM.BaseGV, getTargetMachine());<br>
-<br>
+<br>
     // If a reference to this global requires an extra load, we can't fold it.<br>
     if (isGlobalStubReference(GVFlags))<br>
       return false;<br>
-<br>
+<br>
     // If BaseGV requires a register for the PIC base, we cannot also have a<br>
     // BaseReg specified.<br>
     if (AM.HasBaseReg && isGlobalRelativeToPICBase(GVFlags))<br>
       return false;<br>
<br>
-    // X86-64 only supports addr of globals in small code model.<br>
-    if (Subtarget->is64Bit()) {<br>
-      if (getTargetMachine().getCodeModel() != CodeModel::Small)<br>
-        return false;<br>
-      // If lower 4G is not available, then we must use rip-relative addressing.<br>
-      if (AM.BaseOffs || AM.Scale > 1)<br>
-        return false;<br>
-    }<br>
+    // If lower 4G is not available, then we must use rip-relative addressing.<br>
+    if (Subtarget->is64Bit() && (AM.BaseOffs || AM.Scale > 1))<br>
+      return false;<br>
   }<br>
<br>
   switch (AM.Scale) {<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=78255&r1=78254&r2=78255&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=78255&r1=78254&r2=78255&view=diff</a><br>

<br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)<br>
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Wed Aug  5 18:01:26 2009<br>
@@ -336,6 +336,11 @@<br>
     /// isZeroNode - Returns true if Elt is a constant zero or a floating point<br>
     /// constant +0.0.<br>
     bool isZeroNode(SDValue Elt);<br>
+<br>
+    /// isOffsetSuitableForCodeModel - Returns true of the given offset can be<br>
+    /// fit into displacement field of the instruction.<br>
+    bool isOffsetSuitableForCodeModel(int64_t Offset, CodeModel::Model M,<br>
+                                      bool hasSymbolicDisplacement = true);<br>
   }<br>
<br>
   //===--------------------------------------------------------------------===//<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br>