This commit changes:
authorChris Lattner <sabre@nondot.org>
Thu, 17 Jan 2008 19:59:44 +0000 (19:59 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 17 Jan 2008 19:59:44 +0000 (19:59 +0000)
1. Legalize now always promotes truncstore of i1 to i8.
2. Remove patterns and gunk related to truncstore i1 from targets.
3. Rename the StoreXAction stuff to TruncStoreAction in TLI.
4. Make the TLI TruncStoreAction table a 2d table to handle from/to conversions.
5. Mark a wide variety of invalid truncstores as such in various targets, e.g.
   X86 currently doesn't support truncstore of any of its integer types.
6. Add legalize support for truncstores with invalid value input types.
7. Add a dag combine transform to turn store(truncate) into truncstore when
   safe.

The later allows us to compile CodeGen/X86/storetrunc-fp.ll to:

_foo:
fldt 20(%esp)
fldt 4(%esp)
faddp %st(1)
movl 36(%esp), %eax
fstps (%eax)
ret

instead of:

_foo:
subl $4, %esp
fldt 24(%esp)
fldt 8(%esp)
faddp %st(1)
fstps (%esp)
movl 40(%esp), %eax
movss (%esp), %xmm0
movss %xmm0, (%eax)
addl $4, %esp
ret

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46140 91177308-0d34-0410-b5e6-96231b3b80d8

17 files changed:
include/llvm/Target/TargetLowering.h
lib/CodeGen/SelectionDAG/DAGCombiner.cpp
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/CodeGen/SelectionDAG/TargetLowering.cpp
lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMInstrThumb.td
lib/Target/Alpha/AlphaISelLowering.cpp
lib/Target/CellSPU/SPUISelLowering.cpp
lib/Target/Mips/MipsISelLowering.cpp
lib/Target/Mips/MipsInstrInfo.td
lib/Target/PowerPC/PPCISelLowering.cpp
lib/Target/Sparc/SparcInstrInfo.td
lib/Target/TargetSelectionDAG.td
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86InstrInfo.td
test/CodeGen/X86/storetrunc-fp.ll [new file with mode: 0644]

index 06c160b1b5e897ba8d4aa702d09a68268eb5b82f..25456d7c6dc4c20186a5c65b3091f12528b54e15 100644 (file)
@@ -301,19 +301,22 @@ public:
            getLoadXAction(LType, VT) == Custom;
   }
   
