diff options
-rw-r--r-- | include/llvm/Target/TargetLowering.h | 42 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 30 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 30 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/TargetLowering.cpp | 2 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 2 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 8 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb.td | 4 | ||||
-rw-r--r-- | lib/Target/Alpha/AlphaISelLowering.cpp | 2 | ||||
-rw-r--r-- | lib/Target/CellSPU/SPUISelLowering.cpp | 14 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 3 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.td | 2 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCISelLowering.cpp | 7 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcInstrInfo.td | 6 | ||||
-rw-r--r-- | lib/Target/TargetSelectionDAG.td | 7 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 10 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.td | 5 | ||||
-rw-r--r-- | test/CodeGen/X86/storetrunc-fp.ll | 8 |
17 files changed, 97 insertions, 85 deletions
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 06c160b1b5..25456d7c6d 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -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 diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d7a9229321..879a4100e2 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -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(); } diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 18d3a6d55a..8d7c85ce93 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -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; } } diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index cb12b7c732..8e7e87dd29 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -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)); diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 4d8a2372d0..bdaf6b2fc5 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -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(); diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 1027b6c3d4..d3bce5d955 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -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)>; diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index d6fa76c977..7880c235fc 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -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. diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp index a37e8861bb..c359a5bcdb 100644 --- a/lib/Target/Alpha/AlphaISelLowering.cpp +++ b/lib/Target/Alpha/AlphaISelLowering.cpp @@ -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); diff --git a/lib/Target/CellSPU/SPUISelLowering.cpp b/lib/Target/CellSPU/SPUISelLowering.cpp index ed6dfe069e..e2a1b43d1a 100644 --- a/lib/Target/CellSPU/SPUISelLowering.cpp +++ b/lib/Target/CellSPU/SPUISelLowering.cpp @@ -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); diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 56527ebc33..fa2f72c4eb 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -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); diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 43313e2106..9b9e4f73df 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -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)>; diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index af9bb79db1..6a35bafaf4 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -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); diff --git a/lib/Target/Sparc/SparcInstrInfo.td b/lib/Target/Sparc/SparcInstrInfo.td index 061cfab973..71fa8877cd 100644 --- a/lib/Target/Sparc/SparcInstrInfo.td +++ b/lib/Target/Sparc/SparcInstrInfo.td @@ -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)>; diff --git a/lib/Target/TargetSelectionDAG.td b/lib/Target/TargetSelectionDAG.td index 696f815d02..2560d86f52 100644 --- a/lib/Target/TargetSelectionDAG.td +++ b/lib/Target/TargetSelectionDAG.td @@ -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)) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 2b58826fc8..bd1ee55345 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -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); diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index de705de390..f5a5803dbf 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -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 index 0000000000..655cbd68b3 --- /dev/null +++ b/test/CodeGen/X86/storetrunc-fp.ll @@ -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 +} |