-  /// getStoreXAction - Return how this store with truncation should be treated:
-  /// either it is legal, needs to be promoted to a larger size, needs to be
-  /// expanded to some other code sequence, or the target has a custom expander
-  /// for it.
-  LegalizeAction getStoreXAction(MVT::ValueType VT) const {
-    if (MVT::isExtendedVT(VT)) return getTypeAction(VT);
-    return (LegalizeAction)((StoreXActions >> (2*VT)) & 3);
+  /// getTruncStoreAction - Return how this store with truncation should be
+  /// treated: either it is legal, needs to be promoted to a larger size, needs
+  /// to be expanded to some other code sequence, or the target has a custom
+  /// expander for it.
+  LegalizeAction getTruncStoreAction(MVT::ValueType ValVT, 
+                                     MVT::ValueType MemVT) const {
+    assert(ValVT < MVT::LAST_VALUETYPE && MemVT < 32 && 
+           "Table isn't big enough!");
+    return (LegalizeAction)((TruncStoreActions[ValVT] >> (2*MemVT)) & 3);
   }
   
-  /// isStoreXLegal - Return true if the specified store with truncation is
+  /// isTruncStoreLegal - Return true if the specified store with truncation is
   /// legal on this target.
-  bool isStoreXLegal(MVT::ValueType VT) const {
-    return getStoreXAction(VT) == Legal || getStoreXAction(VT) == Custom;
+  bool isTruncStoreLegal(MVT::ValueType ValVT, MVT::ValueType MemVT) const {
+    return getTruncStoreAction(ValVT, MemVT) == Legal ||
+           getTruncStoreAction(ValVT, MemVT) == Custom;
   }
 
   /// getIndexedLoadAction - Return how the indexed load should be treated:
@@ -760,12 +763,14 @@ protected:
     LoadXActions[ExtType] |= (uint64_t)Action << VT*2;
   }
   
-  /// setStoreXAction - Indicate that the specified store with truncation does
+  /// setTruncStoreAction - Indicate that the specified truncating store does
   /// not work with the with specified type and indicate what to do about it.
-  void setStoreXAction(MVT::ValueType VT, LegalizeAction Action) {
-    assert(VT < 32 && "Table isn't big enough!");
-    StoreXActions &= ~(uint64_t(3UL) << VT*2);
-    StoreXActions |= (uint64_t)Action << VT*2;
+  void setTruncStoreAction(MVT::ValueType ValVT, MVT::ValueType MemVT,
+                           LegalizeAction Action) {
+    assert(ValVT < MVT::LAST_VALUETYPE && MemVT < 32 && 
+           "Table isn't big enough!");
+    TruncStoreActions[ValVT] &= ~(uint64_t(3UL) << MemVT*2);
+    TruncStoreActions[ValVT] |= (uint64_t)Action << MemVT*2;
   }
 
   /// setIndexedLoadAction - Indicate that the specified indexed load does or
@@ -1183,10 +1188,9 @@ private:
   /// with the load.
   uint64_t LoadXActions[ISD::LAST_LOADX_TYPE];
   
-  /// StoreXActions - For each store with truncation of each value type, keep a
-  /// LegalizeAction that indicates how instruction selection should deal with
-  /// the store.
-  uint64_t StoreXActions;
+  /// TruncStoreActions - For each truncating store, keep a LegalizeAction that
+  /// indicates how instruction selection should deal with the store.
+  uint64_t TruncStoreActions[MVT::LAST_VALUETYPE];
 
   /// IndexedModeActions - For each indexed mode and each value type, keep a
   /// pair of LegalizeAction that indicates how instruction selection should
index d7a9229321382e2d76e595591ee2f6e00bfe5b9b..879a4100e210cea9fedc6bd657617b3c0876bd28 100644 (file)
@@ -1690,8 +1690,7 @@ SDOperand DAGCombiner::visitAND(SDNode *N) {
   if (N1C && N0.getOpcode() == ISD::LOAD) {
     LoadSDNode *LN0 = cast<LoadSDNode>(N0);
     if (LN0->getExtensionType() != ISD::SEXTLOAD &&
-        LN0->getAddressingMode() == ISD::UNINDEXED &&
-        N0.hasOneUse()) {
+        LN0->isUnindexed() && N0.hasOneUse()) {
       MVT::ValueType EVT, LoadedVT;
       if (N1C->getValue() == 255)
         EVT = MVT::i8;
@@ -3810,7 +3809,7 @@ bool DAGCombiner::CombineToPreIndexedLoadStore(SDNode *N) {
   SDOperand Ptr;
   MVT::ValueType VT;
   if (LoadSDNode *LD  = dyn_cast<LoadSDNode>(N)) {
-    if (LD->getAddressingMode() != ISD::UNINDEXED)
+    if (LD->isIndexed())
       return false;
     VT = LD->getLoadedVT();
     if (!TLI.isIndexedLoadLegal(ISD::PRE_INC, VT) &&
@@ -3818,7 +3817,7 @@ bool DAGCombiner::CombineToPreIndexedLoadStore(SDNode *N) {
       return false;
     Ptr = LD->getBasePtr();
   } else if (StoreSDNode *ST  = dyn_cast<StoreSDNode>(N)) {
-    if (ST->getAddressingMode() != ISD::UNINDEXED)
+    if (ST->isIndexed())
       return false;
     VT = ST->getStoredVT();
     if (!TLI.isIndexedStoreLegal(ISD::PRE_INC, VT) &&
@@ -3937,7 +3936,7 @@ bool DAGCombiner::CombineToPostIndexedLoadStore(SDNode *N) {
   SDOperand Ptr;
   MVT::ValueType VT;
   if (LoadSDNode *LD  = dyn_cast<LoadSDNode>(N)) {
-    if (LD->getAddressingMode() != ISD::UNINDEXED)
+    if (LD->isIndexed())
       return false;
     VT = LD->getLoadedVT();
     if (!TLI.isIndexedLoadLegal(ISD::POST_INC, VT) &&
@@ -3945,7 +3944,7 @@ bool DAGCombiner::CombineToPostIndexedLoadStore(SDNode *N) {
       return false;
     Ptr = LD->getBasePtr();
   } else if (StoreSDNode *ST  = dyn_cast<StoreSDNode>(N)) {
-    if (ST->getAddressingMode() != ISD::UNINDEXED)
+    if (ST->isIndexed())
       return false;
     VT = ST->getStoredVT();
     if (!TLI.isIndexedStoreLegal(ISD::POST_INC, VT) &&
@@ -4187,7 +4186,7 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) {
   // If this is a store of a bit convert, store the input value if the
   // resultant store does not need a higher alignment than the original.
   if (Value.getOpcode() == ISD::BIT_CONVERT && !ST->isTruncatingStore() &&
-      ST->getAddressingMode() == ISD::UNINDEXED) {
+      ST->isUnindexed()) {
     unsigned Align = ST->getAlignment();
     MVT::ValueType SVT = Value.getOperand(0).getValueType();
     unsigned OrigAlign = TLI.getTargetMachine().getTargetData()->
@@ -4285,7 +4284,7 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) {
     return SDOperand(N, 0);
 
   // FIXME: is there such a thing as a truncating indexed store?
-  if (ST->isTruncatingStore() && ST->getAddressingMode() == ISD::UNINDEXED &&
+  if (ST->isTruncatingStore() && ST->isUnindexed() &&
       MVT::isInteger(Value.getValueType())) {
     // See if we can simplify the input to this truncstore with knowledge that
     // only the low bits are being used.  For example:
@@ -4308,8 +4307,7 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) {
   // is dead/noop.
   if (LoadSDNode *Ld = dyn_cast<LoadSDNode>(Value)) {
     if (Ld->getBasePtr() == Ptr && ST->getStoredVT() == Ld->getLoadedVT() &&
-        ST->getAddressingMode() == ISD::UNINDEXED &&
-        !ST->isVolatile() &&
+        ST->isUnindexed() && !ST->isVolatile() &&
         // There can't be any side effects between the load and store, such as
         // a call or store.
         Chain.reachesChainWithoutSideEffects(SDOperand(Ld, 1))) {
@@ -4318,6 +4316,18 @@ SDOperand DAGCombiner::visitSTORE(SDNode *N) {
     }
   }
   
+  // If this is an FP_ROUND or TRUNC followed by a store, fold this into a
+  // truncating store.  We can do this even if this is already a truncstore.
+  if ((Value.getOpcode() == ISD::FP_ROUND || Value.getOpcode() == ISD::TRUNCATE)
+      && TLI.isTypeLegal(Value.getOperand(0).getValueType()) &&
+      Value.Val->hasOneUse() && ST->isUnindexed() &&
+      TLI.isTruncStoreLegal(Value.getOperand(0).getValueType(),
+                            ST->getStoredVT())) {
+    return DAG.getTruncStore(Chain, Value.getOperand(0), Ptr, ST->getSrcValue(),
+                             ST->getSrcValueOffset(), ST->getStoredVT(),
+                             ST->isVolatile(), ST->getAlignment());
+  }
+  
   return SDOperand();
 }
 
index 18d3a6d55a829e239534bd1c00ab86bcaf086f4f..8d7c85ce936c156a7cc7973e3e8e2acb6d2c5b20 100644 (file)
@@ -2239,15 +2239,24 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         break;
       }
     } else {
-      // Truncating store
-      assert(isTypeLegal(ST->getValue().getValueType()) &&
-             "Cannot handle illegal TRUNCSTORE yet!");
-      Tmp3 = LegalizeOp(ST->getValue());
+      switch (getTypeAction(ST->getValue().getValueType())) {
+      case Legal:
+        Tmp3 = LegalizeOp(ST->getValue());
+        break;
+      case Promote:
+        // We can promote the value, the truncstore will still take care of it.
+        Tmp3 = PromoteOp(ST->getValue());
+        break;
+      case Expand:
+        // Just store the low part.  This may become a non-trunc store, so make
+        // sure to use getTruncStore, not UpdateNodeOperands below.
+        ExpandOp(ST->getValue(), Tmp3, Tmp4);
+        return DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+                                 SVOffset, MVT::i8, isVolatile, Alignment);
+      }
     
-      // The only promote case we handle is TRUNCSTORE:i1 X into
-      //   -> TRUNCSTORE:i8 (and X, 1)
-      if (ST->getStoredVT() == MVT::i1 &&
-          TLI.getStoreXAction(MVT::i1) == TargetLowering::Promote) {
+      // Unconditionally promote TRUNCSTORE:i1 X -> TRUNCSTORE:i8 (and X, 1)
+      if (ST->getStoredVT() == MVT::i1) {
         // Promote the bool to a mask then store.
         Tmp3 = DAG.getNode(ISD::AND, Tmp3.getValueType(), Tmp3,
                            DAG.getConstant(1, Tmp3.getValueType()));
@@ -2261,7 +2270,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       }
 
       MVT::ValueType StVT = cast<StoreSDNode>(Result.Val)->getStoredVT();
-      switch (TLI.getStoreXAction(StVT)) {
+      switch (TLI.getTruncStoreAction(ST->getValue().getValueType(), StVT)) {
       default: assert(0 && "This action is not supported yet!");
       case TargetLowering::Legal:
         // If this is an unaligned store and the target doesn't support it,
@@ -2275,8 +2284,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         }
         break;
       case TargetLowering::Custom:
-        Tmp1 = TLI.LowerOperation(Result, DAG);
-        if (Tmp1.Val) Result = Tmp1;
+        Result = TLI.LowerOperation(Result, DAG);
         break;
       }
     }
index cb12b7c7329899c41855b6eb73643aadfc46b46c..8e7e87dd2943b41bcb115bc46108b2640da51d2e 100644 (file)
@@ -158,7 +158,7 @@ TargetLowering::TargetLowering(TargetMachine &tm)
   // All operations default to being supported.
   memset(OpActions, 0, sizeof(OpActions));
   memset(LoadXActions, 0, sizeof(LoadXActions));
-  memset(&StoreXActions, 0, sizeof(StoreXActions));
+  memset(TruncStoreActions, 0, sizeof(TruncStoreActions));
   memset(&IndexedModeActions, 0, sizeof(IndexedModeActions));
   memset(&ConvertActions, 0, sizeof(ConvertActions));
 
index 4d8a2372d017b02922d2429aae4fc8e5928e36bd..bdaf6b2fc506697d75006853e313a00f9e048ca3 100644 (file)
@@ -125,6 +125,8 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
   if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb()) {
     addRegisterClass(MVT::f32, ARM::SPRRegisterClass);
     addRegisterClass(MVT::f64, ARM::DPRRegisterClass);
+    
+    setTruncStoreAction(MVT::f64, MVT::f32, Expand);
   }
   computeRegisterProperties();
 
index 1027b6c3d45a718747b86fe9a8383e73deda0eb2..d3bce5d955b37bc04ef3d2f061d9968eb128ea1c 100644 (file)
@@ -1404,14 +1404,6 @@ def : ARMPat<(extloadi1  addrmode2:$addr),  (LDRB addrmode2:$addr)>;
 def : ARMPat<(extloadi8  addrmode2:$addr),  (LDRB addrmode2:$addr)>;
 def : ARMPat<(extloadi16 addrmode3:$addr),  (LDRH addrmode3:$addr)>;
 
-// truncstore i1 -> truncstore i8
-def : ARMPat<(truncstorei1 GPR:$src, addrmode2:$dst), 
-             (STRB GPR:$src, addrmode2:$dst)>;
-def : ARMPat<(pre_truncsti1 GPR:$src, GPR:$base, am2offset:$offset), 
-             (STRB_PRE GPR:$src, GPR:$base, am2offset:$offset)>;
-def : ARMPat<(post_truncsti1 GPR:$src, GPR:$base, am2offset:$offset), 
-             (STRB_POST GPR:$src, GPR:$base, am2offset:$offset)>;
-
 // smul* and smla*
 def : ARMV5TEPat<(mul (sra (shl GPR:$a, 16), 16), (sra (shl GPR:$b, 16), 16)),
                  (SMULBB GPR:$a, GPR:$b)>;
index d6fa76c9779f91bac006b2ce8ebfd7f7676a2b41..7880c235fccf641211b1af33f4fb6de47ad257e7 100644 (file)
@@ -588,10 +588,6 @@ def : ThumbPat<(extloadi1  t_addrmode_s1:$addr),  (tLDRB t_addrmode_s1:$addr)>;
 def : ThumbPat<(extloadi8  t_addrmode_s1:$addr),  (tLDRB t_addrmode_s1:$addr)>;
 def : ThumbPat<(extloadi16 t_addrmode_s2:$addr),  (tLDRH t_addrmode_s2:$addr)>;
 
-// truncstore i1 -> truncstore i8
-def : ThumbPat<(truncstorei1 GPR:$src, t_addrmode_s1:$dst), 
-               (tSTRB GPR:$src, t_addrmode_s1:$dst)>;
-
 // Large immediate handling.
 
 // Two piece imms.
index a37e8861bbc794be35db35936117dda72df23f87..c359a5bcdbeebae60f70f67fdbb0828ea073b790 100644 (file)
@@ -59,8 +59,6 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
   setLoadXAction(ISD::SEXTLOAD, MVT::i8,  Expand);
   setLoadXAction(ISD::SEXTLOAD, MVT::i16, Expand);
 
-  setStoreXAction(MVT::i1, Promote);
-  
   //  setOperationAction(ISD::BRIND,        MVT::Other,   Expand);
   setOperationAction(ISD::BR_JT,        MVT::Other, Expand);
   setOperationAction(ISD::BR_CC,        MVT::Other, Expand);
index ed6dfe069ef90fd1f750cdac02e6601767e6c5b9..e2a1b43d1a07777e4402fe9b7f53cef6c6cc3e5c 100644 (file)
@@ -129,13 +129,21 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
   setLoadXAction(ISD::EXTLOAD,  MVT::i1, Custom);
   setLoadXAction(ISD::SEXTLOAD, MVT::i1, Promote);
   setLoadXAction(ISD::ZEXTLOAD, MVT::i1, Promote);
-  setStoreXAction(MVT::i1, Custom);
+  setTruncStoreAction(MVT::i8, MVT::i1, Custom);
+  setTruncStoreAction(MVT::i16, MVT::i1, Custom);
+  setTruncStoreAction(MVT::i32, MVT::i1, Custom);
+  setTruncStoreAction(MVT::i64, MVT::i1, Custom);
+  setTruncStoreAction(MVT::i128, MVT::i1, Custom);
 
   setLoadXAction(ISD::EXTLOAD,  MVT::i8, Custom);
   setLoadXAction(ISD::SEXTLOAD, MVT::i8, Custom);
   setLoadXAction(ISD::ZEXTLOAD, MVT::i8, Custom);
-  setStoreXAction(MVT::i8, Custom);
-
+  setTruncStoreAction(MVT::i8  , MVT::i8, Custom);
+  setTruncStoreAction(MVT::i16 , MVT::i8, Custom);
+  setTruncStoreAction(MVT::i32 , MVT::i8, Custom);
+  setTruncStoreAction(MVT::i64 , MVT::i8, Custom);
+  setTruncStoreAction(MVT::i128, MVT::i8, Custom);
+  
   setLoadXAction(ISD::EXTLOAD,  MVT::i16, Custom);
   setLoadXAction(ISD::SEXTLOAD, MVT::i16, Custom);
   setLoadXAction(ISD::ZEXTLOAD, MVT::i16, Custom);
index 56527ebc3394439eceeb9bdf5ce00ee2b520d94e..fa2f72c4eba413ff714931b06d01a32096c64c28 100644 (file)
@@ -72,9 +72,6 @@ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM)
   setLoadXAction(ISD::ZEXTLOAD, MVT::i1,  Promote);
   setLoadXAction(ISD::SEXTLOAD, MVT::i1,  Promote);
 
-  // Store operations for i1 types must be promoted
-  setStoreXAction(MVT::i1, Promote);
-
   // Mips does not have these NodeTypes below.
   setOperationAction(ISD::BR_JT,     MVT::Other, Expand);
   setOperationAction(ISD::BR_CC,     MVT::Other, Expand);
index 43313e21061c052ff2265fee8d3bff20f96ac8f4..9b9e4f73df97b333fb0405055874a98dc4a89881 100644 (file)
@@ -534,8 +534,6 @@ def : Pat<(not CPURegs:$in),
 def : Pat<(i32 (extloadi1  addr:$src)), (LBu addr:$src)>;
 def : Pat<(i32 (extloadi8  addr:$src)), (LBu addr:$src)>;
 def : Pat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
-def : Pat<(truncstorei1 CPURegs:$src, addr:$addr),
-           (SB CPURegs:$src, addr:$addr)>;
 
 // some peepholes
 def : Pat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
index af9bb79db1574da64e2f380b2f15067cd93e67b1..6a35bafaf4a4fe6c76977f75154a83f4086d0af1 100644 (file)
@@ -54,10 +54,9 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
   // PowerPC has an i16 but no i8 (or i1) SEXTLOAD
   setLoadXAction(ISD::SEXTLOAD, MVT::i1, Expand);
   setLoadXAction(ISD::SEXTLOAD, MVT::i8, Expand);
-  
-  // PowerPC does not have truncstore for i1.
-  setStoreXAction(MVT::i1, Promote);
-
+    
+  setTruncStoreAction(MVT::f64, MVT::f32, Expand);
+    
   // PowerPC has pre-inc load and store's.
   setIndexedLoadAction(ISD::PRE_INC, MVT::i1, Legal);
   setIndexedLoadAction(ISD::PRE_INC, MVT::i8, Legal);
index 061cfab973a50895e7037a69d7bf4a26e792285f..71fa8877cd5b949371161233bf2eabe86510738d 100644 (file)
@@ -774,9 +774,3 @@ def : Pat<(i32 (extloadi16 ADDRri:$src)), (LDUHri ADDRri:$src)>;
 // zextload bool -> zextload byte
 def : Pat<(i32 (zextloadi1 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>;
 def : Pat<(i32 (zextloadi1 ADDRri:$src)), (LDUBri ADDRri:$src)>;
-
-// truncstore bool -> truncstore byte.
-def : Pat<(truncstorei1 IntRegs:$src, ADDRrr:$addr),
-          (STBrr ADDRrr:$addr, IntRegs:$src)>;
-def : Pat<(truncstorei1 IntRegs:$src, ADDRri:$addr), 
-          (STBri ADDRri:$addr, IntRegs:$src)>;
index 696f815d02a8a3865a4c154c818c07ac6279364a..2560d86f52df8c7206ee047c8be095c5c17f11ad 100644 (file)
@@ -551,13 +551,6 @@ def store : PatFrag<(ops node:$val, node:$ptr),
 }]>;
 
 // truncstore fragments.
-def truncstorei1 : PatFrag<(ops node:$val, node:$ptr),
-                           (st node:$val, node:$ptr), [{
-  if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N))
-    return ST->isTruncatingStore() && ST->getStoredVT() == MVT::i1 &&
-           ST->getAddressingMode() == ISD::UNINDEXED;
-  return false;
-}]>;
 def truncstorei8 : PatFrag<(ops node:$val, node:$ptr),
                            (st node:$val, node:$ptr), [{
   if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N))
index 2b58826fc8bce049f59a96c199a89593b8f1022b..bd1ee55345e196eff31fa4d49d6e7b42b456a13a 100644 (file)
@@ -82,6 +82,14 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
 
   setLoadXAction(ISD::SEXTLOAD, MVT::i1, Expand);
 
+  // We don't accept any truncstore of integer registers.  
+  setTruncStoreAction(MVT::i64, MVT::i32, Expand);
+  setTruncStoreAction(MVT::i64, MVT::i16, Expand);
+  setTruncStoreAction(MVT::i64, MVT::i8 , Expand);
+  setTruncStoreAction(MVT::i32, MVT::i16, Expand);
+  setTruncStoreAction(MVT::i32, MVT::i8 , Expand);
+  setTruncStoreAction(MVT::i16, MVT::i8, Expand);
+
   // Promote all UINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have this
   // operation.
   setOperationAction(ISD::UINT_TO_FP       , MVT::i1   , Promote);
@@ -638,6 +646,8 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
       AddPromotedToType (ISD::SELECT, (MVT::ValueType)VT, MVT::v2i64);
     }
 
+    setTruncStoreAction(MVT::f64, MVT::f32, Expand);
+    
     // Custom lower v2i64 and v2f64 selects.
     setOperationAction(ISD::LOAD,               MVT::v2f64, Legal);
     setOperationAction(ISD::LOAD,               MVT::v2i64, Legal);
index de705de390d4a1148ceba2c68046e792773909a0..f5a5803dbf2adea29072f0cad10ee434da4e1243 100644 (file)
@@ -2598,11 +2598,6 @@ def : Pat<(subc GR32:$src1, imm:$src2),
 def : Pat<(subc GR32:$src1, i32immSExt8:$src2),
           (SUB32ri8 GR32:$src1, i32immSExt8:$src2)>;
 
-def : Pat<(truncstorei1 (i8 imm:$src), addr:$dst), 
-          (MOV8mi addr:$dst, imm:$src)>;
-def : Pat<(truncstorei1 GR8:$src, addr:$dst), 
-          (MOV8mr addr:$dst, GR8:$src)>;
-
 // Comparisons.
 
 // TEST R,R is smaller than CMP R,0
diff --git a/test/CodeGen/X86/storetrunc-fp.ll b/test/CodeGen/X86/storetrunc-fp.ll
new file mode 100644 (file)
index 0000000..655cbd6
--- /dev/null
@@ -0,0 +1,8 @@
+; RUN: llvm-as < %s | llc -march=x86 | not grep flds
+
+define void @foo(x86_fp80 %a, x86_fp80 %b, float* %fp) {
+       %c = add x86_fp80 %a, %b
+       %d = fptrunc x86_fp80 %c to float
+       store float %d, float* %fp
+       ret void
+}