[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.396 - 1.397 X86ISelLowering.h updated: 1.99 - 1.100 --- Log message: Support for the special case of a vector with the canonical form: vector_shuffle v1, v2, 2, 6, 3, 7 I.e. vector_shuffle v, undef, 2, 2, 3, 3 MMX only has a shuffle for v4i16 vectors. It needs to use the unpackh for this type of operation. --- Diffs of the changes: (+35 -2) X86ISelLowering.cpp | 32 ++-- X86ISelLowering.h |5 + 2 files changed, 35 insertions(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.396 llvm/lib/Target/X86/X86ISelLowering.cpp:1.397 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.396 Sun Apr 22 17:50:52 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Apr 24 16:16:55 2007 @@ -379,6 +379,8 @@ setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v8i8, Custom); setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v4i16, Custom); +setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v2i32, Custom); +setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v1i64, Custom); } if (Subtarget-hasSSE1()) { @@ -1776,7 +1778,7 @@ assert(N-getOpcode() == ISD::BUILD_VECTOR); unsigned NumElems = N-getNumOperands(); - if (NumElems != 4 NumElems != 8 NumElems != 16) + if (NumElems != 2 NumElems != 4 NumElems != 8 NumElems != 16) return false; for (unsigned i = 0, j = 0; i != NumElems; i += 2, ++j) { @@ -1792,6 +1794,29 @@ return true; } +/// isUNPCKH_v_undef_Mask - Special case of isUNPCKHMask for canonical form +/// of vector_shuffle v, v, 2, 6, 3, 7, i.e. vector_shuffle v, undef, +/// 2, 2, 3, 3 +bool X86::isUNPCKH_v_undef_Mask(SDNode *N) { + assert(N-getOpcode() == ISD::BUILD_VECTOR); + + unsigned NumElems = N-getNumOperands(); + if (NumElems != 2 NumElems != 4 NumElems != 8 NumElems != 16) +return false; + + for (unsigned i = 0, j = NumElems / 2; i != NumElems; i += 2, ++j) { +SDOperand BitI = N-getOperand(i); +SDOperand BitI1 = N-getOperand(i + 1); + +if (!isUndefOrEqual(BitI, j)) + return false; +if (!isUndefOrEqual(BitI1, j)) + return false; + } + + return true; +} + /// isMOVLMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a shuffle of elements that is suitable for input to MOVSS, /// MOVSD, and MOVD, i.e. setting the lowest element. @@ -2432,7 +2457,7 @@ } } - // Let legalizer expand 2-wide build_vector's. + // Let legalizer expand 2-wide build_vectors. if (EVTBits == 64) return SDOperand(); @@ -2591,6 +2616,7 @@ } if (X86::isUNPCKL_v_undef_Mask(PermMask.Val) || + X86::isUNPCKH_v_undef_Mask(PermMask.Val) || X86::isUNPCKLMask(PermMask.Val) || X86::isUNPCKHMask(PermMask.Val)) return Op; @@ -2619,6 +2645,7 @@ // Commute is back and try unpck* again. Op = CommuteVectorShuffle(Op, V1, V2, PermMask, DAG); if (X86::isUNPCKL_v_undef_Mask(PermMask.Val) || +X86::isUNPCKH_v_undef_Mask(PermMask.Val) || X86::isUNPCKLMask(PermMask.Val) || X86::isUNPCKHMask(PermMask.Val)) return Op; @@ -4231,6 +4258,7 @@ isPSHUFHW_PSHUFLWMask(Mask.Val) || X86::isUNPCKLMask(Mask.Val) || X86::isUNPCKL_v_undef_Mask(Mask.Val) || + X86::isUNPCKH_v_undef_Mask(Mask.Val) || X86::isUNPCKHMask(Mask.Val)); } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.99 llvm/lib/Target/X86/X86ISelLowering.h:1.100 --- llvm/lib/Target/X86/X86ISelLowering.h:1.99 Fri Apr 20 16:38:10 2007 +++ llvm/lib/Target/X86/X86ISelLowering.h Tue Apr 24 16:16:55 2007 @@ -231,6 +231,11 @@ /// 0, 0, 1, 1 bool isUNPCKL_v_undef_Mask(SDNode *N); + /// isUNPCKH_v_undef_Mask - Special case of isUNPCKHMask for canonical form + /// of vector_shuffle v, v, 2, 6, 3, 7, i.e. vector_shuffle v, undef, + /// 2, 2, 3, 3 + bool isUNPCKH_v_undef_Mask(SDNode *N); + /// isMOVLMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a shuffle of elements that is suitable for input to MOVSS, /// MOVSD, and MOVD, i.e. setting the lowest element. ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
Re: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td X86RegisterInfo.cpp
Implemented correct stack probing on mingw/cygwin for dynamic alloca's. Also, fixed static case in presence of eax livin. This fixes PR331: http://llvm.org/PR331 Cool :) +SDOperand X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDOperand Op, + SelectionDAG DAG) { Please add a comment above this that explains why this lowering is needed. Also, please assert that the subtarget isCygMing() on entry, to make it obvious to the reader that this is cygwin-specific lowering code. Thanks Anton! -Chris ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.386 - 1.387 X86ISelLowering.h updated: 1.95 - 1.96 --- Log message: remove some dead target hooks, subsumed by isLegalAddressingMode --- Diffs of the changes: (+0 -28) X86ISelLowering.cpp | 16 X86ISelLowering.h | 12 2 files changed, 28 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.386 llvm/lib/Target/X86/X86ISelLowering.cpp:1.387 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.386 Mon Apr 9 00:49:22 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Mon Apr 9 17:26:30 2007 @@ -4127,22 +4127,6 @@ } } -/// isLegalAddressScaleAndImm - Return true if S works for IsLegalAddressScale -/// and V works for isLegalAddressImmediate _and_ both can be applied -/// simultaneously to the same instruction. -bool X86TargetLowering::isLegalAddressScaleAndImm(int64_t S, int64_t V, - const Type* Ty) const { - return isLegalAddressScale(S, Ty) isLegalAddressImmediate(V, Ty); -} - -/// isLegalAddressScaleAndImm - Return true if S works for IsLegalAddressScale -/// and GV works for isLegalAddressImmediate _and_ both can be applied -/// simultaneously to the same instruction. -bool X86TargetLowering::isLegalAddressScaleAndImm(int64_t S, GlobalValue *GV, - const Type* Ty) const { - return isLegalAddressScale(S, Ty) isLegalAddressImmediate(GV); -} - /// isShuffleMaskLegal - Targets can use this to indicate that they only /// support *some* VECTOR_SHUFFLE operations, those with specific masks. /// By default, if a target supports the VECTOR_SHUFFLE node, all mask values Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.95 llvm/lib/Target/X86/X86ISelLowering.h:1.96 --- llvm/lib/Target/X86/X86ISelLowering.h:1.95 Fri Mar 30 18:15:24 2007 +++ llvm/lib/Target/X86/X86ISelLowering.h Mon Apr 9 17:26:30 2007 @@ -353,18 +353,6 @@ /// type. virtual bool isLegalAddressScale(int64_t S, const Type *Ty) const; -/// isLegalAddressScaleAndImm - Return true if S works for -/// IsLegalAddressScale and V works for isLegalAddressImmediate _and_ -/// both can be applied simultaneously to the same instruction. -virtual bool isLegalAddressScaleAndImm(int64_t S, int64_t V, - const Type *Ty) const; - -/// isLegalAddressScaleAndImm - Return true if S works for -/// IsLegalAddressScale and GV works for isLegalAddressImmediate _and_ -/// both can be applied simultaneously to the same instruction. -virtual bool isLegalAddressScaleAndImm(int64_t S, GlobalValue *GV, - const Type *Ty) const; - /// isShuffleMaskLegal - Targets can use this to indicate that they only /// support *some* VECTOR_SHUFFLE operations, those with specific masks. /// By default, if a target supports the VECTOR_SHUFFLE node, all mask ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.387 - 1.388 X86ISelLowering.h updated: 1.96 - 1.97 --- Log message: remove some dead hooks --- Diffs of the changes: (+0 -49) X86ISelLowering.cpp | 35 --- X86ISelLowering.h | 14 -- 2 files changed, 49 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.387 llvm/lib/Target/X86/X86ISelLowering.cpp:1.388 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.387 Mon Apr 9 17:26:30 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Mon Apr 9 18:31:19 2007 @@ -4092,41 +4092,6 @@ } -/// isLegalAddressImmediate - Return true if the integer value can be used -/// as the offset of the target addressing mode for load / store of the -/// given type. -bool X86TargetLowering::isLegalAddressImmediate(int64_t V,const Type *Ty) const{ - // X86 allows a sign-extended 32-bit immediate field. - return (V -(1LL 32) V (1LL 32)-1); -} - -/// isLegalAddressImmediate - Return true if the GlobalValue can be used as -/// the offset of the target addressing mode. -bool X86TargetLowering::isLegalAddressImmediate(GlobalValue *GV) const { - // In 64-bit mode, GV is 64-bit so it won't fit in the 32-bit displacement - // field unless we are in small code model. - if (Subtarget-is64Bit() - getTargetMachine().getCodeModel() != CodeModel::Small) -return false; - - return (!Subtarget-GVRequiresExtraLoad(GV, getTargetMachine(), false)); -} - -/// isLegalAddressScale - Return true if the integer value can be used as the -/// scale of the target addressing mode for load / store of the given type. -bool X86TargetLowering::isLegalAddressScale(int64_t S, const Type *Ty) const { - switch (S) { - default: -return false; - case 2: case 4: case 8: -return true; - // FIXME: These require both scale + index last and thus more expensive. - // How to tell LSR to try for 2, 4, 8 first? - case 3: case 5: case 9: -return true; - } -} - /// isShuffleMaskLegal - Targets can use this to indicate that they only /// support *some* VECTOR_SHUFFLE operations, those with specific masks. /// By default, if a target supports the VECTOR_SHUFFLE node, all mask values Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.96 llvm/lib/Target/X86/X86ISelLowering.h:1.97 --- llvm/lib/Target/X86/X86ISelLowering.h:1.96 Mon Apr 9 17:26:30 2007 +++ llvm/lib/Target/X86/X86ISelLowering.h Mon Apr 9 18:31:19 2007 @@ -339,20 +339,6 @@ /// by AM is legal for this target, for a load/store of the specified type. virtual bool isLegalAddressingMode(const AddrMode AM, const Type *Ty)const; -/// isLegalAddressImmediate - Return true if the integer value can be used -/// as the offset of the target addressing mode for load / store of the -/// given type. -virtual bool isLegalAddressImmediate(int64_t V, const Type *Ty) const; - -/// isLegalAddressImmediate - Return true if the GlobalValue can be used as -/// the offset of the target addressing mode. -virtual bool isLegalAddressImmediate(GlobalValue *GV) const; - -/// isLegalAddressScale - Return true if the integer value can be used as -/// the scale of the target addressing mode for load / store of the given -/// type. -virtual bool isLegalAddressScale(int64_t S, const Type *Ty) const; - /// isShuffleMaskLegal - Targets can use this to indicate that they only /// support *some* VECTOR_SHUFFLE operations, those with specific masks. /// By default, if a target supports the VECTOR_SHUFFLE node, all mask ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.382 - 1.383 X86ISelLowering.h updated: 1.94 - 1.95 --- Log message: implement the new addressing mode description hook. --- Diffs of the changes: (+49 -0) X86ISelLowering.cpp | 45 + X86ISelLowering.h |4 2 files changed, 49 insertions(+) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.382 llvm/lib/Target/X86/X86ISelLowering.cpp:1.383 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.382 Tue Mar 27 20:02:54 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Mar 30 18:15:24 2007 @@ -4047,6 +4047,51 @@ } } +// isLegalAddressingMode - Return true if the addressing mode represented +// by AM is legal for this target, for a load/store of the specified type. +bool X86TargetLowering::isLegalAddressingMode(const AddrMode AM, + const Type *Ty) const { + // X86 supports extremely general addressing modes. + + // X86 allows a sign-extended 32-bit immediate field as a displacement. + if (AM.BaseOffs = -(1LL 32) || AM.BaseOffs = (1LL 32)-1) +return false; + + if (AM.BaseGV) { +// X86-64 only supports addr of globals in small code model. +if (Subtarget-is64Bit() +getTargetMachine().getCodeModel() != CodeModel::Small) + return false; + +// We can only fold this if we don't need a load either. +if (Subtarget-GVRequiresExtraLoad(AM.BaseGV, getTargetMachine(), false)) + return false; + } + + switch (AM.Scale) { + case 0: + case 1: + case 2: + case 4: + case 8: +// These scales always work. +break; + case 3: + case 5: + case 9: +// These scales are formed with basereg+scalereg. Only accept if there is +// no basereg yet. +if (AM.HasBaseReg) + return false; +break; + default: // Other stuff never works. +return false; + } + + return true; +} + + /// isLegalAddressImmediate - Return true if the integer value can be used /// as the offset of the target addressing mode for load / store of the /// given type. Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.94 llvm/lib/Target/X86/X86ISelLowering.h:1.95 --- llvm/lib/Target/X86/X86ISelLowering.h:1.94 Sat Mar 24 21:14:49 2007 +++ llvm/lib/Target/X86/X86ISelLowering.h Fri Mar 30 18:15:24 2007 @@ -335,6 +335,10 @@ getRegForInlineAsmConstraint(const std::string Constraint, MVT::ValueType VT) const; +/// isLegalAddressingMode - Return true if the addressing mode represented +/// by AM is legal for this target, for a load/store of the specified type. +virtual bool isLegalAddressingMode(const AddrMode AM, const Type *Ty)const; + /// isLegalAddressImmediate - Return true if the integer value can be used /// as the offset of the target addressing mode for load / store of the /// given type. ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.376 - 1.377 X86ISelLowering.h updated: 1.93 - 1.94 --- Log message: switch TargetLowering::getConstraintType to take the entire constraint, not just the first letter. No functionality change. --- Diffs of the changes: (+17 -13) X86ISelLowering.cpp | 28 X86ISelLowering.h |2 +- 2 files changed, 17 insertions(+), 13 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.376 llvm/lib/Target/X86/X86ISelLowering.cpp:1.377 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.376 Sat Mar 24 20:57:35 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Sat Mar 24 21:14:49 2007 @@ -4521,19 +4521,23 @@ /// getConstraintType - Given a constraint letter, return the type of /// constraint it is for this target. X86TargetLowering::ConstraintType -X86TargetLowering::getConstraintType(char ConstraintLetter) const { - switch (ConstraintLetter) { - case 'A': - case 'r': - case 'R': - case 'l': - case 'q': - case 'Q': - case 'x': - case 'Y': -return C_RegisterClass; - default: return TargetLowering::getConstraintType(ConstraintLetter); +X86TargetLowering::getConstraintType(const std::string Constraint) const { + if (Constraint.size() == 1) { +switch (Constraint[0]) { +case 'A': +case 'r': +case 'R': +case 'l': +case 'q': +case 'Q': +case 'x': +case 'Y': + return C_RegisterClass; +default: + break; +} } + return TargetLowering::getConstraintType(Constraint); } /// isOperandValidForConstraint - Return the specified operand (possibly Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.93 llvm/lib/Target/X86/X86ISelLowering.h:1.94 --- llvm/lib/Target/X86/X86ISelLowering.h:1.93 Wed Mar 21 16:51:52 2007 +++ llvm/lib/Target/X86/X86ISelLowering.h Sat Mar 24 21:14:49 2007 @@ -316,7 +316,7 @@ SDOperand getReturnAddressFrameIndex(SelectionDAG DAG); -ConstraintType getConstraintType(char ConstraintLetter) const; +ConstraintType getConstraintType(const std::string Constraint) const; std::vectorunsigned getRegClassForInlineAsmConstraint(const std::string Constraint, ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.367 - 1.368 X86ISelLowering.h updated: 1.91 - 1.92 --- Log message: More flexible TargetLowering LSR hooks for testing whether an immediate is a legal target address immediate or scale. --- Diffs of the changes: (+33 -16) X86ISelLowering.cpp | 34 +- X86ISelLowering.h | 15 --- 2 files changed, 33 insertions(+), 16 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.367 llvm/lib/Target/X86/X86ISelLowering.cpp:1.368 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.367 Mon Mar 12 17:58:52 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Mon Mar 12 18:28:50 2007 @@ -64,16 +64,6 @@ setUseUnderscoreLongJmp(true); } - // Add legal addressing mode scale values. - addLegalAddressScale(8); - addLegalAddressScale(4); - addLegalAddressScale(2); - // Enter the ones which require both scale + index last. These are more - // expensive. - addLegalAddressScale(9); - addLegalAddressScale(5); - addLegalAddressScale(3); - // Set up the register classes. addRegisterClass(MVT::i8, X86::GR8RegisterClass); addRegisterClass(MVT::i16, X86::GR16RegisterClass); @@ -4016,13 +4006,16 @@ } } -/// isLegalAddressImmediate - Return true if the integer value or -/// GlobalValue can be used as the offset of the target addressing mode. -bool X86TargetLowering::isLegalAddressImmediate(int64_t V) const { +/// isLegalAddressImmediate - Return true if the integer value can be used +/// as the offset of the target addressing mode for load / store of the +/// given type. +bool X86TargetLowering::isLegalAddressImmediate(int64_t V,const Type *Ty) const{ // X86 allows a sign-extended 32-bit immediate field. return (V -(1LL 32) V (1LL 32)-1); } +/// isLegalAddressImmediate - Return true if the GlobalValue can be used as +/// the offset of the target addressing mode. bool X86TargetLowering::isLegalAddressImmediate(GlobalValue *GV) const { // In 64-bit mode, GV is 64-bit so it won't fit in the 32-bit displacement // field unless we are in small code model. @@ -4033,6 +4026,21 @@ return (!Subtarget-GVRequiresExtraLoad(GV, getTargetMachine(), false)); } +/// isLegalAddressScale - Return true if the integer value can be used as the +/// scale of the target addressing mode for load / store of the given type. +bool X86TargetLowering::isLegalAddressScale(int64_t S, const Type *Ty) const { + switch (S) { + default: +return false; + case 2: case 4: case 8: +return true; + // FIXME: These require both scale + index last and thus more expensive. + // How to tell LSR to try for 2, 4, 8 first? + case 3: case 5: case 9: +return true; + } +} + /// isShuffleMaskLegal - Targets can use this to indicate that they only /// support *some* VECTOR_SHUFFLE operations, those with specific masks. /// By default, if a target supports the VECTOR_SHUFFLE node, all mask values Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.91 llvm/lib/Target/X86/X86ISelLowering.h:1.92 --- llvm/lib/Target/X86/X86ISelLowering.h:1.91 Fri Mar 2 17:16:35 2007 +++ llvm/lib/Target/X86/X86ISelLowering.h Mon Mar 12 18:28:50 2007 @@ -335,11 +335,20 @@ getRegForInlineAsmConstraint(const std::string Constraint, MVT::ValueType VT) const; -/// isLegalAddressImmediate - Return true if the integer value or -/// GlobalValue can be used as the offset of the target addressing mode. -virtual bool isLegalAddressImmediate(int64_t V) const; +/// isLegalAddressImmediate - Return true if the integer value can be used +/// as the offset of the target addressing mode for load / store of the +/// given type. +virtual bool isLegalAddressImmediate(int64_t V, const Type *Ty) const; + +/// isLegalAddressImmediate - Return true if the GlobalValue can be used as +/// the offset of the target addressing mode. virtual bool isLegalAddressImmediate(GlobalValue *GV) const; +/// isLegalAddressScale - Return true if the integer value can be used as +/// the scale of the target addressing mode for load / store of the given +/// type. +virtual bool isLegalAddressScale(int64_t S, const Type *Ty) const; + /// isShuffleMaskLegal - Targets can use this to indicate that they only /// support *some* VECTOR_SHUFFLE operations, those with specific masks. /// By default, if a target supports the VECTOR_SHUFFLE node, all mask ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.359 - 1.360 X86ISelLowering.h updated: 1.90 - 1.91 --- Log message: X86-64 VACOPY needs custom expansion. va_list is a struct { i32, i32, i8*, i8* }. --- Diffs of the changes: (+34 -3) X86ISelLowering.cpp | 36 +--- X86ISelLowering.h |1 + 2 files changed, 34 insertions(+), 3 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.359 llvm/lib/Target/X86/X86ISelLowering.cpp:1.360 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.359 Fri Mar 2 15:50:27 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Mar 2 17:16:35 2007 @@ -236,11 +236,13 @@ // VASTART needs to be custom lowered to use the VarArgsFrameIndex setOperationAction(ISD::VASTART , MVT::Other, Custom); - - // Use the default implementation. setOperationAction(ISD::VAARG , MVT::Other, Expand); - setOperationAction(ISD::VACOPY, MVT::Other, Expand); setOperationAction(ISD::VAEND , MVT::Other, Expand); + if (Subtarget-is64Bit()) +setOperationAction(ISD::VACOPY , MVT::Other, Custom); + else +setOperationAction(ISD::VACOPY , MVT::Other, Expand); + setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); if (Subtarget-is64Bit()) @@ -3761,6 +3763,33 @@ return DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps[0], MemOps.size()); } +SDOperand X86TargetLowering::LowerVACOPY(SDOperand Op, SelectionDAG DAG) { + // X86-64 va_list is a struct { i32, i32, i8*, i8* }. + SDOperand Chain = Op.getOperand(0); + SDOperand DstPtr = Op.getOperand(1); + SDOperand SrcPtr = Op.getOperand(2); + SrcValueSDNode *DstSV = castSrcValueSDNode(Op.getOperand(3)); + SrcValueSDNode *SrcSV = castSrcValueSDNode(Op.getOperand(4)); + + SrcPtr = DAG.getLoad(getPointerTy(), Chain, SrcPtr, + SrcSV-getValue(), SrcSV-getOffset()); + Chain = SrcPtr.getValue(1); + for (unsigned i = 0; i 3; ++i) { +SDOperand Val = DAG.getLoad(MVT::i64, Chain, SrcPtr, +SrcSV-getValue(), SrcSV-getOffset()); +Chain = Val.getValue(1); +Chain = DAG.getStore(Chain, Val, DstPtr, + DstSV-getValue(), DstSV-getOffset()); +if (i == 2) + break; +SrcPtr = DAG.getNode(ISD::ADD, getPointerTy(), SrcPtr, + DAG.getConstant(8, getPointerTy())); +DstPtr = DAG.getNode(ISD::ADD, getPointerTy(), DstPtr, + DAG.getConstant(8, getPointerTy())); + } + return Chain; +} + SDOperand X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG DAG) { unsigned IntNo = castConstantSDNode(Op.getOperand(0))-getValue(); @@ -3925,6 +3954,7 @@ case ISD::MEMCPY: return LowerMEMCPY(Op, DAG); case ISD::READCYCLECOUNTER: return LowerREADCYCLCECOUNTER(Op, DAG); case ISD::VASTART:return LowerVASTART(Op, DAG); + case ISD::VACOPY: return LowerVACOPY(Op, DAG); case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG); case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.90 llvm/lib/Target/X86/X86ISelLowering.h:1.91 --- llvm/lib/Target/X86/X86ISelLowering.h:1.90 Wed Feb 28 00:05:16 2007 +++ llvm/lib/Target/X86/X86ISelLowering.h Fri Mar 2 17:16:35 2007 @@ -405,6 +405,7 @@ SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG DAG); SDOperand LowerREADCYCLCECOUNTER(SDOperand Op, SelectionDAG DAG); SDOperand LowerVASTART(SDOperand Op, SelectionDAG DAG); +SDOperand LowerVACOPY(SDOperand Op, SelectionDAG DAG); SDOperand LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG DAG); SDOperand LowerRETURNADDR(SDOperand Op, SelectionDAG DAG); SDOperand LowerFRAMEADDR(SDOperand Op, SelectionDAG DAG); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.349 - 1.350 X86ISelLowering.h updated: 1.89 - 1.90 --- Log message: remove fastcc (not fastcall) support --- Diffs of the changes: (+26 -58) X86ISelLowering.cpp | 65 X86ISelLowering.h | 19 --- 2 files changed, 26 insertions(+), 58 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.349 llvm/lib/Target/X86/X86ISelLowering.cpp:1.350 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.349 Tue Feb 27 23:46:49 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Feb 28 00:05:16 2007 @@ -1223,8 +1223,7 @@ // bytes, which is needed for tail recursion elimination and stack alignment // reasons. SDOperand -X86TargetLowering::LowerFastCCArguments(SDOperand Op, SelectionDAG DAG, -bool isFastCall) { +X86TargetLowering::LowerFastCCArguments(SDOperand Op, SelectionDAG DAG) { unsigned NumArgs = Op.Val-getNumValues()-1; MachineFunction MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); @@ -1250,17 +1249,16 @@ X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3 }; - static const unsigned GPRArgRegs[][2][2] = { -{{ X86::AL, X86::DL }, { X86::CL, X86::DL }}, -{{ X86::AX, X86::DX }, { X86::CX, X86::DX }}, -{{ X86::EAX, X86::EDX }, { X86::ECX, X86::EDX }} + static const unsigned GPRArgRegs[][2] = { +{ X86::CL, X86::DL }, +{ X86::CX, X86::DX }, +{ X86::ECX, X86::EDX } }; static const TargetRegisterClass* GPRClasses[3] = { X86::GR8RegisterClass, X86::GR16RegisterClass, X86::GR32RegisterClass }; - unsigned GPRInd = (isFastCall ? 1 : 0); for (unsigned i = 0; i NumArgs; ++i) { MVT::ValueType ObjectVT = Op.getValue(i).getValueType(); unsigned ArgIncrement = 4; @@ -1272,8 +1270,7 @@ HowToPassCallArgument(ObjectVT, true, // Use as much registers as possible - NumIntRegs, NumXMMRegs, - (isFastCall ? 2 : FASTCC_NUM_INT_ARGS_INREGS), + NumIntRegs, NumXMMRegs, 2, ObjSize, ObjIntRegs, ObjXMMRegs); if (ObjSize 4) @@ -1285,7 +1282,7 @@ case MVT::i8: case MVT::i16: case MVT::i32: { -unsigned RegToUse = GPRArgRegs[ObjectVT-MVT::i8][GPRInd][NumIntRegs]; +unsigned RegToUse = GPRArgRegs[ObjectVT-MVT::i8][NumIntRegs]; Reg = AddLiveIn(MF, RegToUse, GPRClasses[ObjectVT-MVT::i8]); ArgValue = DAG.getCopyFromReg(Root, Reg, ObjectVT); break; @@ -1296,7 +1293,6 @@ case MVT::v2i64: case MVT::v4f32: case MVT::v2f64: { -assert(!isFastCall Unhandled argument type!); Reg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs], X86::VR128RegisterClass); ArgValue = DAG.getCopyFromReg(Root, Reg, ObjectVT); break; @@ -1360,7 +1356,6 @@ case MVT::v2i64: case MVT::v4f32: case MVT::v2f64: -assert(!isFastCall Unknown result type); MF.addLiveOut(X86::XMM0); break; } @@ -1386,17 +1381,15 @@ unsigned NumIntRegs = 0; unsigned NumXMMRegs = 0; // XMM regs used for parameter passing. - static const unsigned GPRArgRegs[][2][2] = { -{{ X86::AL, X86::DL }, { X86::CL, X86::DL }}, -{{ X86::AX, X86::DX }, { X86::CX, X86::DX }}, -{{ X86::EAX, X86::EDX }, { X86::ECX, X86::EDX }} + static const unsigned GPRArgRegs[][2] = { +{ X86::CL, X86::DL }, +{ X86::CX, X86::DX }, +{ X86::ECX, X86::EDX } }; static const unsigned XMMArgRegs[] = { X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3 }; - bool isFastCall = CC == CallingConv::X86_FastCall; - unsigned GPRInd = isFastCall ? 1 : 0; for (unsigned i = 0; i != NumOps; ++i) { SDOperand Arg = Op.getOperand(5+2*i); @@ -1404,12 +1397,10 @@ default: assert(0 Unknown value type!); case MVT::i8: case MVT::i16: -case MVT::i32: { - unsigned MaxNumIntRegs = (isFastCall ? 2 : FASTCC_NUM_INT_ARGS_INREGS); - if (NumIntRegs MaxNumIntRegs) { +case MVT::i32: + if (NumIntRegs 2) { ++NumIntRegs; break; - } } // Fall through case MVT::f32: NumBytes += 4; @@ -1423,7 +1414,6 @@ case MVT::v2i64: case MVT::v4f32: case MVT::v2f64: - assert(!isFastCall Unknown value type!); if (NumXMMRegs 4) NumXMMRegs++; else { @@ -1455,16 +1445,14 @@ default: assert(0 Unexpected ValueType for argument!); case MVT::i8: case MVT::i16: -case MVT::i32: { - unsigned MaxNumIntRegs = (isFastCall ? 2 : FASTCC_NUM_INT_ARGS_INREGS); - if (NumIntRegs MaxNumIntRegs) { - unsigned RegToUse = - GPRArgRegs[Arg.getValueType()-MVT::i8][GPRInd][NumIntRegs]; - RegsToPass.push_back(std::make_pair(RegToUse, Arg)); - ++NumIntRegs; -
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.327 - 1.328 X86ISelLowering.h updated: 1.85 - 1.86 --- Log message: simplify result value lowering by splitting the selection of *where* to return registers out from the logic of *how* to return them. This changes X86-64 to mark EAX live out when returning a 32-bit value, where before it marked RAX liveout. --- Diffs of the changes: (+111 -91) X86ISelLowering.cpp | 190 X86ISelLowering.h | 12 +-- 2 files changed, 111 insertions(+), 91 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.327 llvm/lib/Target/X86/X86ISelLowering.cpp:1.328 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.327 Sun Feb 25 01:18:38 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Sun Feb 25 02:15:11 2007 @@ -3915,96 +3915,116 @@ } } -SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG DAG) { - SDOperand Copy; +/// GetRetValueLocs - If we are returning a set of values with the specified +/// value types, determine the set of registers each one will land in. This +/// sets one element of the ResultRegs array for each element in the VTs array. +static void GetRetValueLocs(const MVT::ValueType *VTs, unsigned NumVTs, +unsigned *ResultRegs, +const X86Subtarget *Subtarget) { + if (NumVTs == 0) return; + + if (NumVTs == 2) { +ResultRegs[0] = VTs[0] == MVT::i64 ? X86::RAX : X86::EAX; +ResultRegs[1] = VTs[1] == MVT::i64 ? X86::RDX : X86::EDX; +return; + } + + // Otherwise, NumVTs is 1. + MVT::ValueType ArgVT = VTs[0]; + + if (MVT::isVector(ArgVT))// Integer or FP vector result - XMM0. +ResultRegs[0] = X86::XMM0; + else if (MVT::isFloatingPoint(ArgVT) Subtarget-is64Bit()) +// FP values in X86-64 go in XMM0. +ResultRegs[0] = X86::XMM0; + else if (MVT::isFloatingPoint(ArgVT)) +// FP values in X86-32 go in ST0. +ResultRegs[0] = X86::ST0; + else { +assert(MVT::isInteger(ArgVT) Unknown return value type!); + +// Integer result - EAX / RAX. +// The C calling convention guarantees the return value has been +// promoted to at least MVT::i32. The X86-64 ABI doesn't require the +// value to be promoted MVT::i64. So we don't have to extend it to +// 64-bit. +ResultRegs[0] = (ArgVT == MVT::i64) ? X86::RAX : X86::EAX; + } +} - switch(Op.getNumOperands()) { -default: - assert(0 Do not know how to return this many arguments!); - abort(); -case 1:// ret void. - return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, Op.getOperand(0), -DAG.getConstant(getBytesToPopOnReturn(), MVT::i16)); -case 3: { - MVT::ValueType ArgVT = Op.getOperand(1).getValueType(); - - if (MVT::isVector(ArgVT) || - (Subtarget-is64Bit() MVT::isFloatingPoint(ArgVT))) { -// Integer or FP vector result - XMM0. -if (DAG.getMachineFunction().liveout_empty()) - DAG.getMachineFunction().addLiveOut(X86::XMM0); -Copy = DAG.getCopyToReg(Op.getOperand(0), X86::XMM0, Op.getOperand(1), -SDOperand()); - } else if (MVT::isInteger(ArgVT)) { -// Integer result - EAX / RAX. -// The C calling convention guarantees the return value has been -// promoted to at least MVT::i32. The X86-64 ABI doesn't require the -// value to be promoted MVT::i64. So we don't have to extend it to -// 64-bit. Return the value in EAX, but mark RAX as liveout. -unsigned Reg = Subtarget-is64Bit() ? X86::RAX : X86::EAX; -if (DAG.getMachineFunction().liveout_empty()) - DAG.getMachineFunction().addLiveOut(Reg); - -Reg = (ArgVT == MVT::i64) ? X86::RAX : X86::EAX; -Copy = DAG.getCopyToReg(Op.getOperand(0), Reg, Op.getOperand(1), -SDOperand()); - } else if (!X86ScalarSSE) { -// FP return with fp-stack value. -if (DAG.getMachineFunction().liveout_empty()) - DAG.getMachineFunction().addLiveOut(X86::ST0); - -SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag); -SDOperand Ops[] = { Op.getOperand(0), Op.getOperand(1) }; -Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops, 2); - } else { -// FP return with ScalarSSE (return on fp-stack). -if (DAG.getMachineFunction().liveout_empty()) - DAG.getMachineFunction().addLiveOut(X86::ST0); - -SDOperand MemLoc; -SDOperand Chain = Op.getOperand(0); -SDOperand Value = Op.getOperand(1); - -if (ISD::isNON_EXTLoad(Value.Val) -(Chain == Value.getValue(1) || Chain == Value.getOperand(0))) { - Chain = Value.getOperand(0); - MemLoc = Value.getOperand(1); -} else { - // Spill the value to memory and reload it into top of
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.329 - 1.330 X86ISelLowering.h updated: 1.86 - 1.87 --- Log message: factor a bunch of code out of LowerallTo into a new LowerCallResult function. This function now uses GetRetValueLocs to determine *where* the result values are located and concerns itself with *how* to pull the values out. --- Diffs of the changes: (+97 -100) X86ISelLowering.cpp | 194 +--- X86ISelLowering.h |3 2 files changed, 97 insertions(+), 100 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.329 llvm/lib/Target/X86/X86ISelLowering.cpp:1.330 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.329 Sun Feb 25 02:29:00 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Sun Feb 25 02:59:22 2007 @@ -446,24 +446,96 @@ // Otherwise, NumVTs is 1. MVT::ValueType ArgVT = VTs[0]; - if (MVT::isVector(ArgVT))// Integer or FP vector result - XMM0. -ResultRegs[0] = X86::XMM0; - else if (MVT::isFloatingPoint(ArgVT) Subtarget-is64Bit()) -// FP values in X86-64 go in XMM0. -ResultRegs[0] = X86::XMM0; - else if (MVT::isFloatingPoint(ArgVT)) -// FP values in X86-32 go in ST0. -ResultRegs[0] = X86::ST0; - else { -assert(MVT::isInteger(ArgVT) Unknown return value type!); + unsigned Reg; + switch (ArgVT) { + case MVT::i8: Reg = X86::AL; break; + case MVT::i16: Reg = X86::AX; break; + case MVT::i32: Reg = X86::EAX; break; + case MVT::i64: Reg = X86::RAX; break; + case MVT::f32: + case MVT::f64: +if (Subtarget-is64Bit()) + Reg = X86::XMM0; // FP values in X86-64 go in XMM0. +else + Reg = X86::ST0; // FP values in X86-32 go in ST0. +break; + default: +assert(MVT::isVector(ArgVT) Unknown return value type!); +Reg = X86::XMM0; // Int/FP vector result - XMM0. +break; + } + ResultRegs[0] = Reg; +} + +/// LowerCallResult - Lower the result values of an ISD::CALL into the +/// appropriate copies out of appropriate physical registers. This assumes that +/// Chain/InFlag are the input chain/flag to use, and that TheCall is the call +/// being lowered. The returns a SDNode with the same number of values as the +/// ISD::CALL. +SDNode *X86TargetLowering:: +LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode *TheCall, +unsigned CallingConv, SelectionDAG DAG) { + SmallVectorSDOperand, 8 ResultVals; + + // We support returning up to two registers. + MVT::ValueType VTs[2]; + unsigned DestRegs[2]; + unsigned NumRegs = TheCall-getNumValues() - 1; + assert(NumRegs = 2 Can only return up to two regs!); + + for (unsigned i = 0; i != NumRegs; ++i) +VTs[i] = TheCall-getValueType(i); + + // Determine which register each value should be copied into. + GetRetValueLocs(VTs, NumRegs, DestRegs, Subtarget, CallingConv); + + // Copy all of the result registers out of their specified physreg. + if (NumRegs != 1 || DestRegs[0] != X86::ST0) { +for (unsigned i = 0; i != NumRegs; ++i) { + Chain = DAG.getCopyFromReg(Chain, DestRegs[i], VTs[i], + InFlag).getValue(1); + InFlag = Chain.getValue(2); + ResultVals.push_back(Chain.getValue(0)); +} + } else { +// Copies from the FP stack are special, as ST0 isn't a valid register +// before the fp stackifier runs. -// Integer result - EAX / RAX. -// The C calling convention guarantees the return value has been -// promoted to at least MVT::i32. The X86-64 ABI doesn't require the -// value to be promoted MVT::i64. So we don't have to extend it to -// 64-bit. -ResultRegs[0] = (ArgVT == MVT::i64) ? X86::RAX : X86::EAX; +// Copy ST0 into an RFP register with FP_GET_RESULT. +SDVTList Tys = DAG.getVTList(MVT::f64, MVT::Other, MVT::Flag); +SDOperand GROps[] = { Chain, InFlag }; +SDOperand RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys, GROps, 2); +Chain = RetVal.getValue(1); +InFlag = RetVal.getValue(2); + +// If we are using ScalarSSE, store ST(0) to the stack and reload it into +// an XMM register. +if (X86ScalarSSE) { + // FIXME: Currently the FST is flagged to the FP_GET_RESULT. This + // shouldn't be necessary except that RFP cannot be live across + // multiple blocks. When stackifier is fixed, they can be uncoupled. + MachineFunction MF = DAG.getMachineFunction(); + int SSFI = MF.getFrameInfo()-CreateStackObject(8, 8); + SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); + SDOperand Ops[] = { +Chain, RetVal, StackSlot, DAG.getValueType(VTs[0]), InFlag + }; + Chain = DAG.getNode(X86ISD::FST, MVT::Other, Ops, 5); + RetVal = DAG.getLoad(VTs[0], Chain, StackSlot, NULL, 0); + Chain = RetVal.getValue(1); +} + +if (VTs[0] == MVT::f32 !X86ScalarSSE) + // FIXME: we would
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.330 - 1.331 X86ISelLowering.h updated: 1.87 - 1.88 --- Log message: pass the calling convention into Lower*CallTo, instead of using ad-hoc flags. --- Diffs of the changes: (+19 -23) X86ISelLowering.cpp | 34 -- X86ISelLowering.h |8 +++- 2 files changed, 19 insertions(+), 23 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.330 llvm/lib/Target/X86/X86ISelLowering.cpp:1.331 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.330 Sun Feb 25 02:59:22 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Sun Feb 25 03:06:15 2007 @@ -763,7 +763,7 @@ } SDOperand X86TargetLowering::LowerallTo(SDOperand Op, SelectionDAG DAG, -bool isStdCall) { +unsigned CC) { SDOperand Chain = Op.getOperand(0); bool isVarArg = castConstantSDNode(Op.getOperand(2))-getValue() != 0; bool isTailCall = castConstantSDNode(Op.getOperand(3))-getValue() != 0; @@ -808,7 +808,7 @@ ArgInRegs[i], NumIntRegs, NumXMMRegs, 3, ObjSize, ObjIntRegs, ObjXMMRegs, - !isStdCall); + CC != CallingConv::X86_StdCall); if (ObjSize 4) ArgIncrement = ObjSize; @@ -842,7 +842,7 @@ ArgInRegs[i], NumIntRegs, NumXMMRegs, 3, ObjSize, ObjIntRegs, ObjXMMRegs, - !isStdCall); + CC != CallingConv::X86_StdCall); if (ObjSize 4) ArgIncrement = ObjSize; @@ -868,7 +868,6 @@ case MVT::v2i64: case MVT::v4f32: case MVT::v2f64: - assert(!isStdCall Unhandled argument type!); RegsToPass.push_back(std::make_pair(XMMArgRegs[NumXMMRegs], Arg)); break; } @@ -956,12 +955,11 @@ // Create the CALLSEQ_END node. unsigned NumBytesForCalleeToPush = 0; - if (isStdCall) { -if (isVarArg) { + if (CC == CallingConv::X86_StdCall) { +if (isVarArg) NumBytesForCalleeToPush = NumSRetBytes; -} else { +else NumBytesForCalleeToPush = NumBytes; -} } else { // If this is is a call to a struct-return function, the callee // pops the hidden struct pointer, so we have to push it back. @@ -980,8 +978,7 @@ // Handle result values, copying them out of physregs into vregs that we // return. - return SDOperand(LowerCallResult(Chain, InFlag, Op.Val, CallingConv::C, DAG), - Op.ResNo); + return SDOperand(LowerCallResult(Chain, InFlag, Op.Val, CC, DAG), Op.ResNo); } @@ -1219,7 +1216,8 @@ } SDOperand -X86TargetLowering::LowerX86_64allTo(SDOperand Op, SelectionDAG DAG) { +X86TargetLowering::LowerX86_64allTo(SDOperand Op, SelectionDAG DAG, +unsigned CallingConv) { SDOperand Chain = Op.getOperand(0); bool isVarArg = castConstantSDNode(Op.getOperand(2))-getValue() != 0; bool isTailCall = castConstantSDNode(Op.getOperand(3))-getValue() != 0; @@ -1652,7 +1650,7 @@ } SDOperand X86TargetLowering::LowerFastCCCallTo(SDOperand Op, SelectionDAG DAG, - bool isFastCall) { + unsigned CC) { SDOperand Chain = Op.getOperand(0); bool isTailCall = castConstantSDNode(Op.getOperand(3))-getValue() != 0; SDOperand Callee= Op.getOperand(4); @@ -1677,7 +1675,8 @@ X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3 }; - unsigned GPRInd = (isFastCall ? 1 : 0); + bool isFastCall = CC == CallingConv::X86_FastCall; + unsigned GPRInd = isFastCall ? 1 : 0; for (unsigned i = 0; i != NumOps; ++i) { SDOperand Arg = Op.getOperand(5+2*i); @@ -3935,21 +3934,20 @@ unsigned CallingConv= castConstantSDNode(Op.getOperand(1))-getValue(); if (Subtarget-is64Bit()) -return LowerX86_64allTo(Op, DAG); +return LowerX86_64allTo(Op, DAG, CallingConv); else switch (CallingConv) { default: assert(0 Unsupported calling convention); case CallingConv::Fast: if (EnableFastCC) -return LowerFastCCCallTo(Op, DAG); +return LowerFastCCCallTo(Op, DAG, CallingConv); // Falls through case CallingConv::C: - return LowerallTo(Op, DAG); case CallingConv::X86_StdCall: - return LowerallTo(Op, DAG, true); + return LowerallTo(Op, DAG, CallingConv); case CallingConv::X86_FastCall: - return LowerFastCCCallTo(Op, DAG, true); + return LowerFastCCCallTo(Op, DAG, CallingConv); } } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.87 llvm/lib/Target/X86/X86ISelLowering.h:1.88
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.312 - 1.313 X86ISelLowering.h updated: 1.82 - 1.83 X86InstrSSE.td updated: 1.175 - 1.176 --- Log message: - FCOPYSIGN custom lowering bug. Clear the sign bit of operand 0 first before or'ing in the sign bit of operand 1. - Tweaking: rather than left shift the sign bit, fp_extend operand 1 first before taking its sign bit if its type is smaller than that of operand 0. --- Diffs of the changes: (+39 -21) X86ISelLowering.cpp | 51 +-- X86ISelLowering.h |6 ++ X86InstrSSE.td |3 --- 3 files changed, 39 insertions(+), 21 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.312 llvm/lib/Target/X86/X86ISelLowering.cpp:1.313 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.312 Fri Jan 5 02:32:24 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Jan 5 15:37:56 2007 @@ -4127,9 +4127,18 @@ } SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG DAG) { + SDOperand Op0 = Op.getOperand(0); + SDOperand Op1 = Op.getOperand(1); MVT::ValueType VT = Op.getValueType(); - MVT::ValueType SrcVT = Op.getOperand(1).getValueType(); + MVT::ValueType SrcVT = Op1.getValueType(); const Type *SrcTy = MVT::getTypeForValueType(SrcVT); + + // If second operand is smaller, extend it first. + if (MVT::getSizeInBits(SrcVT) MVT::getSizeInBits(VT)) { +Op1 = DAG.getNode(ISD::FP_EXTEND, VT, Op1); +SrcVT = VT; + } + // First get the sign bit of second operand. std::vectorConstant* CV; if (SrcVT == MVT::f64) { @@ -4150,8 +4159,8 @@ Ops.push_back(DAG.getEntryNode()); Ops.push_back(CPIdx); Ops.push_back(DAG.getSrcValue(NULL)); - SDOperand Mask = DAG.getNode(X86ISD::LOAD_PACK, Tys, Ops[0], Ops.size()); - SDOperand SignBit = DAG.getNode(X86ISD::FAND, SrcVT, Op.getOperand(1), Mask); + SDOperand Mask1 = DAG.getNode(X86ISD::LOAD_PACK, Tys, Ops[0], Ops.size()); + SDOperand SignBit = DAG.getNode(X86ISD::FAND, SrcVT, Op1, Mask1); // Shift sign bit right or left if the two operands have different types. if (MVT::getSizeInBits(SrcVT) MVT::getSizeInBits(VT)) { @@ -4162,18 +4171,33 @@ SignBit = DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32, SignBit); SignBit = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::f32, SignBit, DAG.getConstant(0, getPointerTy())); - } else if (MVT::getSizeInBits(SrcVT) MVT::getSizeInBits(VT)) { -// Op0 is MVT::f64, Op1 is MVT::f32. -SignBit = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v4f32, SignBit); -SignBit = DAG.getNode(X86ISD::FSHL, MVT::v4f32, SignBit, - DAG.getConstant(32, MVT::i32)); -SignBit = DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64, SignBit); -SignBit = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::f64, SignBit, - DAG.getConstant(0, getPointerTy())); } - // Or the first operand with the sign bit. - return DAG.getNode(X86ISD::FOR, VT, Op.getOperand(0), SignBit); + // Clear first operand sign bit. + CV.clear(); + if (VT == MVT::f64) { +CV.push_back(ConstantFP::get(SrcTy, BitsToDouble(~(1ULL 63; +CV.push_back(ConstantFP::get(SrcTy, 0.0)); + } else { +CV.push_back(ConstantFP::get(SrcTy, BitsToFloat(~(1U 31; +CV.push_back(ConstantFP::get(SrcTy, 0.0)); +CV.push_back(ConstantFP::get(SrcTy, 0.0)); +CV.push_back(ConstantFP::get(SrcTy, 0.0)); + } + CS = ConstantStruct::get(CV); + CPIdx = DAG.getConstantPool(CS, getPointerTy(), 4); + Tys.clear(); + Tys.push_back(VT); + Tys.push_back(MVT::Other); + Ops.clear(); + Ops.push_back(DAG.getEntryNode()); + Ops.push_back(CPIdx); + Ops.push_back(DAG.getSrcValue(NULL)); + SDOperand Mask2 = DAG.getNode(X86ISD::LOAD_PACK, Tys, Ops[0], Ops.size()); + SDOperand Val = DAG.getNode(X86ISD::FAND, VT, Op0, Mask2); + + // Or the value with the sign bit. + return DAG.getNode(X86ISD::FOR, VT, Val, SignBit); } SDOperand X86TargetLowering::LowerSETCC(SDOperand Op, SelectionDAG DAG, @@ -5032,7 +5056,6 @@ case X86ISD::FAND: return X86ISD::FAND; case X86ISD::FOR:return X86ISD::FOR; case X86ISD::FXOR: return X86ISD::FXOR; - case X86ISD::FSHL: return X86ISD::FSHL; case X86ISD::FSRL: return X86ISD::FSRL; case X86ISD::FILD: return X86ISD::FILD; case X86ISD::FILD_FLAG: return X86ISD::FILD_FLAG; Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.82 llvm/lib/Target/X86/X86ISelLowering.h:1.83 --- llvm/lib/Target/X86/X86ISelLowering.h:1.82 Fri Jan 5 01:55:56 2007 +++ llvm/lib/Target/X86/X86ISelLowering.h Fri Jan 5 15:37:56 2007 @@ -43,10 +43,8 @@ /// to X86::XORPS or X86::XORPD. FXOR, - /// FSHL, FSRL - Shift a floating point value (in SSE register) by n bits - /// while shifting
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.310 - 1.311 X86ISelLowering.h updated: 1.81 - 1.82 X86InstrSSE.td updated: 1.174 - 1.175 --- Log message: With SSE2, expand FCOPYSIGN to a series of SSE bitwise operations. --- Diffs of the changes: (+93 -8) X86ISelLowering.cpp | 65 X86ISelLowering.h | 11 X86InstrSSE.td | 25 3 files changed, 93 insertions(+), 8 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.310 llvm/lib/Target/X86/X86ISelLowering.cpp:1.311 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.310 Wed Jan 3 11:24:59 2007 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Jan 5 01:55:56 2007 @@ -250,9 +250,6 @@ setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand); - setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand); - setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand); - if (X86ScalarSSE) { // Set up the FP register classes. addRegisterClass(MVT::f32, X86::FR32RegisterClass); @@ -266,6 +263,10 @@ setOperationAction(ISD::FNEG , MVT::f64, Custom); setOperationAction(ISD::FNEG , MVT::f32, Custom); +// Use ANDPD and ORPD to simulate FCOPYSIGN. +setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom); +setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom); + // We don't support sin/cos/fmod setOperationAction(ISD::FSIN , MVT::f64, Expand); setOperationAction(ISD::FCOS , MVT::f64, Expand); @@ -283,7 +284,9 @@ // Set up the FP register classes. addRegisterClass(MVT::f64, X86::RFPRegisterClass); -setOperationAction(ISD::UNDEF, MVT::f64, Expand); +setOperationAction(ISD::UNDEF, MVT::f64, Expand); +setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand); +setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand); if (!UnsafeFPMath) { setOperationAction(ISD::FSIN , MVT::f64 , Expand); @@ -4123,6 +4126,56 @@ return DAG.getNode(X86ISD::FXOR, VT, Op.getOperand(0), Mask); } +SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG DAG) { + MVT::ValueType VT = Op.getValueType(); + MVT::ValueType SrcVT = Op.getOperand(1).getValueType(); + const Type *SrcTy = MVT::getTypeForValueType(SrcVT); + // First get the sign bit of second operand. + std::vectorConstant* CV; + if (SrcVT == MVT::f64) { +CV.push_back(ConstantFP::get(SrcTy, BitsToDouble(1ULL 63))); +CV.push_back(ConstantFP::get(SrcTy, 0.0)); + } else { +CV.push_back(ConstantFP::get(SrcTy, BitsToFloat(1U 31))); +CV.push_back(ConstantFP::get(SrcTy, 0.0)); +CV.push_back(ConstantFP::get(SrcTy, 0.0)); +CV.push_back(ConstantFP::get(SrcTy, 0.0)); + } + Constant *CS = ConstantStruct::get(CV); + SDOperand CPIdx = DAG.getConstantPool(CS, getPointerTy(), 4); + std::vectorMVT::ValueType Tys; + Tys.push_back(VT); + Tys.push_back(MVT::Other); + SmallVectorSDOperand, 3 Ops; + Ops.push_back(DAG.getEntryNode()); + Ops.push_back(CPIdx); + Ops.push_back(DAG.getSrcValue(NULL)); + SDOperand Mask = DAG.getNode(X86ISD::LOAD_PACK, Tys, Ops[0], Ops.size()); + SDOperand SignBit = DAG.getNode(X86ISD::FAND, SrcVT, Op.getOperand(1), Mask); + + // Shift sign bit right or left if the two operands have different types. + if (MVT::getSizeInBits(SrcVT) MVT::getSizeInBits(VT)) { +// Op0 is MVT::f32, Op1 is MVT::f64. +SignBit = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v2f64, SignBit); +SignBit = DAG.getNode(X86ISD::FSRL, MVT::v2f64, SignBit, + DAG.getConstant(32, MVT::i32)); +SignBit = DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32, SignBit); +SignBit = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::f32, SignBit, + DAG.getConstant(0, getPointerTy())); + } else if (MVT::getSizeInBits(SrcVT) MVT::getSizeInBits(VT)) { +// Op0 is MVT::f64, Op1 is MVT::f32. +SignBit = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v4f32, SignBit); +SignBit = DAG.getNode(X86ISD::FSHL, MVT::v4f32, SignBit, + DAG.getConstant(32, MVT::i32)); +SignBit = DAG.getNode(ISD::BIT_CONVERT, MVT::v2f64, SignBit); +SignBit = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::f64, SignBit, + DAG.getConstant(0, getPointerTy())); + } + + // Or the first operand with the sign bit. + return DAG.getNode(X86ISD::FOR, VT, Op.getOperand(0), SignBit); +} + SDOperand X86TargetLowering::LowerSETCC(SDOperand Op, SelectionDAG DAG, SDOperand Chain) { assert(Op.getValueType() == MVT::i8 SetCC type must be 8-bit integer); @@ -4955,6 +5008,7 @@ case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG); case ISD::FABS: return LowerFABS(Op, DAG); case ISD::FNEG: return LowerFNEG(Op, DAG); + case
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.289 - 1.290 X86ISelLowering.h updated: 1.79 - 1.80 X86InstrSSE.td updated: 1.170 - 1.171 --- Log message: Don't dag combine floating point select to max and min intrinsics. Those take v4f32 / v2f64 operands and may end up causing larger spills / restores. Added X86 specific nodes X86ISD::FMAX, X86ISD::FMIN instead. This fixes PR996: http://llvm.org/PR996 . --- Diffs of the changes: (+21 -59) X86ISelLowering.cpp | 36 +--- X86ISelLowering.h |6 +- X86InstrSSE.td | 38 +++--- 3 files changed, 21 insertions(+), 59 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.289 llvm/lib/Target/X86/X86ISelLowering.cpp:1.290 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.289 Thu Nov 9 18:48:12 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Nov 10 15:43:37 2006 @@ -4983,6 +4983,8 @@ case X86ISD::S2VEC: return X86ISD::S2VEC; case X86ISD::PEXTRW: return X86ISD::PEXTRW; case X86ISD::PINSRW: return X86ISD::PINSRW; + case X86ISD::FMAX: return X86ISD::FMAX; + case X86ISD::FMIN: return X86ISD::FMIN; } } @@ -5363,7 +5365,7 @@ SDOperand RHS = N-getOperand(2); ISD::CondCode CC = castCondCodeSDNode(Cond.getOperand(2))-get(); - unsigned IntNo = 0; + unsigned Opcode = 0; if (LHS == Cond.getOperand(0) RHS == Cond.getOperand(1)) { switch (CC) { default: break; @@ -5374,8 +5376,7 @@ // FALL THROUGH. case ISD::SETOLT: // (X olt/lt Y) ? X : Y - min case ISD::SETLT: - IntNo = LHS.getValueType() == MVT::f32 ? Intrinsic::x86_sse_min_ss : - Intrinsic::x86_sse2_min_sd; + Opcode = X86ISD::FMIN; break; case ISD::SETOGT: // (X Y) ? X : Y - max @@ -5385,8 +5386,7 @@ // FALL THROUGH. case ISD::SETUGE: // (X uge/ge Y) ? X : Y - max case ISD::SETGE: - IntNo = LHS.getValueType() == MVT::f32 ? Intrinsic::x86_sse_max_ss : - Intrinsic::x86_sse2_max_sd; + Opcode = X86ISD::FMAX; break; } } else if (LHS == Cond.getOperand(1) RHS == Cond.getOperand(0)) { @@ -5399,8 +5399,7 @@ // FALL THROUGH. case ISD::SETUGE: // (X uge/ge Y) ? Y : X - min case ISD::SETGE: - IntNo = LHS.getValueType() == MVT::f32 ? Intrinsic::x86_sse_min_ss : - Intrinsic::x86_sse2_min_sd; + Opcode = X86ISD::FMIN; break; case ISD::SETOLE: // (X = Y) ? Y : X - max @@ -5410,30 +5409,13 @@ // FALL THROUGH. case ISD::SETOLT: // (X olt/lt Y) ? Y : X - max case ISD::SETLT: - IntNo = LHS.getValueType() == MVT::f32 ? Intrinsic::x86_sse_max_ss : - Intrinsic::x86_sse2_max_sd; + Opcode = X86ISD::FMAX; break; } } - // minss/maxss take a v4f32 operand. - if (IntNo) { -if (LHS.getValueType() == MVT::f32) { - LHS = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v4f32, LHS); - RHS = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v4f32, RHS); -} else { - LHS = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v2f64, LHS); - RHS = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v2f64, RHS); -} - -MVT::ValueType PtrTy = Subtarget-is64Bit() ? MVT::i64 : MVT::i32; -SDOperand IntNoN = DAG.getConstant(IntNo, PtrTy); - -SDOperand Val = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, LHS.getValueType(), -IntNoN, LHS, RHS); -return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, N-getValueType(0), Val, - DAG.getConstant(0, PtrTy)); - } + if (Opcode) +return DAG.getNode(Opcode, N-getValueType(0), LHS, RHS); } } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.79 llvm/lib/Target/X86/X86ISelLowering.h:1.80 --- llvm/lib/Target/X86/X86ISelLowering.h:1.79 Tue Nov 7 16:14:24 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Fri Nov 10 15:43:37 2006 @@ -160,7 +160,11 @@ /// PINSRW - Insert the lower 16-bits of a 32-bit value to a vector, /// corresponds to X86::PINSRW. - PINSRW + PINSRW, + + /// FMAX, FMIN - Floating point max and min. + /// + FMAX, FMIN }; } Index: llvm/lib/Target/X86/X86InstrSSE.td diff -u llvm/lib/Target/X86/X86InstrSSE.td:1.170 llvm/lib/Target/X86/X86InstrSSE.td:1.171 --- llvm/lib/Target/X86/X86InstrSSE.td:1.170Tue Nov 7 16:14:24 2006 +++
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.287 - 1.288 X86ISelLowering.h updated: 1.78 - 1.79 X86InstrSSE.td updated: 1.169 - 1.170 --- Log message: Fixed a bug which causes x86 be to incorrectly match shuffle v, undef, 2, ?, 3, ? to movhlps It should match to unpckhps instead. Added proper matching code for shuffle v, undef, 2, 3, 2, 3 --- Diffs of the changes: (+30 -5) X86ISelLowering.cpp | 18 +- X86ISelLowering.h |5 + X86InstrSSE.td | 12 3 files changed, 30 insertions(+), 5 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.287 llvm/lib/Target/X86/X86ISelLowering.cpp:1.288 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.287 Thu Nov 2 14:25:49 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Nov 7 16:14:24 2006 @@ -2582,6 +2582,22 @@ isUndefOrEqual(N-getOperand(3), 3); } +/// isMOVHLPS_v_undef_Mask - Special case of isMOVHLPSMask for canonical form +/// of vector_shuffle v, v, 2, 3, 2, 3, i.e. vector_shuffle v, undef, +/// 2, 3, 2, 3 +bool X86::isMOVHLPS_v_undef_Mask(SDNode *N) { + assert(N-getOpcode() == ISD::BUILD_VECTOR); + + if (N-getNumOperands() != 4) +return false; + + // Expect bit0 == 2, bit1 == 3, bit2 == 2, bit3 == 3 + return isUndefOrEqual(N-getOperand(0), 2) + isUndefOrEqual(N-getOperand(1), 3) + isUndefOrEqual(N-getOperand(2), 2) + isUndefOrEqual(N-getOperand(3), 3); +} + /// isMOVLPMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a shuffle of elements that is suitable for input to MOVLP{S|D}. bool X86::isMOVLPMask(SDNode *N) { @@ -3724,7 +3740,7 @@ SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, IdxVec[0], IdxVec.size()); Vec = DAG.getNode(ISD::VECTOR_SHUFFLE, Vec.getValueType(), - Vec, Vec, Mask); + Vec, DAG.getNode(ISD::UNDEF, Vec.getValueType()), Mask); return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, VT, Vec, DAG.getConstant(0, getPointerTy())); } else if (MVT::getSizeInBits(VT) == 64) { Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.78 llvm/lib/Target/X86/X86ISelLowering.h:1.79 --- llvm/lib/Target/X86/X86ISelLowering.h:1.78 Tue Oct 31 14:13:11 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Tue Nov 7 16:14:24 2006 @@ -186,6 +186,11 @@ /// specifies a shuffle of elements that is suitable for input to MOVHLPS. bool isMOVHLPSMask(SDNode *N); + /// isMOVHLPS_v_undef_Mask - Special case of isMOVHLPSMask for canonical form + /// of vector_shuffle v, v, 2, 3, 2, 3, i.e. vector_shuffle v, undef, + /// 2, 3, 2, 3 + bool isMOVHLPS_v_undef_Mask(SDNode *N); + /// isMOVLPMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a shuffle of elements that is suitable for input to MOVLP{S|D}. bool isMOVLPMask(SDNode *N); Index: llvm/lib/Target/X86/X86InstrSSE.td diff -u llvm/lib/Target/X86/X86InstrSSE.td:1.169 llvm/lib/Target/X86/X86InstrSSE.td:1.170 --- llvm/lib/Target/X86/X86InstrSSE.td:1.169Fri Nov 3 17:48:56 2006 +++ llvm/lib/Target/X86/X86InstrSSE.td Tue Nov 7 16:14:24 2006 @@ -110,6 +110,10 @@ return X86::isMOVHLPSMask(N); }]; +def MOVHLPS_v_undef_shuffle_mask : PatLeaf(build_vector), [{ + return X86::isMOVHLPS_v_undef_Mask(N); +}]; + def MOVHP_shuffle_mask : PatLeaf(build_vector), [{ return X86::isMOVHPMask(N); }]; @@ -1987,16 +1991,16 @@ MOVHLPS_shuffle_mask)), (MOVHLPSrr VR128:$src1, VR128:$src2); -// vector_shuffle v1, undef 2, 3, ?, ? using MOVHLPS +// vector_shuffle v1, undef 2, ?, ?, ? using MOVHLPS def : Pat(v4f32 (vector_shuffle VR128:$src1, (undef), - UNPCKH_shuffle_mask)), + MOVHLPS_v_undef_shuffle_mask)), (MOVHLPSrr VR128:$src1, VR128:$src1); def : Pat(v4i32 (vector_shuffle VR128:$src1, (undef), - UNPCKH_shuffle_mask)), + MOVHLPS_v_undef_shuffle_mask)), (MOVHLPSrr VR128:$src1, VR128:$src1); } - let AddedComplexity = 20 in { +let AddedComplexity = 20 in { // vector_shuffle v1, (load v2) 4, 5, 2, 3 using MOVLPS // vector_shuffle v1, (load v2) 0, 1, 4, 5 using MOVHPS def : Pat(v4f32 (vector_shuffle VR128:$src1, (loadv4f32 addr:$src2), ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.285 - 1.286 X86ISelLowering.h updated: 1.77 - 1.78 --- Log message: allow the address of a global to be used with the i constraint when in -static mode. This implements PR882: http://llvm.org/PR882 . --- Diffs of the changes: (+36 -1) X86ISelLowering.cpp | 30 ++ X86ISelLowering.h |7 ++- 2 files changed, 36 insertions(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.285 llvm/lib/Target/X86/X86ISelLowering.cpp:1.286 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.285 Tue Oct 31 13:42:44 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Oct 31 14:13:11 2006 @@ -5466,6 +5466,36 @@ } } +/// isOperandValidForConstraint - Return the specified operand (possibly +/// modified) if the specified SDOperand is valid for the specified target +/// constraint letter, otherwise return null. +SDOperand X86TargetLowering:: +isOperandValidForConstraint(SDOperand Op, char Constraint, SelectionDAG DAG) { + switch (Constraint) { + default: break; + case 'i': +// Literal immediates are always ok. +if (isaConstantSDNode(Op)) return Op; + +// If we are in non-pic codegen mode, we allow the address of a global to +// be used with 'i'. +if (GlobalAddressSDNode *GA = dyn_castGlobalAddressSDNode(Op)) { + if (getTargetMachine().getRelocationModel() == Reloc::PIC_) +return SDOperand(0, 0); + + if (GA-getOpcode() != ISD::TargetGlobalAddress) +Op = DAG.getTargetGlobalAddress(GA-getGlobal(), GA-getValueType(0), +GA-getOffset()); + return Op; +} + +// Otherwise, not valid for this mode. +return SDOperand(0, 0); + } + return TargetLowering::isOperandValidForConstraint(Op, Constraint, DAG); +} + + std::vectorunsigned X86TargetLowering:: getRegClassForInlineAsmConstraint(const std::string Constraint, MVT::ValueType VT) const { Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.77 llvm/lib/Target/X86/X86ISelLowering.h:1.78 --- llvm/lib/Target/X86/X86ISelLowering.h:1.77 Fri Oct 27 16:08:32 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Tue Oct 31 14:13:11 2006 @@ -300,7 +300,12 @@ std::vectorunsigned getRegClassForInlineAsmConstraint(const std::string Constraint, MVT::ValueType VT) const; - +/// isOperandValidForConstraint - Return the specified operand (possibly +/// modified) if the specified SDOperand is valid for the specified target +/// constraint letter, otherwise return null. +SDOperand isOperandValidForConstraint(SDOperand Op, char ConstraintLetter, + SelectionDAG DAG); + /// getRegForInlineAsmConstraint - Given a physical register constraint /// (e.g. {edx}), return the register number and the register class for the /// register. This should only be used for C_Register constraints. On ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.280 - 1.281 X86ISelLowering.h updated: 1.76 - 1.77 X86InstrSSE.td updated: 1.166 - 1.167 --- Log message: Fixed a significant bug where unpcklpd is incorrectly used to extract element 1 from a v2f64 value. --- Diffs of the changes: (+25 -6) X86ISelLowering.cpp | 11 +++ X86ISelLowering.h |4 X86InstrSSE.td | 16 ++-- 3 files changed, 25 insertions(+), 6 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.280 llvm/lib/Target/X86/X86ISelLowering.cpp:1.281 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.280 Fri Oct 27 13:49:08 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Oct 27 16:08:32 2006 @@ -2868,6 +2868,17 @@ return ::isSplatMask(N); } +/// isSplatLoMask - Return true if the specified VECTOR_SHUFFLE operand +/// specifies a splat of zero element. +bool X86::isSplatLoMask(SDNode *N) { + assert(N-getOpcode() == ISD::BUILD_VECTOR); + + for (unsigned i = 0, e = N-getNumOperands(); i e; ++i) +if (!isUndefOrEqual(N-getOperand(i), 0)) + return false; + return true; +} + /// getShuffleSHUFImmediate - Return the appropriate immediate to shuffle /// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUF* and SHUFP* /// instructions. Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.76 llvm/lib/Target/X86/X86ISelLowering.h:1.77 --- llvm/lib/Target/X86/X86ISelLowering.h:1.76 Fri Oct 20 12:42:20 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Fri Oct 27 16:08:32 2006 @@ -225,6 +225,10 @@ /// specifies a splat of a single element. bool isSplatMask(SDNode *N); + /// isSplatLoMask - Return true if the specified VECTOR_SHUFFLE operand + /// specifies a splat of zero element. + bool isSplatLoMask(SDNode *N); + /// getShuffleSHUFImmediate - Return the appropriate immediate to shuffle /// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUF* and SHUFP* /// instructions. Index: llvm/lib/Target/X86/X86InstrSSE.td diff -u llvm/lib/Target/X86/X86InstrSSE.td:1.166 llvm/lib/Target/X86/X86InstrSSE.td:1.167 --- llvm/lib/Target/X86/X86InstrSSE.td:1.166Wed Oct 25 16:35:05 2006 +++ llvm/lib/Target/X86/X86InstrSSE.td Fri Oct 27 16:08:32 2006 @@ -104,8 +104,8 @@ return X86::isSplatMask(N); }], SHUFFLE_get_shuf_imm; -def SSE_splat_v2_mask : PatLeaf(build_vector), [{ - return X86::isSplatMask(N); +def SSE_splat_lo_mask : PatLeaf(build_vector), [{ + return X86::isSplatLoMask(N); }]; def MOVHLPS_shuffle_mask : PatLeaf(build_vector), [{ @@ -812,13 +812,13 @@ movddup {$src, $dst|$dst, $src}, [(set VR128:$dst, (v2f64 (vector_shuffle VR128:$src, (undef), -SSE_splat_v2_mask)))]; +SSE_splat_lo_mask)))]; def MOVDDUPrm : S3DI0x12, MRMSrcMem, (ops VR128:$dst, f64mem:$src), movddup {$src, $dst|$dst, $src}, [(set VR128:$dst, (v2f64 (vector_shuffle (scalar_to_vector (loadf64 addr:$src)), (undef), -SSE_splat_v2_mask)))]; +SSE_splat_lo_mask)))]; // SSE2 instructions without OpSize prefix def Int_CVTDQ2PSrr : I0x5B, MRMSrcReg, (ops VR128:$dst, VR128:$src), @@ -1908,10 +1908,14 @@ // Splat v2f64 / v2i64 let AddedComplexity = 10 in { -def : Pat(vector_shuffle (v2f64 VR128:$src), (undef), SSE_splat_v2_mask:$sm), +def : Pat(vector_shuffle (v2f64 VR128:$src), (undef), SSE_splat_lo_mask:$sm), (UNPCKLPDrr VR128:$src, VR128:$src), Requires[HasSSE2]; -def : Pat(vector_shuffle (v2i64 VR128:$src), (undef), SSE_splat_v2_mask:$sm), +def : Pat(vector_shuffle (v2f64 VR128:$src), (undef), UNPCKH_shuffle_mask:$sm), + (UNPCKHPDrr VR128:$src, VR128:$src), Requires[HasSSE2]; +def : Pat(vector_shuffle (v2i64 VR128:$src), (undef), SSE_splat_lo_mask:$sm), (PUNPCKLQDQrr VR128:$src, VR128:$src), Requires[HasSSE2]; +def : Pat(vector_shuffle (v2i64 VR128:$src), (undef), UNPCKH_shuffle_mask:$sm), + (PUNPCKHQDQrr VR128:$src, VR128:$src), Requires[HasSSE2]; } // Splat v4f32 ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.cpp X86InstrInfo.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.276 - 1.277 X86ISelLowering.h updated: 1.75 - 1.76 X86InstrInfo.cpp updated: 1.63 - 1.64 X86InstrInfo.h updated: 1.56 - 1.57 --- Log message: Implement branch analysis/xform hooks required by the branch folding pass. --- Diffs of the changes: (+229 -87) X86ISelLowering.cpp | 107 ++-- X86ISelLowering.h | 22 --- X86InstrInfo.cpp| 151 X86InstrInfo.h | 36 4 files changed, 229 insertions(+), 87 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.276 llvm/lib/Target/X86/X86ISelLowering.cpp:1.277 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.276 Mon Oct 16 01:36:00 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Oct 20 12:42:20 2006 @@ -2317,30 +2317,6 @@ return std::make_pair(Result, Chain); } -/// getCondBrOpcodeForX86CC - Returns the X86 conditional branch opcode -/// which corresponds to the condition code. -static unsigned getCondBrOpcodeForX86CC(unsigned X86CC) { - switch (X86CC) { - default: assert(0 Unknown X86 conditional code!); - case X86ISD::COND_A: return X86::JA; - case X86ISD::COND_AE: return X86::JAE; - case X86ISD::COND_B: return X86::JB; - case X86ISD::COND_BE: return X86::JBE; - case X86ISD::COND_E: return X86::JE; - case X86ISD::COND_G: return X86::JG; - case X86ISD::COND_GE: return X86::JGE; - case X86ISD::COND_L: return X86::JL; - case X86ISD::COND_LE: return X86::JLE; - case X86ISD::COND_NE: return X86::JNE; - case X86ISD::COND_NO: return X86::JNO; - case X86ISD::COND_NP: return X86::JNP; - case X86ISD::COND_NS: return X86::JNS; - case X86ISD::COND_O: return X86::JO; - case X86ISD::COND_P: return X86::JP; - case X86ISD::COND_S: return X86::JS; - } -} - /// translateX86CC - do a one to one translation of a ISD::CondCode to the X86 /// specific condition code. It returns a false if it cannot do a direct /// translation. X86CC is the translated CondCode. LHS/RHS are modified as @@ -2348,33 +2324,33 @@ static bool translateX86CC(ISD::CondCode SetCCOpcode, bool isFP, unsigned X86CC, SDOperand LHS, SDOperand RHS, SelectionDAG DAG) { - X86CC = X86ISD::COND_INVALID; + X86CC = X86::COND_INVALID; if (!isFP) { if (ConstantSDNode *RHSC = dyn_castConstantSDNode(RHS)) { if (SetCCOpcode == ISD::SETGT RHSC-isAllOnesValue()) { // X -1 - X == 0, jump !sign. RHS = DAG.getConstant(0, RHS.getValueType()); -X86CC = X86ISD::COND_NS; +X86CC = X86::COND_NS; return true; } else if (SetCCOpcode == ISD::SETLT RHSC-isNullValue()) { // X 0 - X == 0, jump on sign. -X86CC = X86ISD::COND_S; +X86CC = X86::COND_S; return true; } } switch (SetCCOpcode) { default: break; -case ISD::SETEQ: X86CC = X86ISD::COND_E; break; -case ISD::SETGT: X86CC = X86ISD::COND_G; break; -case ISD::SETGE: X86CC = X86ISD::COND_GE; break; -case ISD::SETLT: X86CC = X86ISD::COND_L; break; -case ISD::SETLE: X86CC = X86ISD::COND_LE; break; -case ISD::SETNE: X86CC = X86ISD::COND_NE; break; -case ISD::SETULT: X86CC = X86ISD::COND_B; break; -case ISD::SETUGT: X86CC = X86ISD::COND_A; break; -case ISD::SETULE: X86CC = X86ISD::COND_BE; break; -case ISD::SETUGE: X86CC = X86ISD::COND_AE; break; +case ISD::SETEQ: X86CC = X86::COND_E; break; +case ISD::SETGT: X86CC = X86::COND_G; break; +case ISD::SETGE: X86CC = X86::COND_GE; break; +case ISD::SETLT: X86CC = X86::COND_L; break; +case ISD::SETLE: X86CC = X86::COND_LE; break; +case ISD::SETNE: X86CC = X86::COND_NE; break; +case ISD::SETULT: X86CC = X86::COND_B; break; +case ISD::SETUGT: X86CC = X86::COND_A; break; +case ISD::SETULE: X86CC = X86::COND_BE; break; +case ISD::SETUGE: X86CC = X86::COND_AE; break; } } else { // On a floating point condition, the flags are set as follows: @@ -2387,29 +2363,29 @@ switch (SetCCOpcode) { default: break; case ISD::SETUEQ: -case ISD::SETEQ: X86CC = X86ISD::COND_E; break; +case ISD::SETEQ: X86CC = X86::COND_E; break; case ISD::SETOLT: Flip = true; // Fallthrough case ISD::SETOGT: -case ISD::SETGT: X86CC = X86ISD::COND_A; break; +case ISD::SETGT: X86CC = X86::COND_A; break; case ISD::SETOLE: Flip = true; // Fallthrough case ISD::SETOGE: -case ISD::SETGE: X86CC = X86ISD::COND_AE; break; +case ISD::SETGE: X86CC = X86::COND_AE; break; case ISD::SETUGT: Flip = true; // Fallthrough case ISD::SETULT: -case ISD::SETLT: X86CC = X86ISD::COND_B; break; +case ISD::SETLT: X86CC = X86::COND_B; break; case ISD::SETUGE: Flip = true; // Fallthrough case ISD::SETULE: -case
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.240 - 1.241 X86ISelLowering.h updated: 1.69 - 1.70 --- Log message: Fix PR850: http://llvm.org/PR850 and CodeGen/X86/2006-07-31-SingleRegClass.ll. The CFE refers to all single-register constraints (like A) by their 16-bit name, even though the 8 or 32-bit version of the register may be needed. The X86 backend should realize what is going on and redecode the name back to its proper form. --- Diffs of the changes: (+68 -0) X86ISelLowering.cpp | 60 X86ISelLowering.h |8 ++ 2 files changed, 68 insertions(+) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.240 llvm/lib/Target/X86/X86ISelLowering.cpp:1.241 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.240 Wed Jul 26 16:12:04 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Mon Jul 31 18:26:50 2006 @@ -4212,3 +4212,63 @@ return std::vectorunsigned(); } + +std::pairunsigned, const TargetRegisterClass* +X86TargetLowering::getRegForInlineAsmConstraint(const std::string Constraint, +MVT::ValueType VT) const { + // Use the default implementation in TargetLowering to convert the register + // constraint into a member of a register class. + std::pairunsigned, const TargetRegisterClass* Res; + Res = TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); + + // Not found? Bail out. + if (Res.second == 0) return Res; + + // Otherwise, check to see if this is a register class of the wrong value + // type. For example, we want to map {ax},i32 - {eax}, we don't want it to + // turn into {ax},{dx}. + if (Res.second-hasType(VT)) +return Res; // Correct type already, nothing to do. + + // All of the single-register GCC register classes map their values onto + // 16-bit register pieces ax,dx,cx,bx,si,di,bp,sp. If we + // really want an 8-bit or 32-bit register, map to the appropriate register + // class and return the appropriate register. + if (Res.second != X86::GR16RegisterClass) +return Res; + + if (VT == MVT::i8) { +unsigned DestReg = 0; +switch (Res.first) { +default: break; +case X86::AX: DestReg = X86::AL; break; +case X86::DX: DestReg = X86::DL; break; +case X86::CX: DestReg = X86::CL; break; +case X86::BX: DestReg = X86::BL; break; +} +if (DestReg) { + Res.first = DestReg; + Res.second = Res.second = X86::GR8RegisterClass; +} + } else if (VT == MVT::i32) { +unsigned DestReg = 0; +switch (Res.first) { +default: break; +case X86::AX: DestReg = X86::EAX; break; +case X86::DX: DestReg = X86::EDX; break; +case X86::CX: DestReg = X86::ECX; break; +case X86::BX: DestReg = X86::EBX; break; +case X86::SI: DestReg = X86::ESI; break; +case X86::DI: DestReg = X86::EDI; break; +case X86::BP: DestReg = X86::EBP; break; +case X86::SP: DestReg = X86::ESP; break; +} +if (DestReg) { + Res.first = DestReg; + Res.second = Res.second = X86::GR32RegisterClass; +} + } + + return Res; +} + Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.69 llvm/lib/Target/X86/X86ISelLowering.h:1.70 --- llvm/lib/Target/X86/X86ISelLowering.h:1.69 Mon Jul 10 21:54:03 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Mon Jul 31 18:26:50 2006 @@ -316,6 +316,14 @@ getRegClassForInlineAsmConstraint(const std::string Constraint, MVT::ValueType VT) const; +/// getRegForInlineAsmConstraint - Given a physical register constraint (e.g. +/// {edx}), return the register number and the register class for the +/// register. This should only be used for C_Register constraints. On error, +/// this returns a register number of 0. +std::pairunsigned, const TargetRegisterClass* + getRegForInlineAsmConstraint(const std::string Constraint, + MVT::ValueType VT) const; + /// isLegalAddressImmediate - Return true if the integer value or /// GlobalValue can be used as the offset of the target addressing mode. virtual bool isLegalAddressImmediate(int64_t V) const; ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.235 - 1.236 X86ISelLowering.h updated: 1.68 - 1.69 --- Log message: Implement the inline asm 'A' constraint. This implements PR825: http://llvm.org/PR825 and CodeGen/X86/2006-07-10-InlineAsmAConstraint.ll --- Diffs of the changes: (+17 -1) X86ISelLowering.cpp | 16 +++- X86ISelLowering.h |2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.235 llvm/lib/Target/X86/X86ISelLowering.cpp:1.236 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.235 Mon Jul 10 16:37:44 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Mon Jul 10 21:54:03 2006 @@ -4135,6 +4135,16 @@ // X86 Inline Assembly Support //===--===// +/// getConstraintType - Given a constraint letter, return the type of +/// constraint it is for this target. +X86TargetLowering::ConstraintType +X86TargetLowering::getConstraintType(char ConstraintLetter) const { + switch (ConstraintLetter) { + case 'A': return C_RegisterClass; + default: return TargetLowering::getConstraintType(ConstraintLetter); + } +} + std::vectorunsigned X86TargetLowering:: getRegClassForInlineAsmConstraint(const std::string Constraint, MVT::ValueType VT) const { @@ -4142,7 +4152,11 @@ // FIXME: not handling fp-stack yet! // FIXME: not handling MMX registers yet ('y' constraint). switch (Constraint[0]) { // GCC X86 Constraint Letters -default: break; // Unknown constriant letter +default: break; // Unknown constraint letter +case 'A': // EAX/EDX + if (VT == MVT::i32 || VT == MVT::i64) +return make_vectorunsigned(X86::EAX, X86::EDX, 0); + break; case 'r': // GENERAL_REGS case 'R': // LEGACY_REGS if (VT == MVT::i32) Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.68 llvm/lib/Target/X86/X86ISelLowering.h:1.69 --- llvm/lib/Target/X86/X86ISelLowering.h:1.68 Fri Jul 7 03:33:52 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Mon Jul 10 21:54:03 2006 @@ -310,6 +310,8 @@ SDOperand getReturnAddressFrameIndex(SelectionDAG DAG); +ConstraintType getConstraintType(char ConstraintLetter) const; + std::vectorunsigned getRegClassForInlineAsmConstraint(const std::string Constraint, MVT::ValueType VT) const; ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86JITInfo.cpp
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.230 - 1.231 X86ISelLowering.h updated: 1.66 - 1.67 X86JITInfo.cpp updated: 1.20 - 1.21 --- Log message: Simplify X86CompilationCallback: always align to 16-byte boundary; don't save EAX/EDX if unnecessary. --- Diffs of the changes: (+44 -34) X86ISelLowering.cpp | 32 X86ISelLowering.h | 16 X86JITInfo.cpp | 30 -- 3 files changed, 44 insertions(+), 34 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.230 llvm/lib/Target/X86/X86ISelLowering.cpp:1.231 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.230 Thu Jun 15 03:14:54 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Sat Jun 24 03:36:10 2006 @@ -762,26 +762,6 @@ // (when we have a global fp allocator) and do other tricks. // -// FASTCC_NUM_INT_ARGS_INREGS - This is the max number of integer arguments -// to pass in registers. 0 is none, 1 is is use EAX, 2 is use EAX and -// EDX. Anything more is illegal. -// -// FIXME: The linscan register allocator currently has problem with -// coalescing. At the time of this writing, whenever it decides to coalesce -// a physreg with a virtreg, this increases the size of the physreg's live -// range, and the live range cannot ever be reduced. This causes problems if -// too many physregs are coaleced with virtregs, which can cause the register -// allocator to wedge itself. -// -// This code triggers this problem more often if we pass args in registers, -// so disable it until this is fixed. -// -// NOTE: this isn't marked const, so that GCC doesn't emit annoying warnings -// about code being dead. -// -static unsigned FASTCC_NUM_INT_ARGS_INREGS = 0; - - /// HowToPassFastCCArgument - Returns how an formal argument of the specified /// type should be passed. If it is through stack, returns the size of the stack /// slot; if it is through integer or XMM register, returns the number of @@ -798,30 +778,38 @@ switch (ObjectVT) { default: assert(0 Unhandled argument type!); case MVT::i8: +#if FASTCC_NUM_INT_ARGS_INREGS 0 if (NumIntRegs FASTCC_NUM_INT_ARGS_INREGS) ObjIntRegs = 1; else +#endif ObjSize = 1; break; case MVT::i16: +#if FASTCC_NUM_INT_ARGS_INREGS 0 if (NumIntRegs FASTCC_NUM_INT_ARGS_INREGS) ObjIntRegs = 1; else +#endif ObjSize = 2; break; case MVT::i32: +#if FASTCC_NUM_INT_ARGS_INREGS 0 if (NumIntRegs FASTCC_NUM_INT_ARGS_INREGS) ObjIntRegs = 1; else +#endif ObjSize = 4; break; case MVT::i64: +#if FASTCC_NUM_INT_ARGS_INREGS 0 if (NumIntRegs+2 = FASTCC_NUM_INT_ARGS_INREGS) { ObjIntRegs = 2; } else if (NumIntRegs+1 = FASTCC_NUM_INT_ARGS_INREGS) { ObjIntRegs = 1; ObjSize = 4; } else +#endif ObjSize = 8; case MVT::f32: ObjSize = 4; @@ -1027,10 +1015,12 @@ case MVT::i8: case MVT::i16: case MVT::i32: +#if FASTCC_NUM_INT_ARGS_INREGS 0 if (NumIntRegs FASTCC_NUM_INT_ARGS_INREGS) { ++NumIntRegs; break; } +#endif // Fall through case MVT::f32: NumBytes += 4; @@ -1076,6 +1066,7 @@ case MVT::i8: case MVT::i16: case MVT::i32: +#if FASTCC_NUM_INT_ARGS_INREGS 0 if (NumIntRegs FASTCC_NUM_INT_ARGS_INREGS) { RegsToPass.push_back( std::make_pair(GPRArgRegs[Arg.getValueType()-MVT::i8][NumIntRegs], @@ -1083,6 +1074,7 @@ ++NumIntRegs; break; } +#endif // Fall through case MVT::f32: { SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.66 llvm/lib/Target/X86/X86ISelLowering.h:1.67 --- llvm/lib/Target/X86/X86ISelLowering.h:1.66 Wed May 24 19:59:30 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Sat Jun 24 03:36:10 2006 @@ -370,4 +370,20 @@ }; } +// FASTCC_NUM_INT_ARGS_INREGS - This is the max number of integer arguments +// to pass in registers. 0 is none, 1 is is use EAX, 2 is use EAX and +// EDX. Anything more is illegal. +// +// FIXME: The linscan register allocator currently has problem with +// coalescing. At the time of this writing, whenever it decides to coalesce +// a physreg with a virtreg, this increases the size of the physreg's live +// range, and the live range cannot ever be reduced. This causes problems if +// too many physregs are coaleced with virtregs, which can cause the register +// allocator to wedge itself. +// +// This code triggers this problem more often if we pass args in registers, +// so disable it until this is fixed. +// +#define FASTCC_NUM_INT_ARGS_INREGS 0 + #endif// X86ISELLOWERING_H Index: llvm/lib/Target/X86/X86JITInfo.cpp diff -u llvm/lib/Target/X86/X86JITInfo.cpp:1.20
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.211 - 1.212 X86ISelLowering.h updated: 1.65 - 1.66 --- Log message: Switch X86 over to a call-selection model where the lowering code creates the copyto/fromregs instead of making the X86ISD::CALL selection code create them. --- Diffs of the changes: (+391 -421) X86ISelLowering.cpp | 792 +--- X86ISelLowering.h | 20 - 2 files changed, 391 insertions(+), 421 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.211 llvm/lib/Target/X86/X86ISelLowering.cpp:1.212 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.211 Tue May 23 18:20:42 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed May 24 19:59:30 2006 @@ -358,29 +358,6 @@ allowUnalignedMemoryAccesses = true; // x86 supports it! } -std::pairSDOperand, SDOperand -X86TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, - bool isVarArg, unsigned CallingConv, - bool isTailCall, - SDOperand Callee, ArgListTy Args, - SelectionDAG DAG) { - assert((!isVarArg || CallingConv == CallingConv::C || - CallingConv == CallingConv::CSRet) - Only CCC/CSRet takes varargs!); - - // If the callee is a GlobalAddress node (quite common, every direct call is) - // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. - if (GlobalAddressSDNode *G = dyn_castGlobalAddressSDNode(Callee)) -Callee = DAG.getTargetGlobalAddress(G-getGlobal(), getPointerTy()); - else if (ExternalSymbolSDNode *S = dyn_castExternalSymbolSDNode(Callee)) -Callee = DAG.getTargetExternalSymbol(S-getSymbol(), getPointerTy()); - - if (CallingConv == CallingConv::Fast EnableFastCC) -return LowerFastCCCallTo(Chain, RetTy, isTailCall, Callee, Args, DAG); - return LowerallTo(Chain, RetTy, isVarArg, isTailCall, CallingConv, - Callee, Args, DAG); -} - //===--===// //C Calling Convention implementation //===--===// @@ -516,150 +493,134 @@ return DAG.getNode(ISD::MERGE_VALUES, RetVTs, ArgValues); } -std::pairSDOperand, SDOperand -X86TargetLowering::LowerallTo(SDOperand Chain, const Type *RetTy, - bool isVarArg, bool isTailCall, - unsigned CallingConv, - SDOperand Callee, ArgListTy Args, - SelectionDAG DAG) { - // Count how many bytes are to be pushed on the stack. - unsigned NumBytes = 0; + +SDOperand X86TargetLowering::LowerallTo(SDOperand Op, SelectionDAG DAG) { + SDOperand Chain = Op.getOperand(0); + unsigned CallingConv= castConstantSDNode(Op.getOperand(1))-getValue(); + bool isVarArg = castConstantSDNode(Op.getOperand(2))-getValue() != 0; + bool isTailCall = castConstantSDNode(Op.getOperand(3))-getValue() != 0; + SDOperand Callee= Op.getOperand(4); + MVT::ValueType RetVT= Op.Val-getValueType(0); + unsigned NumOps = (Op.getNumOperands() - 5) / 2; // Keep track of the number of XMM regs passed so far. unsigned NumXMMRegs = 0; - unsigned XMMArgRegs[] = { X86::XMM0, X86::XMM1, X86::XMM2 }; + static const unsigned XMMArgRegs[] = { +X86::XMM0, X86::XMM1, X86::XMM2 + }; - std::vectorSDOperand RegValuesToPass; - if (Args.empty()) { -// Save zero bytes. -Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(0, getPointerTy())); - } else { -for (unsigned i = 0, e = Args.size(); i != e; ++i) - switch (getValueType(Args[i].second)) { - default: assert(0 Unknown value type!); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - case MVT::f32: -NumBytes += 4; -break; - case MVT::i64: - case MVT::f64: -NumBytes += 8; -break; - case MVT::Vector: -if (NumXMMRegs 3) - ++NumXMMRegs; -else - NumBytes += 16; -break; - } + // Count how many bytes are to be pushed on the stack. + unsigned NumBytes = 0; + for (unsigned i = 0; i != NumOps; ++i) { +SDOperand Arg = Op.getOperand(5+2*i); -Chain = DAG.getCALLSEQ_START(Chain, - DAG.getConstant(NumBytes, getPointerTy())); +switch (Arg.getValueType()) { +default: assert(0 Unexpected ValueType for argument!); +case MVT::i8: +case MVT::i16: +case MVT::i32: +case MVT::f32: + NumBytes += 4; + break; +case MVT::i64: +case MVT::f64: + NumBytes += 8; + break; +case MVT::v16i8: +case MVT::v8i16: +case MVT::v4i32: +case MVT::v2i64: +case MVT::v4f32: +case
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.207 - 1.208 X86ISelLowering.h updated: 1.62 - 1.63 --- Log message: Implement an annoying part of the Darwin/X86 abi: the callee of a struct return argument pops the hidden struct pointer if present, not the caller. For example, in this testcase: struct X { int D, E, F, G; }; struct X bar() { struct X a; a.D = 0; a.E = 1; a.F = 2; a.G = 3; return a; } void foo(struct X *P) { *P = bar(); } We used to emit: _foo: subl $28, %esp movl 32(%esp), %eax movl %eax, (%esp) call _bar addl $28, %esp ret _bar: movl 4(%esp), %eax movl $0, (%eax) movl $1, 4(%eax) movl $2, 8(%eax) movl $3, 12(%eax) ret This is correct on Linux/X86 but not Darwin/X86. With this patch, we now emit: _foo: subl $28, %esp movl 32(%esp), %eax movl %eax, (%esp) call _bar *** addl $24, %esp ret _bar: movl 4(%esp), %eax movl $0, (%eax) movl $1, 4(%eax) movl $2, 8(%eax) movl $3, 12(%eax) *** ret $4 For the record, GCC emits (which is functionally equivalent to our new code): _bar: movl4(%esp), %eax movl$3, 12(%eax) movl$2, 8(%eax) movl$1, 4(%eax) movl$0, (%eax) ret $4 _foo: pushl %esi subl$40, %esp movl48(%esp), %esi leal16(%esp), %eax movl%eax, (%esp) call_bar subl$4, %esp movl16(%esp), %eax movl%eax, (%esi) movl20(%esp), %eax movl%eax, 4(%esi) movl24(%esp), %eax movl%eax, 8(%esi) movl28(%esp), %eax movl%eax, 12(%esi) addl$40, %esp popl%esi ret This fixes SingleSource/Benchmarks/CoyoteBench/fftbench with LLC and the JIT, and fixes the X86-backend portion of PR729: http://llvm.cs.uiuc.edu/PR729 . The CBE still needs to be updated. --- Diffs of the changes: (+19 -3) X86ISelLowering.cpp | 20 ++-- X86ISelLowering.h |2 +- 2 files changed, 19 insertions(+), 3 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.207 llvm/lib/Target/X86/X86ISelLowering.cpp:1.208 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.207 Fri May 19 16:34:04 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue May 23 13:50:38 2006 @@ -393,7 +393,8 @@ if (CallingConv == CallingConv::Fast EnableFastCC) return LowerFastCCCallTo(Chain, RetTy, isTailCall, Callee, Args, DAG); - return LowerallTo(Chain, RetTy, isVarArg, isTailCall, Callee, Args, DAG); + return LowerallTo(Chain, RetTy, isVarArg, isTailCall, CallingConv, + Callee, Args, DAG); } //===--===// @@ -520,6 +521,12 @@ ReturnAddrIndex = 0; // No return address slot generated yet. BytesToPopOnReturn = 0; // Callee pops nothing. BytesCallerReserves = ArgOffset; + + // If this is a struct return on Darwin/X86, the callee pops the hidden struct + // pointer. + if (F.getCallingConv() == CallingConv::CSRet + Subtarget-isTargetDarwin()) +BytesToPopOnReturn = 4; } void X86TargetLowering::LowerCCCArguments(SDOperand Op, SelectionDAG DAG) { @@ -551,6 +558,7 @@ std::pairSDOperand, SDOperand X86TargetLowering::LowerallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, bool isTailCall, + unsigned CallingConv, SDOperand Callee, ArgListTy Args, SelectionDAG DAG) { // Count how many bytes are to be pushed on the stack. @@ -704,13 +712,21 @@ Chain = DAG.getNode(X86ISD::CALL, NodeTys, Ops); InFlag = Chain.getValue(1); + // Create the CALLSEQ_END node. + unsigned NumBytesForCalleeToPush = 0; + + // If this is is a call to a struct-return function on Darwin/X86, the callee + // pops the hidden struct pointer, so we have to push it back. + if (CallingConv == CallingConv::CSRet Subtarget-isTargetDarwin()) +NumBytesForCalleeToPush = 4; + NodeTys.clear(); NodeTys.push_back(MVT::Other); // Returns a chain NodeTys.push_back(MVT::Flag);// Returns a flag for retval copy to use. Ops.clear(); Ops.push_back(Chain); Ops.push_back(DAG.getConstant(NumBytes, getPointerTy())); - Ops.push_back(DAG.getConstant(0, getPointerTy())); + Ops.push_back(DAG.getConstant(NumBytesForCalleeToPush, getPointerTy())); Ops.push_back(InFlag); Chain = DAG.getNode(ISD::CALLSEQ_END, NodeTys, Ops); InFlag = Chain.getValue(1); Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.62 llvm/lib/Target/X86/X86ISelLowering.h:1.63 ---
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.208 - 1.209 X86ISelLowering.h updated: 1.63 - 1.64 --- Log message: Remove PreprocessCCCArguments and PreprocessFastCCArguments now that FORMAL_ARGUMENTS nodes include a token operand. --- Diffs of the changes: (+124 -253) X86ISelLowering.cpp | 341 ++-- X86ISelLowering.h | 36 - 2 files changed, 124 insertions(+), 253 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.208 llvm/lib/Target/X86/X86ISelLowering.cpp:1.209 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.208 Tue May 23 13:50:38 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue May 23 16:06:34 2006 @@ -358,22 +358,6 @@ allowUnalignedMemoryAccesses = true; // x86 supports it! } -std::vectorSDOperand -X86TargetLowering::LowerArguments(Function F, SelectionDAG DAG) { - std::vectorSDOperand Args = TargetLowering::LowerArguments(F, DAG); - - FormalArgs.clear(); - FormalArgLocs.clear(); - - // This sets BytesToPopOnReturn, BytesCallerReserves, etc. which have to be - // set before the rest of the function can be lowered. - if (F.getCallingConv() == CallingConv::Fast EnableFastCC) -PreprocessFastCCArguments(Args, F, DAG); - else -PreprocessCCCArguments(Args, F, DAG); - return Args; -} - std::pairSDOperand, SDOperand X86TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, unsigned CallingConv, @@ -463,11 +447,12 @@ return Objs; } -void X86TargetLowering::PreprocessCCCArguments(std::vectorSDOperand Args, - Function F, SelectionDAG DAG) { - unsigned NumArgs = Args.size(); +SDOperand X86TargetLowering::LowerCCCArguments(SDOperand Op, SelectionDAG DAG) { + unsigned NumArgs = Op.Val-getNumValues() - 1; MachineFunction MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); + SDOperand Root = Op.getOperand(0); + std::vectorSDOperand ArgValues; // Add DAG nodes to load the arguments... On entry to a function on the X86, // the stack frame looks like this: @@ -481,78 +466,53 @@ unsigned NumXMMRegs = 0; // XMM regs used for parameter passing. unsigned XMMArgRegs[] = { X86::XMM0, X86::XMM1, X86::XMM2 }; for (unsigned i = 0; i NumArgs; ++i) { -SDOperand Op = Args[i]; -std::vectorSDOperand Objs = getFormalArgObjects(Op); -for (std::vectorSDOperand::iterator I = Objs.begin(), E = Objs.end(); - I != E; ++I) { - SDOperand Obj = *I; - MVT::ValueType ObjectVT = Obj.getValueType(); - unsigned ArgIncrement = 4; - unsigned ObjSize = 0; - unsigned ObjXMMRegs = 0; - HowToPassCCCArgument(ObjectVT, NumXMMRegs, ObjSize, ObjXMMRegs); - if (ObjSize = 8) -ArgIncrement = ObjSize; - - if (ObjXMMRegs) { -// Passed in a XMM register. -unsigned Reg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs], +MVT::ValueType ObjectVT = Op.getValue(i).getValueType(); +unsigned ArgIncrement = 4; +unsigned ObjSize = 0; +unsigned ObjXMMRegs = 0; +HowToPassCCCArgument(ObjectVT, NumXMMRegs, ObjSize, ObjXMMRegs); +if (ObjSize = 8) + ArgIncrement = ObjSize; + +SDOperand ArgValue; +if (ObjXMMRegs) { + // Passed in a XMM register. + unsigned Reg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs], X86::VR128RegisterClass); -std::pairFALocInfo, FALocInfo Loc = - std::make_pair(FALocInfo(FALocInfo::LiveInRegLoc, Reg, ObjectVT), - FALocInfo()); -FormalArgLocs.push_back(Loc); -NumXMMRegs += ObjXMMRegs; - } else { -// Create the frame index object for this incoming parameter... -int FI = MFI-CreateFixedObject(ObjSize, ArgOffset); -std::pairFALocInfo, FALocInfo Loc = - std::make_pair(FALocInfo(FALocInfo::StackFrameLoc, FI), FALocInfo()); -FormalArgLocs.push_back(Loc); -ArgOffset += ArgIncrement; // Move on to the next argument... - } + ArgValue= DAG.getCopyFromReg(Root, Reg, ObjectVT); + ArgValues.push_back(ArgValue); + NumXMMRegs += ObjXMMRegs; +} else { + // Create the frame index object for this incoming parameter... + int FI = MFI-CreateFixedObject(ObjSize, ArgOffset); + SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy()); + ArgValue = DAG.getLoad(Op.Val-getValueType(i), Root, FIN, + DAG.getSrcValue(NULL)); + ArgValues.push_back(ArgValue); + ArgOffset += ArgIncrement; // Move on to the next argument... } } + ArgValues.push_back(Root); + // If the function takes variable number of arguments, make a frame index for // the start of the first vararg value... for expansion of llvm.va_start. - if (F.isVarArg()) + if (MF.getFunction()-isVarArg()) VarArgsFrameIndex =
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.205 - 1.206 X86ISelLowering.h updated: 1.61 - 1.62 --- Log message: Should pass by reference. --- Diffs of the changes: (+4 -4) X86ISelLowering.cpp |4 ++-- X86ISelLowering.h |4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.205 llvm/lib/Target/X86/X86ISelLowering.cpp:1.206 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.205 Tue May 16 12:14:26 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed May 17 14:07:40 2006 @@ -461,7 +461,7 @@ return Objs; } -void X86TargetLowering::PreprocessCCCArguments(std::vectorSDOperandArgs, +void X86TargetLowering::PreprocessCCCArguments(std::vectorSDOperand Args, Function F, SelectionDAG DAG) { unsigned NumArgs = Args.size(); MachineFunction MF = DAG.getMachineFunction(); @@ -895,7 +895,7 @@ } void -X86TargetLowering::PreprocessFastCCArguments(std::vectorSDOperandArgs, +X86TargetLowering::PreprocessFastCCArguments(std::vectorSDOperand Args, Function F, SelectionDAG DAG) { unsigned NumArgs = Args.size(); MachineFunction MF = DAG.getMachineFunction(); Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.61 llvm/lib/Target/X86/X86ISelLowering.h:1.62 --- llvm/lib/Target/X86/X86ISelLowering.h:1.61 Wed Apr 26 20:32:22 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Wed May 17 14:07:40 2006 @@ -369,7 +369,7 @@ std::vectorstd::pairFALocInfo, FALocInfo FormalArgLocs; // C Calling Convention implementation. -void PreprocessCCCArguments(std::vectorSDOperandArgs, Function F, +void PreprocessCCCArguments(std::vectorSDOperand Args, Function F, SelectionDAG DAG); void LowerCCCArguments(SDOperand Op, SelectionDAG DAG); std::pairSDOperand, SDOperand @@ -379,7 +379,7 @@ // Fast Calling Convention implementation. void -PreprocessFastCCArguments(std::vectorSDOperandArgs, Function F, +PreprocessFastCCArguments(std::vectorSDOperand Args, Function F, SelectionDAG DAG); void LowerFastCCArguments(SDOperand Op, SelectionDAG DAG); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.189 - 1.190 X86ISelLowering.h updated: 1.60 - 1.61 --- Log message: - Clean up formal argument lowering code. Prepare for vector pass by value work. - Fixed vararg support. --- Diffs of the changes: (+237 -215) X86ISelLowering.cpp | 427 ++-- X86ISelLowering.h | 25 ++- 2 files changed, 237 insertions(+), 215 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.189 llvm/lib/Target/X86/X86ISelLowering.cpp:1.190 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.189 Wed Apr 26 13:21:31 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Apr 26 20:32:22 2006 @@ -366,12 +366,14 @@ std::vectorSDOperand Args = TargetLowering::LowerArguments(F, DAG); FormalArgs.clear(); + FormalArgLocs.clear(); + // This sets BytesToPopOnReturn, BytesCallerReserves, etc. which have to be set // before the rest of the function can be lowered. if (F.getCallingConv() == CallingConv::Fast EnableFastCC) -PreprocessFastCCArguments(Args[0], F, DAG); +PreprocessFastCCArguments(Args, F, DAG); else -PreprocessCCCArguments(Args[0], F, DAG); +PreprocessCCCArguments(Args, F, DAG); return Args; } @@ -400,28 +402,74 @@ //C Calling Convention implementation //===--===// -void X86TargetLowering::PreprocessCCCArguments(SDOperand Op, Function F, - SelectionDAG DAG) { - unsigned NumArgs = Op.Val-getNumValues(); +static unsigned getFormalArgSize(MVT::ValueType ObjectVT) { + unsigned ObjSize = 0; + switch (ObjectVT) { + default: assert(0 Unhandled argument type!); + case MVT::i1: + case MVT::i8: ObjSize = 1; break; + case MVT::i16: ObjSize = 2; break; + case MVT::i32: ObjSize = 4; break; + case MVT::i64: ObjSize = 8; break; + case MVT::f32: ObjSize = 4; break; + case MVT::f64: ObjSize = 8; break; + } + return ObjSize; +} + +static std::vectorSDOperand getFormalArgObjects(SDOperand Op) { + unsigned Opc = Op.getOpcode(); + std::vectorSDOperand Objs; + if (Opc == ISD::TRUNCATE) { +Op = Op.getOperand(0); +assert(Op.getOpcode() == ISD::AssertSext || + Op.getOpcode() == ISD::AssertZext); +Objs.push_back(Op.getOperand(0)); + } else if (Opc == ISD::FP_ROUND) { +Objs.push_back(Op.getOperand(0)); + } else if (Opc == ISD::BUILD_PAIR) { +Objs.push_back(Op.getOperand(0)); +Objs.push_back(Op.getOperand(1)); + } else { +Objs.push_back(Op); + } + return Objs; +} + +void X86TargetLowering::PreprocessCCCArguments(std::vectorSDOperandArgs, + Function F, SelectionDAG DAG) { + unsigned NumArgs = Args.size(); MachineFunction MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); + // Add DAG nodes to load the arguments... On entry to a function on the X86, + // the stack frame looks like this: + // + // [ESP] -- return address + // [ESP + 4] -- first argument (leftmost lexically) + // [ESP + 8] -- second argument, if first argument is four bytes in size + //... + // unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot for (unsigned i = 0; i NumArgs; ++i) { -MVT::ValueType ObjectVT = Op.Val-getValueType(i); -unsigned ArgIncrement = 4; -unsigned ObjSize; -switch (ObjectVT) { -default: assert(0 Unhandled argument type!); -case MVT::i1: -case MVT::i8: ObjSize = 1;break; -case MVT::i16: ObjSize = 2;break; -case MVT::i32: ObjSize = 4;break; -case MVT::i64: ObjSize = ArgIncrement = 8; break; -case MVT::f32: ObjSize = 4;break; -case MVT::f64: ObjSize = ArgIncrement = 8; break; +SDOperand Op = Args[i]; +std::vectorSDOperand Objs = getFormalArgObjects(Op); +for (std::vectorSDOperand::iterator I = Objs.begin(), E = Objs.end(); + I != E; ++I) { + SDOperand Obj = *I; + MVT::ValueType ObjectVT = Obj.getValueType(); + unsigned ArgIncrement = 4; + unsigned ObjSize = getFormalArgSize(ObjectVT); + if (ObjSize == 8) +ArgIncrement = 8; + + // Create the frame index object for this incoming parameter... + int FI = MFI-CreateFixedObject(ObjSize, ArgOffset); + std::pairFALocInfo, FALocInfo Loc = +std::make_pair(FALocInfo(FALocInfo::StackFrameLoc, FI), FALocInfo()); + FormalArgLocs.push_back(Loc); + ArgOffset += ArgIncrement; // Move on to the next argument... } -ArgOffset += ArgIncrement; // Move on to the next argument... } // If the function takes variable number of arguments, make a frame index for @@ -438,39 +486,13 @@ MachineFunction MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); - // Add DAG
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.187 - 1.188 X86ISelLowering.h updated: 1.59 - 1.60 --- Log message: Switching over FORMAL_ARGUMENTS mechanism to lower call arguments. --- Diffs of the changes: (+177 -80) X86ISelLowering.cpp | 245 +++- X86ISelLowering.h | 12 ++ 2 files changed, 177 insertions(+), 80 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.187 llvm/lib/Target/X86/X86ISelLowering.cpp:1.188 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.187 Tue Apr 25 15:13:52 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Apr 25 20:20:17 2006 @@ -363,9 +363,16 @@ std::vectorSDOperand X86TargetLowering::LowerArguments(Function F, SelectionDAG DAG) { + std::vectorSDOperand Args = TargetLowering::LowerArguments(F, DAG); + + FormalArgs.clear(); + // This sets BytesToPopOnReturn, BytesCallerReserves, etc. which have to be set + // before the rest of the function can be lowered. if (F.getCallingConv() == CallingConv::Fast EnableFastCC) -return LowerFastCCArguments(F, DAG); - return LowerCCCArguments(F, DAG); +PreprocessFastCCArguments(Args[0], F, DAG); + else +PreprocessCCCArguments(Args[0], F, DAG); + return Args; } std::pairSDOperand, SDOperand @@ -393,10 +400,41 @@ //C Calling Convention implementation //===--===// -std::vectorSDOperand -X86TargetLowering::LowerCCCArguments(Function F, SelectionDAG DAG) { - std::vectorSDOperand ArgValues; +void X86TargetLowering::PreprocessCCCArguments(SDOperand Op, Function F, + SelectionDAG DAG) { + unsigned NumArgs = Op.Val-getNumValues(); + MachineFunction MF = DAG.getMachineFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + + unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot + for (unsigned i = 0; i NumArgs; ++i) { +MVT::ValueType ObjectVT = Op.Val-getValueType(i); +unsigned ArgIncrement = 4; +unsigned ObjSize; +switch (ObjectVT) { +default: assert(0 Unhandled argument type!); +case MVT::i1: +case MVT::i8: ObjSize = 1;break; +case MVT::i16: ObjSize = 2;break; +case MVT::i32: ObjSize = 4;break; +case MVT::i64: ObjSize = ArgIncrement = 8; break; +case MVT::f32: ObjSize = 4;break; +case MVT::f64: ObjSize = ArgIncrement = 8; break; +} +ArgOffset += ArgIncrement; // Move on to the next argument... + } + // If the function takes variable number of arguments, make a frame index for + // the start of the first vararg value... for expansion of llvm.va_start. + if (F.isVarArg()) +VarArgsFrameIndex = MFI-CreateFixedObject(1, ArgOffset); + ReturnAddrIndex = 0; // No return address slot generated yet. + BytesToPopOnReturn = 0; // Callee pops nothing. + BytesCallerReserves = ArgOffset; +} + +void X86TargetLowering::LowerCCCArguments(SDOperand Op, SelectionDAG DAG) { + unsigned NumArgs = Op.Val-getNumValues(); MachineFunction MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); @@ -409,8 +447,8 @@ //... // unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot - for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { -MVT::ValueType ObjectVT = getValueType(I-getType()); + for (unsigned i = 0; i NumArgs; ++i) { +MVT::ValueType ObjectVT = Op.Val-getValueType(i); unsigned ArgIncrement = 4; unsigned ObjSize; switch (ObjectVT) { @@ -429,31 +467,11 @@ // Create the SelectionDAG nodes corresponding to a load from this parameter SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); -// Don't codegen dead arguments. FIXME: remove this check when we can nuke -// dead loads. -SDOperand ArgValue; -if (!I-use_empty()) - ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN, - DAG.getSrcValue(NULL)); -else { - if (MVT::isInteger(ObjectVT)) -ArgValue = DAG.getConstant(0, ObjectVT); - else -ArgValue = DAG.getConstantFP(0, ObjectVT); -} -ArgValues.push_back(ArgValue); - +SDOperand ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN, + DAG.getSrcValue(NULL)); +FormalArgs.push_back(ArgValue); ArgOffset += ArgIncrement; // Move on to the next argument... } - - // If the function takes variable number of arguments, make a frame index for - // the start of the first vararg value... for expansion of llvm.va_start. - if (F.isVarArg()) -VarArgsFrameIndex = MFI-CreateFixedObject(1, ArgOffset); - ReturnAddrIndex = 0; // No return address slot generated yet. - BytesToPopOnReturn = 0; // Callee pops nothing. - BytesCallerReserves =
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.177 - 1.178 X86ISelLowering.h updated: 1.56 - 1.57 --- Log message: - Added support to turn vector clear elements, e.g. pand V, -1, -1, 0, -1 to a vector shuffle. - VECTOR_SHUFFLE lowering change in preparation for more efficient codegen of vector shuffle with zero (or any splat) vector. --- Diffs of the changes: (+233 -78) X86ISelLowering.cpp | 299 ++-- X86ISelLowering.h | 12 +- 2 files changed, 233 insertions(+), 78 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.177 llvm/lib/Target/X86/X86ISelLowering.cpp:1.178 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.177 Wed Apr 19 19:11:39 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Thu Apr 20 03:58:49 2006 @@ -1501,45 +1501,51 @@ /// isSHUFPMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a shuffle of elements that is suitable for input to SHUFP*. -bool X86::isSHUFPMask(SDNode *N) { - assert(N-getOpcode() == ISD::BUILD_VECTOR); - - unsigned NumElems = N-getNumOperands(); - if (NumElems == 2) { -// The only cases that ought be handled by SHUFPD is -// Dest { 2, 1 } = shuffle( Dest { 1, 0 }, Src { 3, 2 } -// Dest { 3, 0 } = shuffle( Dest { 1, 0 }, Src { 3, 2 } -// Expect bit 0 == 1, bit1 == 2 -SDOperand Bit0 = N-getOperand(0); -SDOperand Bit1 = N-getOperand(1); -if (isUndefOrEqual(Bit0, 0) isUndefOrEqual(Bit1, 3)) - return true; -if (isUndefOrEqual(Bit0, 1) isUndefOrEqual(Bit1, 2)) - return true; -return false; - } +static bool isSHUFPMask(std::vectorSDOperand N) { + unsigned NumElems = N.size(); + if (NumElems != 2 NumElems != 4) return false; + + unsigned Half = NumElems / 2; + for (unsigned i = 0; i Half; ++i) +if (!isUndefOrInRange(N[i], 0, NumElems)) + return false; + for (unsigned i = Half; i NumElems; ++i) +if (!isUndefOrInRange(N[i], NumElems, NumElems*2)) + return false; - if (NumElems != 4) return false; + return true; +} - // Each half must refer to only one of the vector. - for (unsigned i = 0; i 2; ++i) { -SDOperand Arg = N-getOperand(i); -if (Arg.getOpcode() == ISD::UNDEF) continue; -assert(isaConstantSDNode(Arg) Invalid VECTOR_SHUFFLE mask!); -unsigned Val = castConstantSDNode(Arg)-getValue(); -if (Val = 4) return false; - } - for (unsigned i = 2; i 4; ++i) { -SDOperand Arg = N-getOperand(i); -if (Arg.getOpcode() == ISD::UNDEF) continue; -assert(isaConstantSDNode(Arg) Invalid VECTOR_SHUFFLE mask!); -unsigned Val = castConstantSDNode(Arg)-getValue(); -if (Val 4) return false; - } +bool X86::isSHUFPMask(SDNode *N) { + assert(N-getOpcode() == ISD::BUILD_VECTOR); + std::vectorSDOperand Ops(N-op_begin(), N-op_end()); + return ::isSHUFPMask(Ops); +} +/// isCommutedSHUFP - Returns true if the shuffle mask is except +/// the reverse of what x86 shuffles want. x86 shuffles requires the lower +/// half elements to come from vector 1 (which would equal the dest.) and +/// the upper half to come from vector 2. +static bool isCommutedSHUFP(std::vectorSDOperand Ops) { + unsigned NumElems = Ops.size(); + if (NumElems != 2 NumElems != 4) return false; + + unsigned Half = NumElems / 2; + for (unsigned i = 0; i Half; ++i) +if (!isUndefOrInRange(Ops[i], NumElems, NumElems*2)) + return false; + for (unsigned i = Half; i NumElems; ++i) +if (!isUndefOrInRange(Ops[i], 0, NumElems)) + return false; return true; } +static bool isCommutedSHUFP(SDNode *N) { + assert(N-getOpcode() == ISD::BUILD_VECTOR); + std::vectorSDOperand Ops(N-op_begin(), N-op_end()); + return isCommutedSHUFP(Ops); +} + /// isMOVHLPSMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a shuffle of elements that is suitable for input to MOVHLPS. bool X86::isMOVHLPSMask(SDNode *N) { @@ -1600,46 +1606,64 @@ /// isUNPCKLMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a shuffle of elements that is suitable for input to UNPCKL. -bool X86::isUNPCKLMask(SDNode *N) { - assert(N-getOpcode() == ISD::BUILD_VECTOR); - - unsigned NumElems = N-getNumOperands(); +bool static isUNPCKLMask(std::vectorSDOperand N, bool V2IsSplat = false) { + unsigned NumElems = N.size(); if (NumElems != 2 NumElems != 4 NumElems != 8 NumElems != 16) return false; for (unsigned i = 0, j = 0; i != NumElems; i += 2, ++j) { -SDOperand BitI = N-getOperand(i); -SDOperand BitI1 = N-getOperand(i+1); +SDOperand BitI = N[i]; +SDOperand BitI1 = N[i+1]; if (!isUndefOrEqual(BitI, j)) return false; -if (!isUndefOrEqual(BitI1, j + NumElems)) - return false; +if (V2IsSplat) { + if (isUndefOrEqual(BitI1, NumElems)) +return false; +} else { + if (!isUndefOrEqual(BitI1, j + NumElems)) +return false; +
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.178 - 1.179 X86ISelLowering.h updated: 1.57 - 1.58 X86InstrSSE.td updated: 1.109 - 1.110 --- Log message: Now generating perfect (I think) code for vector set with a single non-zero scalar value. e.g. _mm_set_epi32(0, a, 0, 0); == movd 4(%esp), %xmm0 pshufd $69, %xmm0, %xmm0 _mm_set_epi8(0, 0, 0, 0, 0, a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); == movzbw 4(%esp), %ax movzwl %ax, %eax pxor %xmm0, %xmm0 pinsrw $5, %eax, %xmm0 --- Diffs of the changes: (+175 -105) X86ISelLowering.cpp | 198 +--- X86ISelLowering.h | 11 +- X86InstrSSE.td | 71 +++--- 3 files changed, 175 insertions(+), 105 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.178 llvm/lib/Target/X86/X86ISelLowering.cpp:1.179 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.178 Thu Apr 20 03:58:49 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Thu Apr 20 20:05:10 2006 @@ -1687,11 +1687,12 @@ return true; } -/// isMOVSMask - Return true if the specified VECTOR_SHUFFLE operand -/// specifies a shuffle of elements that is suitable for input to MOVS{S|D}. -static bool isMOVSMask(std::vectorSDOperand N) { +/// isMOVLMask - Return true if the specified VECTOR_SHUFFLE operand +/// specifies a shuffle of elements that is suitable for input to MOVSS, +/// MOVSD, and MOVD, i.e. setting the lowest element. +static bool isMOVLMask(std::vectorSDOperand N) { unsigned NumElems = N.size(); - if (NumElems != 2 NumElems != 4) + if (NumElems != 2 NumElems != 4 NumElems != 8 NumElems != 16) return false; if (!isUndefOrEqual(N[0], NumElems)) @@ -1706,18 +1707,18 @@ return true; } -bool X86::isMOVSMask(SDNode *N) { +bool X86::isMOVLMask(SDNode *N) { assert(N-getOpcode() == ISD::BUILD_VECTOR); std::vectorSDOperand Ops(N-op_begin(), N-op_end()); - return ::isMOVSMask(Ops); + return ::isMOVLMask(Ops); } -/// isCommutedMOVS - Returns true if the shuffle mask is except the reverse -/// of what x86 movs want. X86 movs requires the lowest element to be lowest +/// isCommutedMOVL - Returns true if the shuffle mask is except the reverse +/// of what x86 movss want. X86 movs requires the lowest element to be lowest /// element of vector 2 and the other elements to come from vector 1 in order. -static bool isCommutedMOVS(std::vectorSDOperand Ops, bool V2IsSplat = false) { +static bool isCommutedMOVL(std::vectorSDOperand Ops, bool V2IsSplat = false) { unsigned NumElems = Ops.size(); - if (NumElems != 2 NumElems != 4) + if (NumElems != 2 NumElems != 4 NumElems != 8 NumElems != 16) return false; if (!isUndefOrEqual(Ops[0], 0)) @@ -1737,10 +1738,10 @@ return true; } -static bool isCommutedMOVS(SDNode *N, bool V2IsSplat = false) { +static bool isCommutedMOVL(SDNode *N, bool V2IsSplat = false) { assert(N-getOpcode() == ISD::BUILD_VECTOR); std::vectorSDOperand Ops(N-op_begin(), N-op_end()); - return isCommutedMOVS(Ops); + return isCommutedMOVL(Ops, V2IsSplat); } /// isMOVSHDUPMask - Return true if the specified VECTOR_SHUFFLE operand @@ -2055,9 +2056,9 @@ return Mask; } -/// getMOVSMask - Returns a vector_shuffle mask for an movs{s|d} operation -/// of specified width. -static SDOperand getMOVSMask(unsigned NumElems, SelectionDAG DAG) { +/// getMOVLMask - Returns a vector_shuffle mask for an movs{s|d}, movd +/// operation of specified width. +static SDOperand getMOVLMask(unsigned NumElems, SelectionDAG DAG) { MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems); MVT::ValueType BaseVT = MVT::getVectorBaseType(MaskVT); @@ -2095,30 +2096,63 @@ return DAG.getNode(ISD::BUILD_VECTOR, MaskVT, MaskVec); } +/// getZeroVector - Returns a vector of specified type with all zero elements. +/// +static SDOperand getZeroVector(MVT::ValueType VT, SelectionDAG DAG) { + assert(MVT::isVector(VT) Expected a vector type); + unsigned NumElems = getVectorNumElements(VT); + MVT::ValueType EVT = MVT::getVectorBaseType(VT); + bool isFP = MVT::isFloatingPoint(EVT); + SDOperand Zero = isFP ? DAG.getConstantFP(0.0, EVT) : DAG.getConstant(0, EVT); + std::vectorSDOperand ZeroVec(NumElems, Zero); + return DAG.getNode(ISD::BUILD_VECTOR, VT, ZeroVec); +} + /// PromoteSplat - Promote a splat of v8i16 or v16i8 to v4i32. /// static SDOperand PromoteSplat(SDOperand Op, SelectionDAG DAG) { SDOperand V1 = Op.getOperand(0); - SDOperand PermMask = Op.getOperand(2); + SDOperand Mask = Op.getOperand(2); MVT::ValueType VT = Op.getValueType(); - unsigned NumElems = PermMask.getNumOperands(); - PermMask = getUnpacklMask(NumElems, DAG); + unsigned NumElems = Mask.getNumOperands(); + Mask = getUnpacklMask(NumElems, DAG); while (NumElems != 4) { -V1 = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V1, PermMask); +
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.173 - 1.174 X86ISelLowering.h updated: 1.55 - 1.56 --- Log message: Commute vector_shuffle to match more movlhps, movlp{s|d} cases. --- Diffs of the changes: (+59 -63) X86ISelLowering.cpp | 115 +--- X86ISelLowering.h |7 --- 2 files changed, 59 insertions(+), 63 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.173 llvm/lib/Target/X86/X86ISelLowering.cpp:1.174 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.173 Mon Apr 17 17:45:49 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Apr 19 15:35:22 2006 @@ -1555,21 +1555,6 @@ isUndefOrEqual(N-getOperand(3), 3); } -/// isMOVLHPSMask - Return true if the specified VECTOR_SHUFFLE operand -/// specifies a shuffle of elements that is suitable for input to MOVHLPS. -bool X86::isMOVLHPSMask(SDNode *N) { - assert(N-getOpcode() == ISD::BUILD_VECTOR); - - if (N-getNumOperands() != 4) -return false; - - // Expect bit0 == 0, bit1 == 1, bit2 == 4, bit3 == 5 - return isUndefOrEqual(N-getOperand(0), 0) - isUndefOrEqual(N-getOperand(1), 1) - isUndefOrEqual(N-getOperand(2), 4) - isUndefOrEqual(N-getOperand(3), 5); -} - /// isMOVLPMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a shuffle of elements that is suitable for input to MOVLP{S|D}. bool X86::isMOVLPMask(SDNode *N) { @@ -1591,7 +1576,8 @@ } /// isMOVHPMask - Return true if the specified VECTOR_SHUFFLE operand -/// specifies a shuffle of elements that is suitable for input to MOVHP{S|D}. +/// specifies a shuffle of elements that is suitable for input to MOVHP{S|D} +/// and MOVLHPS. bool X86::isMOVHPMask(SDNode *N) { assert(N-getOpcode() == ISD::BUILD_VECTOR); @@ -1909,35 +1895,52 @@ return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V2, V1, Mask); } +/// ShouldXformToMOVHLPS - Return true if the node should be transformed to +/// match movhlps. The lower half elements should come from upper half of +/// V1 (and in order), and the upper half elements should come from the upper +/// half of V2 (and in order). +static bool ShouldXformToMOVHLPS(SDNode *Mask) { + unsigned NumElems = Mask-getNumOperands(); + if (NumElems != 4) +return false; + for (unsigned i = 0, e = 2; i != e; ++i) +if (!isUndefOrEqual(Mask-getOperand(i), i+2)) + return false; + for (unsigned i = 2; i != 4; ++i) +if (!isUndefOrEqual(Mask-getOperand(i), i+4)) + return false; + return true; +} + /// isScalarLoadToVector - Returns true if the node is a scalar load that /// is promoted to a vector. -static inline bool isScalarLoadToVector(SDOperand Op) { - if (Op.getOpcode() == ISD::SCALAR_TO_VECTOR) { -Op = Op.getOperand(0); -return (Op.getOpcode() == ISD::LOAD); +static inline bool isScalarLoadToVector(SDNode *N) { + if (N-getOpcode() == ISD::SCALAR_TO_VECTOR) { +N = N-getOperand(0).Val; +return (N-getOpcode() == ISD::LOAD); } return false; } -/// ShouldXformedToMOVLP - Return true if the node should be transformed to -/// match movlp{d|s}. The lower half elements should come from V1 (and in -/// order), and the upper half elements should come from the upper half of -/// V2 (not necessarily in order). And since V1 will become the source of -/// the MOVLP, it must be a scalar load. -static bool ShouldXformedToMOVLP(SDOperand V1, SDOperand V2, SDOperand Mask) { - if (isScalarLoadToVector(V1)) { -unsigned NumElems = Mask.getNumOperands(); -for (unsigned i = 0, e = NumElems/2; i != e; ++i) - if (!isUndefOrEqual(Mask.getOperand(i), i)) -return false; -for (unsigned i = NumElems/2; i != NumElems; ++i) - if (!isUndefOrInRange(Mask.getOperand(i), -NumElems+NumElems/2, NumElems*2)) -return false; -return true; - } +/// ShouldXformToMOVLP{S|D} - Return true if the node should be transformed to +/// match movlp{s|d}. The lower half elements should come from lower half of +/// V1 (and in order), and the upper half elements should come from the upper +/// half of V2 (and in order). And since V1 will become the source of the +/// MOVLP, it must be either a vector load or a scalar load to vector. +static bool ShouldXformToMOVLP(SDNode *V1, SDNode *Mask) { + if (V1-getOpcode() != ISD::LOAD !isScalarLoadToVector(V1)) +return false; - return false; + unsigned NumElems = Mask-getNumOperands(); + if (NumElems != 2 NumElems != 4) +return false; + for (unsigned i = 0, e = NumElems/2; i != e; ++i) +if (!isUndefOrEqual(Mask-getOperand(i), i)) + return false; + for (unsigned i = NumElems/2; i != NumElems; ++i) +if (!isUndefOrEqual(Mask-getOperand(i), i+NumElems)) + return false; + return true; } /// isLowerFromV2UpperFromV1 - Returns true if the shuffle mask is except @@ -2806,29 +2809,16 @@ return PromoteSplat(Op,
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.161 - 1.162 X86ISelLowering.h updated: 1.53 - 1.54 X86InstrSSE.td updated: 1.72 - 1.73 --- Log message: Added support for _mm_move_ss and _mm_move_sd. --- Diffs of the changes: (+46 -2) X86ISelLowering.cpp | 29 +++-- X86ISelLowering.h |4 X86InstrSSE.td | 15 +++ 3 files changed, 46 insertions(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.161 llvm/lib/Target/X86/X86ISelLowering.cpp:1.162 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.161 Mon Apr 10 02:23:14 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Mon Apr 10 19:19:04 2006 @@ -1684,6 +1684,26 @@ return true; } +/// isMOVSMask - Return true if the specified VECTOR_SHUFFLE operand +/// specifies a shuffle of elements that is suitable for input to MOVS{S|D}. +bool X86::isMOVSMask(SDNode *N) { + assert(N-getOpcode() == ISD::BUILD_VECTOR); + + unsigned NumElems = N-getNumOperands(); + if (NumElems != 2 NumElems != 4) +return false; + + if (!isUndefOrEqual(N-getOperand(0), NumElems)) +return false; + + for (unsigned i = 1; i NumElems; ++i) { +SDOperand Arg = N-getOperand(i); +if (!isUndefOrEqual(Arg, i)) + return false; + } + + return true; +} /// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand specifies /// a splat of a single element. @@ -2680,6 +2700,10 @@ if (NumElems == 2) return Op; +if (X86::isMOVSMask(PermMask.Val)) + // Leave the VECTOR_SHUFFLE alone. It matches MOVS{S|D}. + return Op; + if (X86::isUNPCKLMask(PermMask.Val) || X86::isUNPCKL_v_undef_Mask(PermMask.Val) || X86::isUNPCKHMask(PermMask.Val)) @@ -3106,10 +3130,11 @@ // Only do shuffles on 128-bit vector types for now. if (MVT::getSizeInBits(VT) == 64) return false; return (Mask.Val-getNumOperands() == 2 || - X86::isSplatMask(Mask.Val) || + X86::isSplatMask(Mask.Val) || + X86::isMOVSMask(Mask.Val) || X86::isPSHUFDMask(Mask.Val) || isPSHUFHW_PSHUFLWMask(Mask.Val) || - X86::isSHUFPMask(Mask.Val) || + X86::isSHUFPMask(Mask.Val) || X86::isUNPCKLMask(Mask.Val) || X86::isUNPCKL_v_undef_Mask(Mask.Val) || X86::isUNPCKHMask(Mask.Val)); Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.53 llvm/lib/Target/X86/X86ISelLowering.h:1.54 --- llvm/lib/Target/X86/X86ISelLowering.h:1.53 Thu Apr 6 18:23:56 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Mon Apr 10 19:19:04 2006 @@ -233,6 +233,10 @@ /// 0, 0, 1, 1 bool isUNPCKL_v_undef_Mask(SDNode *N); + /// isMOVSMask - Return true if the specified VECTOR_SHUFFLE operand + /// specifies a shuffle of elements that is suitable for input to MOVS{S|D}. + bool isMOVSMask(SDNode *N); + /// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a splat of a single element. bool isSplatMask(SDNode *N); Index: llvm/lib/Target/X86/X86InstrSSE.td diff -u llvm/lib/Target/X86/X86InstrSSE.td:1.72 llvm/lib/Target/X86/X86InstrSSE.td:1.73 --- llvm/lib/Target/X86/X86InstrSSE.td:1.72 Mon Apr 10 17:35:16 2006 +++ llvm/lib/Target/X86/X86InstrSSE.td Mon Apr 10 19:19:04 2006 @@ -104,6 +104,10 @@ return X86::isMOVLPMask(N); }]; +def MOVS_shuffle_mask : PatLeaf(build_vector), [{ + return X86::isMOVSMask(N); +}]; + def UNPCKL_shuffle_mask : PatLeaf(build_vector), [{ return X86::isUNPCKLMask(N); }]; @@ -1641,6 +1645,17 @@ movsd {$src2, $dst|$dst, $src2}, []; def MOVLDI2PDIrr : PDI0x6E, MRMSrcReg, (ops VR128:$dst, VR128:$src1, R32:$src2), movd {$src2, $dst|$dst, $src2}, []; + +def MOVLPSrr : SSI0x10, MRMSrcReg, (ops VR128:$dst, VR128:$src1, VR128:$src2), + movss {$src2, $dst|$dst, $src2}, + [(set VR128:$dst, + (v4f32 (vector_shuffle VR128:$src1, VR128:$src2, + MOVS_shuffle_mask)))]; +def MOVLPDrr : SDI0x10, MRMSrcReg, (ops VR128:$dst, VR128:$src1, VR128:$src2), + movsd {$src2, $dst|$dst, $src2}, + [(set VR128:$dst, + (v2f64 (vector_shuffle VR128:$src1, VR128:$src2, + MOVS_shuffle_mask)))]; } // Move to lower bits of a VR128 and zeroing upper bits. ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.158 - 1.159 X86ISelLowering.h updated: 1.52 - 1.53 X86InstrSSE.td updated: 1.64 - 1.65 --- Log message: - movlp{s|d} and movhp{s|d} support. - Normalize shuffle nodes so result vector lower half elements come from the first vector, the rest come from the second vector. (Except for the exceptions :-). - Other minor fixes. --- Diffs of the changes: (+206 -66) X86ISelLowering.cpp | 234 ++-- X86ISelLowering.h |8 + X86InstrSSE.td | 30 +- 3 files changed, 206 insertions(+), 66 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.158 llvm/lib/Target/X86/X86ISelLowering.cpp:1.159 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.158 Wed Apr 5 18:38:46 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Thu Apr 6 18:23:56 2006 @@ -1404,6 +1404,16 @@ (GV-isExternal() !GV-hasNotBeenReadFromBytecode())); } +/// isUndefOrInRange - Op is either an undef node or a ConstantSDNode. Return +/// true if Op is undef or if its value falls within the specified range (L, H). +static bool isUndefOrInRange(SDOperand Op, unsigned Low, unsigned Hi) { + if (Op.getOpcode() == ISD::UNDEF) +return true; + + unsigned Val = castConstantSDNode(Op)-getValue(); + return (Val = Low Val = Hi); +} + /// isPSHUFDMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a shuffle of elements that is suitable for input to PSHUFD. bool X86::isPSHUFDMask(SDNode *N) { @@ -1491,24 +1501,17 @@ unsigned NumElems = N-getNumOperands(); if (NumElems == 2) { -// The only case that ought be handled by SHUFPD is +// The only cases that ought be handled by SHUFPD is // Dest { 2, 1 } = shuffle( Dest { 1, 0 }, Src { 3, 2 } +// Dest { 3, 0 } = shuffle( Dest { 1, 0 }, Src { 3, 2 } // Expect bit 0 == 1, bit1 == 2 SDOperand Bit0 = N-getOperand(0); -if (Bit0.getOpcode() != ISD::UNDEF) { - assert(isaConstantSDNode(Bit0) Invalid VECTOR_SHUFFLE mask!); - if (castConstantSDNode(Bit0)-getValue() != 1) -return false; -} - SDOperand Bit1 = N-getOperand(1); -if (Bit1.getOpcode() != ISD::UNDEF) { - assert(isaConstantSDNode(Bit1) Invalid VECTOR_SHUFFLE mask!); - if (castConstantSDNode(Bit1)-getValue() != 2) -return false; -} - -return true; +if (isUndefOrInRange(Bit0, 0, 0) isUndefOrInRange(Bit1, 3, 3)) + return true; +if (isUndefOrInRange(Bit0, 1, 1) isUndefOrInRange(Bit1, 2, 2)) + return true; +return false; } if (NumElems != 4) return false; @@ -1614,6 +1617,62 @@ return true; } +/// isMOVLPMask - Return true if the specified VECTOR_SHUFFLE operand +/// specifies a shuffle of elements that is suitable for input to MOVLP{S|D}. +bool X86::isMOVLPMask(SDNode *N) { + assert(N-getOpcode() == ISD::BUILD_VECTOR); + + unsigned NumElems = N-getNumOperands(); + if (NumElems != 2 NumElems != 4) +return false; + + for (unsigned i = 0; i NumElems/2; ++i) { +SDOperand Arg = N-getOperand(i); +if (Arg.getOpcode() == ISD::UNDEF) continue; +assert(isaConstantSDNode(Arg) Invalid VECTOR_SHUFFLE mask!); +unsigned Val = castConstantSDNode(Arg)-getValue(); +if (Val != i + NumElems) return false; + } + + for (unsigned i = NumElems/2; i NumElems; ++i) { +SDOperand Arg = N-getOperand(i); +if (Arg.getOpcode() == ISD::UNDEF) continue; +assert(isaConstantSDNode(Arg) Invalid VECTOR_SHUFFLE mask!); +unsigned Val = castConstantSDNode(Arg)-getValue(); +if (Val != i) return false; + } + + return true; +} + +/// isMOVHPMask - Return true if the specified VECTOR_SHUFFLE operand +/// specifies a shuffle of elements that is suitable for input to MOVHP{S|D}. +bool X86::isMOVHPMask(SDNode *N) { + assert(N-getOpcode() == ISD::BUILD_VECTOR); + + unsigned NumElems = N-getNumOperands(); + if (NumElems != 2 NumElems != 4) +return false; + + for (unsigned i = 0; i NumElems/2; ++i) { +SDOperand Arg = N-getOperand(i); +if (Arg.getOpcode() == ISD::UNDEF) continue; +assert(isaConstantSDNode(Arg) Invalid VECTOR_SHUFFLE mask!); +unsigned Val = castConstantSDNode(Arg)-getValue(); +if (Val != i) return false; + } + + for (unsigned i = 0; i NumElems/2; ++i) { +SDOperand Arg = N-getOperand(i + NumElems/2); +if (Arg.getOpcode() == ISD::UNDEF) continue; +assert(isaConstantSDNode(Arg) Invalid VECTOR_SHUFFLE mask!); +unsigned Val = castConstantSDNode(Arg)-getValue(); +if (Val != i + NumElems) return false; + } + + return true; +} + /// isUNPCKLMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a shuffle of elements that is suitable for input to UNPCKL. bool X86::isUNPCKLMask(SDNode *N) { @@ -1786,42 +1845,6 @@ return Mask; } -/// NormalizeVectorShuffle - Swap vector_shuffle operands (as well as
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.156 - 1.157 X86ISelLowering.h updated: 1.50 - 1.51 X86InstrSSE.td updated: 1.61 - 1.62 --- Log message: Handle canonical form of e.g. vector_shuffle v1, v1, 0, 4, 1, 5, 2, 6, 3, 7 This is turned into vector_shuffle v1, undef, 0, 0, 1, 1, 2, 2, 3, 3 by dag combiner. It would match a {p}unpckl on x86. --- Diffs of the changes: (+56 -0) X86ISelLowering.cpp | 33 + X86ISelLowering.h |5 + X86InstrSSE.td | 18 ++ 3 files changed, 56 insertions(+) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.156 llvm/lib/Target/X86/X86ISelLowering.cpp:1.157 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.156 Wed Apr 5 01:11:20 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Apr 5 02:20:06 2006 @@ -1664,6 +1664,37 @@ return true; } +/// isUNPCKL_v_undef_Mask - Special case of isUNPCKLMask for canonical form +/// of vector_shuffle v, v, 0, 4, 1, 5, i.e. vector_shuffle v, undef, +/// 0, 0, 1, 1 +bool X86::isUNPCKL_v_undef_Mask(SDNode *N) { + assert(N-getOpcode() == ISD::BUILD_VECTOR); + + unsigned NumElems = N-getNumOperands(); + if (NumElems != 4 NumElems != 8 NumElems != 16) +return false; + + for (unsigned i = 0, j = 0; i != NumElems; i += 2, ++j) { +SDOperand BitI = N-getOperand(i); +SDOperand BitI1 = N-getOperand(i+1); + +if (BitI.getOpcode() != ISD::UNDEF) { + assert(isaConstantSDNode(BitI) Invalid VECTOR_SHUFFLE mask!); + if (castConstantSDNode(BitI)-getValue() != j) +return false; +} + +if (BitI1.getOpcode() != ISD::UNDEF) { + assert(isaConstantSDNode(BitI1) Invalid VECTOR_SHUFFLE mask!); + if (castConstantSDNode(BitI1)-getValue() != j) +return false; +} + } + + return true; +} + + /// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand specifies /// a splat of a single element. bool X86::isSplatMask(SDNode *N) { @@ -2604,6 +2635,7 @@ } if (X86::isUNPCKLMask(PermMask.Val) || +X86::isUNPCKL_v_undef_Mask(PermMask.Val) || X86::isUNPCKHMask(PermMask.Val)) // Leave the VECTOR_SHUFFLE alone. It matches {P}UNPCKL*. return Op; @@ -2929,5 +2961,6 @@ isPSHUFHW_PSHUFLWMask(Mask.Val) || X86::isSHUFPMask(Mask.Val) || X86::isUNPCKLMask(Mask.Val) || + X86::isUNPCKL_v_undef_Mask(Mask.Val) || X86::isUNPCKHMask(Mask.Val)); } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.50 llvm/lib/Target/X86/X86ISelLowering.h:1.51 --- llvm/lib/Target/X86/X86ISelLowering.h:1.50 Fri Mar 31 15:55:24 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Wed Apr 5 02:20:06 2006 @@ -220,6 +220,11 @@ /// specifies a shuffle of elements that is suitable for input to UNPCKH. bool isUNPCKHMask(SDNode *N); + /// isUNPCKL_v_undef_Mask - Special case of isUNPCKLMask for canonical form + /// of vector_shuffle v, v, 0, 4, 1, 5, i.e. vector_shuffle v, undef, + /// 0, 0, 1, 1 + bool isUNPCKL_v_undef_Mask(SDNode *N); + /// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a splat of a single element. bool isSplatMask(SDNode *N); Index: llvm/lib/Target/X86/X86InstrSSE.td diff -u llvm/lib/Target/X86/X86InstrSSE.td:1.61 llvm/lib/Target/X86/X86InstrSSE.td:1.62 --- llvm/lib/Target/X86/X86InstrSSE.td:1.61 Tue Apr 4 16:49:39 2006 +++ llvm/lib/Target/X86/X86InstrSSE.td Wed Apr 5 02:20:06 2006 @@ -100,6 +100,10 @@ return X86::isUNPCKHMask(N); }]; +def UNPCKL_v_undef_shuffle_mask : PatLeaf(build_vector), [{ + return X86::isUNPCKL_v_undef_Mask(N); +}]; + def PSHUFD_shuffle_mask : PatLeaf(build_vector), [{ return X86::isPSHUFDMask(N); }], SHUFFLE_get_shuf_imm; @@ -1733,6 +1737,20 @@ (v4f32 (PSHUFLWmi addr:$src1, PSHUFLW_fp_shuffle_mask:$sm)), Requires[HasSSE2]; +// vector_shuffle v1, undef, 0, 0, 1, 1, ... +def : Pat(v4f32 (vector_shuffle VR128:$src, (undef), + UNPCKL_v_undef_shuffle_mask)), + (UNPCKLPSrr VR128:$src, VR128:$src), Requires[HasSSE2]; +def : Pat(v16i8 (vector_shuffle VR128:$src, (undef), + UNPCKL_v_undef_shuffle_mask)), + (PUNPCKLBWrr VR128:$src, VR128:$src), Requires[HasSSE2]; +def : Pat(v8i16 (vector_shuffle VR128:$src, (undef), + UNPCKL_v_undef_shuffle_mask)), + (PUNPCKLWDrr VR128:$src, VR128:$src), Requires[HasSSE2]; +def : Pat(v4i32 (vector_shuffle VR128:$src, (undef), + UNPCKL_v_undef_shuffle_mask)), + (PUNPCKLDQrr VR128:$src, VR128:$src), Requires[HasSSE1]; + // 128-bit logical shifts def : Pat(int_x86_sse2_psll_dq VR128:$src1, imm:$src2), (v2i64 (PSLLDQri VR128:$src1, (PSxLDQ_imm imm:$src2))); ___ llvm-commits mailing list
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.157 - 1.158 X86ISelLowering.h updated: 1.51 - 1.52 X86InstrSSE.td updated: 1.62 - 1.63 --- Log message: Support for comi / ucomi intrinsics. --- Diffs of the changes: (+158 -10) X86ISelLowering.cpp | 133 +--- X86ISelLowering.h |2 X86InstrSSE.td | 33 3 files changed, 158 insertions(+), 10 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.157 llvm/lib/Target/X86/X86ISelLowering.cpp:1.158 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.157 Wed Apr 5 02:20:06 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Apr 5 18:38:46 2006 @@ -19,6 +19,7 @@ #include llvm/CallingConv.h #include llvm/Constants.h #include llvm/Function.h +#include llvm/Intrinsics.h #include llvm/ADT/VectorExtras.h #include llvm/Analysis/ScalarEvolutionExpressions.h #include llvm/CodeGen/MachineFrameInfo.h @@ -323,6 +324,9 @@ setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v8i16, Custom); } + // We want to custom lower some of our intrinsics. + setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); + computeRegisterProperties(); // FIXME: These should be based on subtarget info. Plus, the values should @@ -1185,9 +1189,8 @@ /// specific condition code. It returns a false if it cannot do a direct /// translation. X86CC is the translated CondCode. Flip is set to true if the /// the order of comparison operands should be flipped. -static bool translateX86CC(SDOperand CC, bool isFP, unsigned X86CC, - bool Flip) { - ISD::CondCode SetCCOpcode = castCondCodeSDNode(CC)-get(); +static bool translateX86CC(ISD::CondCode SetCCOpcode, bool isFP, + unsigned X86CC, bool Flip) { Flip = false; X86CC = X86ISD::COND_INVALID; if (!isFP) { @@ -1237,6 +1240,11 @@ return X86CC != X86ISD::COND_INVALID; } +static bool translateX86CC(SDOperand CC, bool isFP, unsigned X86CC, + bool Flip) { + return translateX86CC(castCondCodeSDNode(CC)-get(), isFP, X86CC, Flip); +} + /// hasFPCMov - is there a floating point cmov for the specific X86 condition /// code. Current x86 isa includes the following FP cmov instructions: /// fcmovb, fcomvbe, fcomve, fcmovu, fcmovae, fcmova, fcmovne, fcmovnu. @@ -2146,7 +2154,9 @@ // If the X86ISD::SETCC has more than one use, then it's probably better // to use a test instead of duplicating the X86ISD::CMP (for register // pressure reason). - if (Op0.getOperand(1).getOpcode() == X86ISD::CMP) { + unsigned CmpOpc = Op0.getOperand(1).getOpcode(); + if (CmpOpc == X86ISD::CMP || CmpOpc == X86ISD::COMI || + CmpOpc == X86ISD::UCOMI) { if (!Op0.hasOneUse()) { std::vectorMVT::ValueType Tys; for (unsigned i = 0; i Op0.Val-getNumValues(); ++i) @@ -2160,7 +2170,7 @@ CC = Op0.getOperand(0); Cond = Op0.getOperand(1); // Make a copy as flag result cannot be used by more than one. -Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, +Cond = DAG.getNode(CmpOpc, MVT::Flag, Cond.getOperand(0), Cond.getOperand(1)); addTest = isFPStack !hasFPCMov(castConstantSDNode(CC)-getSignExtended()); @@ -2201,7 +2211,9 @@ // If the X86ISD::SETCC has more than one use, then it's probably better // to use a test instead of duplicating the X86ISD::CMP (for register // pressure reason). - if (Cond.getOperand(1).getOpcode() == X86ISD::CMP) { + unsigned CmpOpc = Cond.getOperand(1).getOpcode(); + if (CmpOpc == X86ISD::CMP || CmpOpc == X86ISD::COMI || + CmpOpc == X86ISD::UCOMI) { if (!Cond.hasOneUse()) { std::vectorMVT::ValueType Tys; for (unsigned i = 0; i Cond.Val-getNumValues(); ++i) @@ -2215,7 +2227,7 @@ CC = Cond.getOperand(0); Cond = Cond.getOperand(1); // Make a copy as flag result cannot be used by more than one. -Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, +Cond = DAG.getNode(CmpOpc, MVT::Flag, Cond.getOperand(0), Cond.getOperand(1)); } else addTest = true; @@ -2829,6 +2841,111 @@ return SDOperand(); } + case ISD::INTRINSIC_WO_CHAIN: { +unsigned IntNo = castConstantSDNode(Op.getOperand(0))-getValue(); +switch (IntNo) { +default: return SDOperand();// Don't custom lower most intrinsics. +// Comparison intrinsics. +case Intrinsic::x86_sse_comieq_ss: +case Intrinsic::x86_sse_comilt_ss: +case Intrinsic::x86_sse_comile_ss: +case Intrinsic::x86_sse_comigt_ss: +case Intrinsic::x86_sse_comige_ss: +case Intrinsic::x86_sse_comineq_ss: +case Intrinsic::x86_sse_ucomieq_ss: +case Intrinsic::x86_sse_ucomilt_ss: +case
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.149 - 1.150 X86ISelLowering.h updated: 1.48 - 1.49 X86InstrSSE.td updated: 1.50 - 1.51 --- Log message: Add support to use pextrw and pinsrw to extract and insert a word element from a 128-bit vector. --- Diffs of the changes: (+69 -4) X86ISelLowering.cpp | 38 -- X86ISelLowering.h |4 X86InstrSSE.td | 31 +-- 3 files changed, 69 insertions(+), 4 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.149 llvm/lib/Target/X86/X86ISelLowering.cpp:1.150 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.149 Thu Mar 30 19:30:39 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Mar 31 13:22:53 2006 @@ -255,9 +255,9 @@ setOperationAction(ISD::SUB , (MVT::ValueType)VT, Expand); setOperationAction(ISD::MUL , (MVT::ValueType)VT, Expand); setOperationAction(ISD::LOAD, (MVT::ValueType)VT, Expand); -setOperationAction(ISD::VECTOR_SHUFFLE, (MVT::ValueType)VT, Expand); +setOperationAction(ISD::VECTOR_SHUFFLE, (MVT::ValueType)VT, Expand); setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::ValueType)VT, Expand); -setOperationAction(ISD::INSERT_VECTOR_ELT, (MVT::ValueType)VT, Expand); +setOperationAction(ISD::INSERT_VECTOR_ELT, (MVT::ValueType)VT, Expand); } if (Subtarget-hasMMX()) { @@ -316,6 +316,8 @@ setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v8i16, Custom); setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v4i32, Custom); setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v2i64, Custom); +setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v8i16, Custom); +setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v8i16, Custom); } computeRegisterProperties(); @@ -2657,6 +2659,37 @@ return SDOperand(); } + case ISD::EXTRACT_VECTOR_ELT: { +// Transform it so it match pextrw which produces a 32-bit result. +MVT::ValueType VT = Op.getValueType(); +if (MVT::getSizeInBits(VT) == 16) { + MVT::ValueType EVT = (MVT::ValueType)(VT+1); + SDOperand Extract = DAG.getNode(X86ISD::PEXTRW, EVT, + Op.getOperand(0), Op.getOperand(1)); + SDOperand Assert = DAG.getNode(ISD::AssertZext, EVT, Extract, + DAG.getValueType(VT)); + return DAG.getNode(ISD::TRUNCATE, VT, Assert); +} + +return SDOperand(); + } + case ISD::INSERT_VECTOR_ELT: { +// Transform it so it match pinsrw which expects a 16-bit value in a R32 +// as its second argument. +MVT::ValueType VT = Op.getValueType(); +MVT::ValueType BaseVT = MVT::getVectorBaseType(VT); +if (MVT::getSizeInBits(BaseVT) == 16) { + SDOperand N1 = Op.getOperand(1); + SDOperand N2 = Op.getOperand(2); + if (N1.getValueType() != MVT::i32) +N1 = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, N1); + if (N2.getValueType() != MVT::i32) +N2 = DAG.getConstant(castConstantSDNode(N2)-getValue(), MVT::i32); + return DAG.getNode(ISD::INSERT_VECTOR_ELT, VT, Op.getOperand(0), N1, N2); +} + +return SDOperand(); + } } } @@ -2692,6 +2725,7 @@ case X86ISD::Wrapper:return X86ISD::Wrapper; case X86ISD::S2VEC: return X86ISD::S2VEC; case X86ISD::ZEXT_S2VEC: return X86ISD::ZEXT_S2VEC; + case X86ISD::PEXTRW: return X86ISD::PEXTRW; } } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.48 llvm/lib/Target/X86/X86ISelLowering.h:1.49 --- llvm/lib/Target/X86/X86ISelLowering.h:1.48 Wed Mar 29 17:07:14 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Fri Mar 31 13:22:53 2006 @@ -153,6 +153,10 @@ /// ZEXT_S2VEC - SCALAR_TO_VECTOR with zero extension. The destination base /// does not have to match the operand type. ZEXT_S2VEC, + + /// PEXTRW - Extract a 16-bit value from a vector and zero extend it to + /// i32, corresponds to X86::PINSRW. + PEXTRW, }; // X86 specific condition code. These correspond to X86_*_COND in Index: llvm/lib/Target/X86/X86InstrSSE.td diff -u llvm/lib/Target/X86/X86InstrSSE.td:1.50 llvm/lib/Target/X86/X86InstrSSE.td:1.51 --- llvm/lib/Target/X86/X86InstrSSE.td:1.50 Thu Mar 30 13:54:57 2006 +++ llvm/lib/Target/X86/X86InstrSSE.td Fri Mar 31 13:22:53 2006 @@ -28,8 +28,8 @@ def X86zexts2vec : SDNodeX86ISD::ZEXT_S2VEC, SDTypeProfile1, 1, [], []; -def SDTUnpckl : SDTypeProfile1, 2, - [SDTCisSameAs0, 1, SDTCisSameAs1, 2]; +def X86pextrw : SDNodeX86ISD::PEXTRW, +SDTypeProfile1, 2, [], []; //===--===// // SSE pattern fragments @@ -1409,6 +1409,33 @@ UNPCKH_shuffle_mask)))]; } +//
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.150 - 1.151 X86ISelLowering.h updated: 1.49 - 1.50 X86InstrSSE.td updated: 1.52 - 1.53 --- Log message: Use a X86 target specific node X86ISD::PINSRW instead of a mal-formed INSERT_VECTOR_ELT to insert a 16-bit value in a 128-bit vector. --- Diffs of the changes: (+12 -6) X86ISelLowering.cpp |3 ++- X86ISelLowering.h |6 +- X86InstrSSE.td |9 + 3 files changed, 12 insertions(+), 6 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.150 llvm/lib/Target/X86/X86ISelLowering.cpp:1.151 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.150 Fri Mar 31 13:22:53 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Mar 31 15:55:24 2006 @@ -2685,7 +2685,7 @@ N1 = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, N1); if (N2.getValueType() != MVT::i32) N2 = DAG.getConstant(castConstantSDNode(N2)-getValue(), MVT::i32); - return DAG.getNode(ISD::INSERT_VECTOR_ELT, VT, Op.getOperand(0), N1, N2); + return DAG.getNode(X86ISD::PINSRW, VT, Op.getOperand(0), N1, N2); } return SDOperand(); @@ -2726,6 +2726,7 @@ case X86ISD::S2VEC: return X86ISD::S2VEC; case X86ISD::ZEXT_S2VEC: return X86ISD::ZEXT_S2VEC; case X86ISD::PEXTRW: return X86ISD::PEXTRW; + case X86ISD::PINSRW: return X86ISD::PINSRW; } } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.49 llvm/lib/Target/X86/X86ISelLowering.h:1.50 --- llvm/lib/Target/X86/X86ISelLowering.h:1.49 Fri Mar 31 13:22:53 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Fri Mar 31 15:55:24 2006 @@ -155,8 +155,12 @@ ZEXT_S2VEC, /// PEXTRW - Extract a 16-bit value from a vector and zero extend it to - /// i32, corresponds to X86::PINSRW. + /// i32, corresponds to X86::PEXTRW. PEXTRW, + + /// PINSRW - Insert the lower 16-bits of a 32-bit value to a vector, + /// corresponds to X86::PINSRW. + PINSRW, }; // X86 specific condition code. These correspond to X86_*_COND in Index: llvm/lib/Target/X86/X86InstrSSE.td diff -u llvm/lib/Target/X86/X86InstrSSE.td:1.52 llvm/lib/Target/X86/X86InstrSSE.td:1.53 --- llvm/lib/Target/X86/X86InstrSSE.td:1.52 Fri Mar 31 15:29:33 2006 +++ llvm/lib/Target/X86/X86InstrSSE.td Fri Mar 31 15:55:24 2006 @@ -27,9 +27,10 @@ SDTypeProfile1, 1, [], []; def X86zexts2vec : SDNodeX86ISD::ZEXT_S2VEC, SDTypeProfile1, 1, [], []; - def X86pextrw : SDNodeX86ISD::PEXTRW, SDTypeProfile1, 2, [], []; +def X86pinsrw : SDNodeX86ISD::PINSRW, +SDTypeProfile1, 3, [], []; //===--===// // SSE pattern fragments @@ -1468,13 +1469,13 @@ def PINSRWrr : PDIi80xC4, MRMSrcReg, (ops VR128:$dst, VR128:$src1, R32:$src2, i32i8imm:$src3), pinsrw {$src3, $src2, $dst|$dst, $src2, $src3}, - [(set VR128:$dst, (v8i16 (vector_insert (v8i16 VR128:$src1), - R32:$src2, (i32 imm:$src3]; + [(set VR128:$dst, (v8i16 (X86pinsrw (v8i16 VR128:$src1), + R32:$src2, (i32 imm:$src3]; def PINSRWrm : PDIi80xC4, MRMSrcMem, (ops VR128:$dst, VR128:$src1, i16mem:$src2, i32i8imm:$src3), pinsrw {$src3, $src2, $dst|$dst, $src2, $src3}, [(set VR128:$dst, - (v8i16 (vector_insert (v8i16 VR128:$src1), + (v8i16 (X86pinsrw (v8i16 VR128:$src1), (i32 (anyext (loadi16 addr:$src2))), (i32 imm:$src3]; } ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.144 - 1.145 X86ISelLowering.h updated: 1.47 - 1.48 X86InstrSSE.td updated: 1.44 - 1.45 --- Log message: - Added some SSE2 128-bit packed integer ops. - Added SSE2 128-bit integer pack with signed saturation ops. - Added pshufhw and pshuflw ops. --- Diffs of the changes: (+314 -25) X86ISelLowering.cpp | 106 - X86ISelLowering.h | 18 X86InstrSSE.td | 215 +++- 3 files changed, 314 insertions(+), 25 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.144 llvm/lib/Target/X86/X86ISelLowering.cpp:1.145 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.144 Wed Mar 29 13:02:40 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Mar 29 17:07:14 2006 @@ -1399,10 +1399,67 @@ return false; // Check if the value doesn't reference the second vector. - for (unsigned i = 1, e = N-getNumOperands(); i != e; ++i) { + for (unsigned i = 0, e = N-getNumOperands(); i != e; ++i) { assert(isaConstantSDNode(N-getOperand(i)) Invalid VECTOR_SHUFFLE mask!); -if (castConstantSDNode(N-getOperand(i))-getValue() = 4) return false; +if (castConstantSDNode(N-getOperand(i))-getValue() = 4) + return false; + } + + return true; +} + +/// isPSHUFHWMask - Return true if the specified VECTOR_SHUFFLE operand +/// specifies a shuffle of elements that is suitable for input to PSHUFD. +bool X86::isPSHUFHWMask(SDNode *N) { + assert(N-getOpcode() == ISD::BUILD_VECTOR); + + if (N-getNumOperands() != 8) +return false; + + // Lower quadword copied in order. + for (unsigned i = 0; i != 4; ++i) { +assert(isaConstantSDNode(N-getOperand(i)) + Invalid VECTOR_SHUFFLE mask!); +if (castConstantSDNode(N-getOperand(i))-getValue() != i) + return false; + } + + // Upper quadword shuffled. + for (unsigned i = 4; i != 8; ++i) { +assert(isaConstantSDNode(N-getOperand(i)) + Invalid VECTOR_SHUFFLE mask!); +unsigned Val = castConstantSDNode(N-getOperand(i))-getValue(); +if (Val 4 || Val 7) + return false; + } + + return true; +} + +/// isPSHUFLWMask - Return true if the specified VECTOR_SHUFFLE operand +/// specifies a shuffle of elements that is suitable for input to PSHUFD. +bool X86::isPSHUFLWMask(SDNode *N) { + assert(N-getOpcode() == ISD::BUILD_VECTOR); + + if (N-getNumOperands() != 8) +return false; + + // Upper quadword copied in order. + for (unsigned i = 4; i != 8; ++i) { +assert(isaConstantSDNode(N-getOperand(i)) + Invalid VECTOR_SHUFFLE mask!); +if (castConstantSDNode(N-getOperand(i))-getValue() != i) + return false; + } + + // Lower quadword shuffled. + for (unsigned i = 0; i != 4; ++i) { +assert(isaConstantSDNode(N-getOperand(i)) + Invalid VECTOR_SHUFFLE mask!); +unsigned Val = castConstantSDNode(N-getOperand(i))-getValue(); +if (Val 4) + return false; } return true; @@ -1431,7 +1488,7 @@ // Each half must refer to only one of the vector. SDOperand Elt = N-getOperand(0); assert(isaConstantSDNode(Elt) Invalid VECTOR_SHUFFLE mask!); - for (unsigned i = 1; i != NumElems / 2; ++i) { + for (unsigned i = 1; i NumElems / 2; ++i) { assert(isaConstantSDNode(N-getOperand(i)) Invalid VECTOR_SHUFFLE mask!); if (castConstantSDNode(N-getOperand(i))-getValue() != @@ -1440,7 +1497,7 @@ } Elt = N-getOperand(NumElems / 2); assert(isaConstantSDNode(Elt) Invalid VECTOR_SHUFFLE mask!); - for (unsigned i = NumElems / 2; i != NumElems; ++i) { + for (unsigned i = NumElems / 2 + 1; i NumElems; ++i) { assert(isaConstantSDNode(N-getOperand(i)) Invalid VECTOR_SHUFFLE mask!); if (castConstantSDNode(N-getOperand(i))-getValue() != @@ -1583,6 +1640,40 @@ return Mask; } +/// getShufflePSHUFHWImmediate - Return the appropriate immediate to shuffle +/// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUFHW +/// instructions. +unsigned X86::getShufflePSHUFHWImmediate(SDNode *N) { + unsigned Mask = 0; + // 8 nodes, but we only care about the last 4. + for (unsigned i = 7; i = 4; --i) { +unsigned Val + = castConstantSDNode(N-getOperand(i))-getValue(); +Mask |= (Val - 4); +if (i != 4) + Mask = 2; + } + + return Mask; +} + +/// getShufflePSHUFLWImmediate - Return the appropriate immediate to shuffle +/// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUFLW +/// instructions. +unsigned X86::getShufflePSHUFLWImmediate(SDNode *N) { + unsigned Mask = 0; + // 8 nodes, but we only care about the first 4. + for (int i = 3; i = 0; --i) { +unsigned Val + = castConstantSDNode(N-getOperand(i))-getValue(); +Mask |= Val; +if (i != 0) + Mask = 2; + } + + return Mask; +} + /// NormalizeVectorShuffle - Swap vector_shuffle operands (as well as ///
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.137 - 1.138 X86ISelLowering.h updated: 1.46 - 1.47 X86InstrSSE.td updated: 1.36 - 1.37 --- Log message: * Prefer using operation of matching types. e.g unpcklpd rather than movlhps. * Bug fixes. --- Diffs of the changes: (+73 -41) X86ISelLowering.cpp | 86 +--- X86ISelLowering.h |4 ++ X86InstrSSE.td | 24 -- 3 files changed, 73 insertions(+), 41 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.137 llvm/lib/Target/X86/X86ISelLowering.cpp:1.138 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.137 Mon Mar 27 20:43:26 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Mar 28 00:50:32 2006 @@ -1456,16 +1456,43 @@ bool X86::isMOVHLPSMask(SDNode *N) { assert(N-getOpcode() == ISD::BUILD_VECTOR); - if (N-getNumOperands() != 2) + if (N-getNumOperands() != 4) return false; - // Expect bit 0 == 1, bit1 == 1 + // Expect bit0 == 6, bit1 == 7, bit2 == 2, bit3 == 3 SDOperand Bit0 = N-getOperand(0); SDOperand Bit1 = N-getOperand(1); + SDOperand Bit2 = N-getOperand(2); + SDOperand Bit3 = N-getOperand(3); assert(isaConstantSDNode(Bit0) isaConstantSDNode(Bit1) + isaConstantSDNode(Bit2) isaConstantSDNode(Bit3) + Invalid VECTOR_SHUFFLE mask!); + return (castConstantSDNode(Bit0)-getValue() == 6 + castConstantSDNode(Bit1)-getValue() == 7 + castConstantSDNode(Bit2)-getValue() == 2 + castConstantSDNode(Bit3)-getValue() == 3); +} + +/// isMOVLHPSMask - Return true if the specified VECTOR_SHUFFLE operand +/// specifies a shuffle of elements that is suitable for input to MOVHLPS. +bool X86::isMOVLHPSMask(SDNode *N) { + assert(N-getOpcode() == ISD::BUILD_VECTOR); + + if (N-getNumOperands() != 4) +return false; + + // Expect bit0 == 0, bit1 == 1, bit2 == 4, bit3 == 5 + SDOperand Bit0 = N-getOperand(0); + SDOperand Bit1 = N-getOperand(1); + SDOperand Bit2 = N-getOperand(2); + SDOperand Bit3 = N-getOperand(3); + assert(isaConstantSDNode(Bit0) isaConstantSDNode(Bit1) + isaConstantSDNode(Bit2) isaConstantSDNode(Bit3) Invalid VECTOR_SHUFFLE mask!); return (castConstantSDNode(Bit0)-getValue() == 0 - castConstantSDNode(Bit1)-getValue() == 3); + castConstantSDNode(Bit1)-getValue() == 1 + castConstantSDNode(Bit2)-getValue() == 4 + castConstantSDNode(Bit3)-getValue() == 5); } /// isUNPCKLMask - Return true if the specified VECTOR_SHUFFLE operand @@ -1556,6 +1583,30 @@ return Mask; } +/// CommuteVectorShuffleIfNeeded - Swap vector_shuffle operands (as well as +/// values in ther permute mask if needed. Return an empty SDOperand is it is +/// already well formed. +static SDOperand CommuteVectorShuffleIfNeeded(SDOperand V1, SDOperand V2, + SDOperand Mask, MVT::ValueType VT, + SelectionDAG DAG) { + unsigned NumElems = Mask.getNumOperands(); + SDOperand Half1 = Mask.getOperand(0); + SDOperand Half2 = Mask.getOperand(NumElems/2); + if (castConstantSDNode(Half1)-getValue() = NumElems + castConstantSDNode(Half2)-getValue() NumElems) { +// Swap the operands and change mask. +std::vectorSDOperand MaskVec; +for (unsigned i = NumElems / 2; i != NumElems; ++i) + MaskVec.push_back(Mask.getOperand(i)); +for (unsigned i = 0; i != NumElems / 2; ++i) + MaskVec.push_back(Mask.getOperand(i)); +Mask = + DAG.getNode(ISD::BUILD_VECTOR, Mask.getValueType(), MaskVec); +return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V2, V1, Mask); + } + return SDOperand(); +} + /// LowerOperation - Provide custom lowering hooks for some operations. /// SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG DAG) { @@ -2336,11 +2387,10 @@ MVT::ValueType VT = Op.getValueType(); unsigned NumElems = PermMask.getNumOperands(); -// All v2f64 cases are handled. -if (NumElems == 2) return SDOperand(); - -// Handle splat cases. -if (X86::isSplatMask(PermMask.Val)) { +if (NumElems == 2) + return CommuteVectorShuffleIfNeeded(V1, V2, PermMask, VT, DAG); +else if (X86::isSplatMask(PermMask.Val)) { + // Handle splat cases. if (V2.getOpcode() == ISD::UNDEF) // Leave the VECTOR_SHUFFLE alone. It matches SHUFP*. return SDOperand(); @@ -2350,7 +2400,8 @@ return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, DAG.getNode(ISD::UNDEF, V1.getValueType()), PermMask); -} else if (X86::isUNPCKLMask(PermMask.Val)) { +} else if (X86::isUNPCKLMask(PermMask.Val) || + X86::isUNPCKHMask(PermMask.Val)) { // Leave the VECTOR_SHUFFLE alone. It matches {P}UNPCKL*. return SDOperand(); } else if
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.132 - 1.133 X86ISelLowering.h updated: 1.43 - 1.44 X86InstrSSE.td updated: 1.31 - 1.32 --- Log message: Remove X86:isZeroVector, use ISD::isBuildVectorAllZeros instead; some fixes / cleanups --- Diffs of the changes: (+44 -72) X86ISelLowering.cpp | 20 --- X86ISelLowering.h |4 -- X86InstrSSE.td | 92 3 files changed, 44 insertions(+), 72 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.132 llvm/lib/Target/X86/X86ISelLowering.cpp:1.133 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.132 Sat Mar 25 03:37:23 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Sun Mar 26 03:53:12 2006 @@ -1533,26 +1533,6 @@ return Mask; } -/// isZeroVector - Return true if this build_vector is an all-zero vector. -/// -bool X86::isZeroVector(SDNode *N) { - if (MVT::isInteger(N-getOperand(0).getValueType())) { -for (unsigned i = 0, e = N-getNumOperands(); i != e; ++i) - if (!isaConstantSDNode(N-getOperand(i)) || - castConstantSDNode(N-getOperand(i))-getValue() != 0) -return false; - } else { -assert(MVT::isFloatingPoint(N-getOperand(0).getValueType()) - Vector of non-int, non-float values?); -// See if this is all zeros. -for (unsigned i = 0, e = N-getNumOperands(); i != e; ++i) - if (!isaConstantFPSDNode(N-getOperand(i)) || - !castConstantFPSDNode(N-getOperand(i))-isExactlyValue(0.0)) -return false; - } - return true; -} - /// LowerOperation - Provide custom lowering hooks for some operations. /// SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG DAG) { Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.43 llvm/lib/Target/X86/X86ISelLowering.h:1.44 --- llvm/lib/Target/X86/X86ISelLowering.h:1.43 Sat Mar 25 03:37:23 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Sun Mar 26 03:53:12 2006 @@ -213,10 +213,6 @@ /// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUF* and SHUFP* /// instructions. unsigned getShuffleSHUFImmediate(SDNode *N); - - /// isZeroVector - Return true if this build_vector is an all-zero vector. - /// - bool isZeroVector(SDNode *N); } //===--===// Index: llvm/lib/Target/X86/X86InstrSSE.td diff -u llvm/lib/Target/X86/X86InstrSSE.td:1.31 llvm/lib/Target/X86/X86InstrSSE.td:1.32 --- llvm/lib/Target/X86/X86InstrSSE.td:1.31 Sat Mar 25 03:37:23 2006 +++ llvm/lib/Target/X86/X86InstrSSE.td Sun Mar 26 03:53:12 2006 @@ -51,10 +51,6 @@ return N-isExactlyValue(+0.0); }]; -def vecimm0 : PatLeaf(build_vector), [{ - return X86::isZeroVector(N); -}]; - // SHUFFLE_get_shuf_imm xform function: convert vector_shuffle mask to PSHUF*, // SHUFP* etc. imm. def SHUFFLE_get_shuf_imm : SDNodeXFormbuild_vector, [{ @@ -1000,24 +996,17 @@ // Alias Instructions //===--===// -// Alias instructions that map zero vector to xorp* for sse. +// Alias instructions that map zero vector to pxor / xorp* for sse. // FIXME: remove when we can teach regalloc that xor reg, reg is ok. -def VZEROv16i8 : I0xEF, MRMInitReg, (ops VR128:$dst), - pxor $dst, $dst, [(set VR128:$dst, (v16i8 vecimm0))], - Requires[HasSSE2], TB, OpSize; -def VZEROv8i16 : I0xEF, MRMInitReg, (ops VR128:$dst), - pxor $dst, $dst, [(set VR128:$dst, (v8i16 vecimm0))], - Requires[HasSSE2], TB, OpSize; -def VZEROv4i32 : I0xEF, MRMInitReg, (ops VR128:$dst), - pxor $dst, $dst, [(set VR128:$dst, (v4i32 vecimm0))], - Requires[HasSSE2], TB, OpSize; -def VZEROv2i64 : I0xEF, MRMInitReg, (ops VR128:$dst), - pxor $dst, $dst, [(set VR128:$dst, (v2i64 vecimm0))], - Requires[HasSSE2], TB, OpSize; -def VZEROv4f32 : PSI0x57, MRMInitReg, (ops VR128:$dst), - xorps $dst, $dst, [(set VR128:$dst, (v4f32 vecimm0))]; -def VZEROv2f64 : PDI0x57, MRMInitReg, (ops VR128:$dst), - xorpd $dst, $dst, [(set VR128:$dst, (v2f64 vecimm0))]; +def V_SET0_PI : PDI0xEF, MRMInitReg, (ops VR128:$dst), +pxor $dst, $dst, +[(set VR128:$dst, (v2i64 immAllZerosV))]; +def V_SET0_PS : PSI0x57, MRMInitReg, (ops VR128:$dst), +xorps $dst, $dst, +[(set VR128:$dst, (v4f32 immAllZerosV))]; +def V_SET0_PD : PDI0x57, MRMInitReg, (ops VR128:$dst), +xorpd $dst, $dst, +[(set VR128:$dst, (v2f64 immAllZerosV))]; // Scalar to 128-bit vector with zero extension. // Three operand (but two address) aliases. @@ -1057,80 +1046,87 @@ def : Pat(v4i32 (undef)), (IMPLICIT_DEF_VR128),
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.131 - 1.132 X86ISelLowering.h updated: 1.42 - 1.43 X86InstrSSE.td updated: 1.30 - 1.31 --- Log message: Build arbitrary vector with more than 2 distinct scalar elements with a series of unpack and interleave ops. --- Diffs of the changes: (+104 -5) X86ISelLowering.cpp | 29 +-- X86ISelLowering.h |4 ++ X86InstrSSE.td | 76 ++-- 3 files changed, 104 insertions(+), 5 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.131 llvm/lib/Target/X86/X86ISelLowering.cpp:1.132 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.131 Fri Mar 24 19:33:37 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Sat Mar 25 03:37:23 2006 @@ -2376,7 +2376,9 @@ abort(); } case ISD::BUILD_VECTOR: { +std::setSDOperand Values; SDOperand Elt0 = Op.getOperand(0); +Values.insert(Elt0); bool Elt0IsZero = (isaConstantSDNode(Elt0) castConstantSDNode(Elt0)-getValue() == 0) || (isaConstantFPSDNode(Elt0) @@ -2384,15 +2386,16 @@ bool RestAreZero = true; unsigned NumElems = Op.getNumOperands(); for (unsigned i = 1; i NumElems; ++i) { - SDOperand V = Op.getOperand(i); - if (ConstantFPSDNode *FPC = dyn_castConstantFPSDNode(V)) { + SDOperand Elt = Op.getOperand(i); + if (ConstantFPSDNode *FPC = dyn_castConstantFPSDNode(Elt)) { if (!FPC-isExactlyValue(+0.0)) RestAreZero = false; - } else if (ConstantSDNode *C = dyn_castConstantSDNode(V)) { + } else if (ConstantSDNode *C = dyn_castConstantSDNode(Elt)) { if (!C-isNullValue()) RestAreZero = false; } else RestAreZero = false; + Values.insert(Elt); } if (RestAreZero) { @@ -2402,6 +2405,25 @@ return DAG.getNode(X86ISD::ZEXT_S2VEC, Op.getValueType(), Elt0); } +if (Values.size() 2) { + // Expand into a number of unpckl*. + // e.g. for v4f32 + // Step 1: unpcklps 0, 2 == X: ?, ?, 2, 0 + // : unpcklps 1, 3 == Y: ?, ?, 3, 1 + // Step 2: unpcklps X, Y ==3, 2, 1, 0 + MVT::ValueType VT = Op.getValueType(); + std::vectorSDOperand V(NumElems); + for (unsigned i = 0; i NumElems; ++i) +V[i] = DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, Op.getOperand(i)); + NumElems = 1; + while (NumElems != 0) { +for (unsigned i = 0; i NumElems; ++i) + V[i] = DAG.getNode(X86ISD::UNPCKL, VT, V[i], V[i + NumElems]); +NumElems = 1; + } + return V[0]; +} + return SDOperand(); } } @@ -2439,6 +2461,7 @@ case X86ISD::Wrapper:return X86ISD::Wrapper; case X86ISD::S2VEC: return X86ISD::S2VEC; case X86ISD::ZEXT_S2VEC: return X86ISD::ZEXT_S2VEC; + case X86ISD::UNPCKL: return X86ISD::UNPCKL; } } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.42 llvm/lib/Target/X86/X86ISelLowering.h:1.43 --- llvm/lib/Target/X86/X86ISelLowering.h:1.42 Fri Mar 24 17:15:12 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Sat Mar 25 03:37:23 2006 @@ -153,6 +153,10 @@ /// ZEXT_S2VEC - SCALAR_TO_VECTOR with zero extension. The destination base /// does not have to match the operand type. ZEXT_S2VEC, + + /// UNPCKL - Unpack and interleave low. This corresponds to X86::UNPCKLPS, + /// X86::PUNPCKL*. + UNPCKL, }; // X86 specific condition code. These correspond to X86_*_COND in Index: llvm/lib/Target/X86/X86InstrSSE.td diff -u llvm/lib/Target/X86/X86InstrSSE.td:1.30 llvm/lib/Target/X86/X86InstrSSE.td:1.31 --- llvm/lib/Target/X86/X86InstrSSE.td:1.30 Sat Mar 25 00:03:26 2006 +++ llvm/lib/Target/X86/X86InstrSSE.td Sat Mar 25 03:37:23 2006 @@ -28,6 +28,11 @@ def X86zexts2vec : SDNodeX86ISD::ZEXT_S2VEC, SDTypeProfile1, 1, [], []; +def SDTUnpckl : SDTypeProfile1, 2, + [SDTCisSameAs0, 1, SDTCisSameAs1, 2]; +def X86unpckl : SDNodeX86ISD::UNPCKL, SDTUnpckl, +[]; + //===--===// // SSE pattern fragments //===--===// @@ -787,10 +792,14 @@ unpckhpd {$src2, $dst|$dst, $src2}, []; def UNPCKLPSrr : PSI0x14, MRMSrcReg, (ops VR128:$dst, VR128:$src1, VR128:$src2), -unpcklps {$src2, $dst|$dst, $src2}, []; +unpcklps {$src2, $dst|$dst, $src2}, +[(set VR128:$dst, (v4f32 (X86unpckl VR128:$src1, + VR128:$src2)))]; def UNPCKLPSrm : PSI0x14, MRMSrcMem, (ops VR128:$dst, VR128:$src1, f128mem:$src2), -
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.cpp X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.129 - 1.130 X86ISelLowering.h updated: 1.41 - 1.42 X86InstrInfo.cpp updated: 1.46 - 1.47 X86InstrSSE.td updated: 1.26 - 1.27 --- Log message: Support for scalar to vector with zero extension. --- Diffs of the changes: (+119 -52) X86ISelLowering.cpp | 70 ++-- X86ISelLowering.h | 16 +- X86InstrInfo.cpp|3 + X86InstrSSE.td | 82 +--- 4 files changed, 119 insertions(+), 52 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.129 llvm/lib/Target/X86/X86ISelLowering.cpp:1.130 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.129 Fri Mar 24 01:29:27 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Mar 24 17:15:12 2006 @@ -1398,8 +1398,8 @@ bool X86::isSHUFPMask(SDNode *N) { assert(N-getOpcode() == ISD::BUILD_VECTOR); - unsigned NumOperands = N-getNumOperands(); - if (NumOperands == 2) { + unsigned NumElems = N-getNumOperands(); + if (NumElems == 2) { // The only case that ought be handled by SHUFPD is // Dest { 2, 1 } = shuffle( Dest { 1, 0 }, Src { 3, 2 } // Expect bit 0 == 1, bit1 == 2 @@ -1411,21 +1411,21 @@ castConstantSDNode(Bit1)-getValue() == 2); } - if (NumOperands != 4) return false; + if (NumElems != 4) return false; // Each half must refer to only one of the vector. SDOperand Elt = N-getOperand(0); assert(isaConstantSDNode(Elt) Invalid VECTOR_SHUFFLE mask!); - for (unsigned i = 1; i != NumOperands / 2; ++i) { + for (unsigned i = 1; i != NumElems / 2; ++i) { assert(isaConstantSDNode(N-getOperand(i)) Invalid VECTOR_SHUFFLE mask!); if (castConstantSDNode(N-getOperand(i))-getValue() != castConstantSDNode(Elt)-getValue()) return false; } - Elt = N-getOperand(NumOperands / 2); + Elt = N-getOperand(NumElems / 2); assert(isaConstantSDNode(Elt) Invalid VECTOR_SHUFFLE mask!); - for (unsigned i = NumOperands / 2; i != NumOperands; ++i) { + for (unsigned i = NumElems / 2; i != NumElems; ++i) { assert(isaConstantSDNode(N-getOperand(i)) Invalid VECTOR_SHUFFLE mask!); if (castConstantSDNode(N-getOperand(i))-getValue() != @@ -1530,20 +1530,23 @@ return Mask; } -/// isZeroVector - Return true if all elements of BUILD_VECTOR are 0 or +0.0. +/// isZeroVector - Return true if this build_vector is an all-zero vector. +/// bool X86::isZeroVector(SDNode *N) { - for (SDNode::op_iterator I = N-op_begin(), E = N-op_end(); - I != E; ++I) { -if (ConstantFPSDNode *FPC = dyn_castConstantFPSDNode(*I)) { - if (!FPC-isExactlyValue(+0.0)) + if (MVT::isInteger(N-getOperand(0).getValueType())) { +for (unsigned i = 0, e = N-getNumOperands(); i != e; ++i) + if (!isaConstantSDNode(N-getOperand(i)) || + castConstantSDNode(N-getOperand(i))-getValue() != 0) return false; -} else if (ConstantSDNode *C = dyn_castConstantSDNode(*I)) { - if (!C-isNullValue()) + } else { +assert(MVT::isFloatingPoint(N-getOperand(0).getValueType()) + Vector of non-int, non-float values?); +// See if this is all zeros. +for (unsigned i = 0, e = N-getNumOperands(); i != e; ++i) + if (!isaConstantFPSDNode(N-getOperand(i)) || + !castConstantFPSDNode(N-getOperand(i))-isExactlyValue(0.0)) return false; -} else - return false; } - return true; } @@ -2318,7 +2321,7 @@ } case ISD::SCALAR_TO_VECTOR: { SDOperand AnyExt = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, Op.getOperand(0)); -return DAG.getNode(X86ISD::SCALAR_TO_VECTOR, Op.getValueType(), AnyExt); +return DAG.getNode(X86ISD::S2VEC, Op.getValueType(), AnyExt); } case ISD::VECTOR_SHUFFLE: { SDOperand V1 = Op.getOperand(0); @@ -2338,6 +2341,9 @@ return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, DAG.getNode(ISD::UNDEF, V1.getValueType()), PermMask); +} else if (NumElems == 2) { + // All v2f64 cases are handled. + return SDOperand(); } else if (X86::isPSHUFDMask(PermMask.Val)) { if (V2.getOpcode() == ISD::UNDEF) // Leave the VECTOR_SHUFFLE alone. It matches PSHUFD. @@ -2347,9 +2353,6 @@ return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, DAG.getNode(ISD::UNDEF, V1.getValueType()), PermMask); -} else if (NumElems == 2) { - // All v2f64 cases are handled. - return SDOperand(); } else if (X86::isSHUFPMask(PermMask.Val)) { SDOperand Elt = PermMask.getOperand(0); if (castConstantSDNode(Elt)-getValue() = NumElems) { @@ -2370,22 +2373,32 @@ abort(); } case ISD::BUILD_VECTOR: { -bool isZero = true; +SDOperand Elt0 = Op.getOperand(0); +bool Elt0IsZero =
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.125 - 1.126 X86ISelLowering.h updated: 1.39 - 1.40 X86InstrSSE.td updated: 1.22 - 1.23 --- Log message: More efficient v2f64 shuffle using movlhps, movhlps, unpckhpd, and unpcklpd. --- Diffs of the changes: (+128 -12) X86ISelLowering.cpp | 74 X86ISelLowering.h | 13 + X86InstrSSE.td | 53 - 3 files changed, 128 insertions(+), 12 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.125 llvm/lib/Target/X86/X86ISelLowering.cpp:1.126 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.125 Thu Mar 23 19:18:28 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Thu Mar 23 20:58:06 2006 @@ -1398,8 +1398,19 @@ assert(N-getOpcode() == ISD::BUILD_VECTOR); unsigned NumOperands = N-getNumOperands(); - if (NumOperands != 2 NumOperands != 4) -return false; + if (NumOperands == 2) { +// The only case that ought be handled by SHUFPD is +// Dest { 2, 1 } = shuffle( Dest { 1, 0 }, Src { 3, 2 } +// Expect bit 0 == 1, bit1 == 2 +SDOperand Bit0 = N-getOperand(0); +SDOperand Bit1 = N-getOperand(1); +assert(isaConstantSDNode(Bit0) isaConstantSDNode(Bit1) + Invalid VECTOR_SHUFFLE mask!); +return (castConstantSDNode(Bit0)-getValue() == 1 +castConstantSDNode(Bit1)-getValue() == 2); + } + + if (NumOperands != 4) return false; // Each half must refer to only one of the vector. SDOperand Elt = N-getOperand(0); @@ -1424,6 +1435,58 @@ return true; } +/// isMOVLHPSorUNPCKLPDMask - Return true if the specified VECTOR_SHUFFLE +/// operand specifies a shuffle of elements that is suitable for input to +/// MOVLHPS or UNPCKLPD. +bool X86::isMOVLHPSorUNPCKLPDMask(SDNode *N) { + assert(N-getOpcode() == ISD::BUILD_VECTOR); + + if (N-getNumOperands() != 2) +return false; + + // Expect bit 0 == 0, bit1 == 2 + SDOperand Bit0 = N-getOperand(0); + SDOperand Bit1 = N-getOperand(1); + assert(isaConstantSDNode(Bit0) isaConstantSDNode(Bit1) + Invalid VECTOR_SHUFFLE mask!); + return (castConstantSDNode(Bit0)-getValue() == 0 + castConstantSDNode(Bit1)-getValue() == 2); +} + +/// isMOVHLPSMask - Return true if the specified VECTOR_SHUFFLE operand +/// specifies a shuffle of elements that is suitable for input to MOVHLPS. +bool X86::isMOVHLPSMask(SDNode *N) { + assert(N-getOpcode() == ISD::BUILD_VECTOR); + + if (N-getNumOperands() != 2) +return false; + + // Expect bit 0 == 0, bit1 == 3 + SDOperand Bit0 = N-getOperand(0); + SDOperand Bit1 = N-getOperand(1); + assert(isaConstantSDNode(Bit0) isaConstantSDNode(Bit1) + Invalid VECTOR_SHUFFLE mask!); + return (castConstantSDNode(Bit0)-getValue() == 0 + castConstantSDNode(Bit1)-getValue() == 3); +} + +/// isUNPCKHPDMask - Return true if the specified VECTOR_SHUFFLE operand +/// specifies a shuffle of elements that is suitable for input to UNPCKHPD. +bool X86::isUNPCKHPDMask(SDNode *N) { + assert(N-getOpcode() == ISD::BUILD_VECTOR); + + if (N-getNumOperands() != 2) +return false; + + // Expect bit 0 == 1, bit1 == 3 + SDOperand Bit0 = N-getOperand(0); + SDOperand Bit1 = N-getOperand(1); + assert(isaConstantSDNode(Bit0) isaConstantSDNode(Bit1) + Invalid VECTOR_SHUFFLE mask!); + return (castConstantSDNode(Bit0)-getValue() == 1 + castConstantSDNode(Bit1)-getValue() == 3); +} + /// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand specifies /// a splat of a single element. bool X86::isSplatMask(SDNode *N) { @@ -2244,6 +2307,7 @@ SDOperand V2 = Op.getOperand(1); SDOperand PermMask = Op.getOperand(2); MVT::ValueType VT = Op.getValueType(); +unsigned NumElems = PermMask.getNumOperands(); // Handle splat cases. if (X86::isSplatMask(PermMask.Val)) { @@ -2265,8 +2329,7 @@ return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, DAG.getNode(ISD::UNDEF, V1.getValueType()), PermMask); -} else if (X86::isSHUFPMask(PermMask.Val)) { - unsigned NumElems = PermMask.getNumOperands(); +} else if (NumElems == 2 || X86::isSHUFPMask(PermMask.Val)) { SDOperand Elt = PermMask.getOperand(0); if (castConstantSDNode(Elt)-getValue() = NumElems) { // Swap the operands and change mask. @@ -2406,7 +2469,8 @@ X86TargetLowering::isShuffleMaskLegal(SDOperand Mask, MVT::ValueType VT) const { // Only do shuffles on 128-bit vector types for now. if (MVT::getSizeInBits(VT) == 64) return false; - return (X86::isSplatMask(Mask.Val) || + return (Mask.Val-getNumOperands() == 2 || + X86::isSplatMask(Mask.Val) || X86::isPSHUFDMask(Mask.Val) || X86::isSHUFPMask(Mask.Val)); } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrFPStack.td X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.128 - 1.129 X86ISelLowering.h updated: 1.40 - 1.41 X86InstrFPStack.td updated: 1.5 - 1.6 X86InstrSSE.td updated: 1.23 - 1.24 --- Log message: Handle BUILD_VECTOR with all zero elements. --- Diffs of the changes: (+73 -11) X86ISelLowering.cpp | 50 +++--- X86ISelLowering.h |3 +++ X86InstrFPStack.td |4 X86InstrSSE.td | 27 +++ 4 files changed, 73 insertions(+), 11 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.128 llvm/lib/Target/X86/X86ISelLowering.cpp:1.129 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.128 Fri Mar 24 01:12:19 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Mar 24 01:29:27 2006 @@ -277,7 +277,7 @@ setOperationAction(ISD::SUB, MVT::v4f32, Legal); setOperationAction(ISD::MUL, MVT::v4f32, Legal); setOperationAction(ISD::LOAD, MVT::v4f32, Legal); -setOperationAction(ISD::BUILD_VECTOR, MVT::v4f32, Expand); +setOperationAction(ISD::BUILD_VECTOR, MVT::v4f32, Custom); setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v4f32, Custom); } @@ -300,10 +300,11 @@ setOperationAction(ISD::LOAD, MVT::v8i16, Legal); setOperationAction(ISD::LOAD, MVT::v4i32, Legal); setOperationAction(ISD::LOAD, MVT::v2i64, Legal); -setOperationAction(ISD::BUILD_VECTOR, MVT::v2f64, Expand); -setOperationAction(ISD::BUILD_VECTOR, MVT::v16i8, Expand); -setOperationAction(ISD::BUILD_VECTOR, MVT::v8i16, Expand); -setOperationAction(ISD::BUILD_VECTOR, MVT::v4i32, Expand); +setOperationAction(ISD::BUILD_VECTOR, MVT::v2f64, Custom); +setOperationAction(ISD::BUILD_VECTOR, MVT::v16i8, Custom); +setOperationAction(ISD::BUILD_VECTOR, MVT::v8i16, Custom); +setOperationAction(ISD::BUILD_VECTOR, MVT::v4i32, Custom); +setOperationAction(ISD::BUILD_VECTOR, MVT::v2i64, Custom); setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v16i8, Custom); setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v8i16, Custom); setOperationAction(ISD::VECTOR_SHUFFLE, MVT::v2f64, Custom); @@ -1529,6 +1530,23 @@ return Mask; } +/// isZeroVector - Return true if all elements of BUILD_VECTOR are 0 or +0.0. +bool X86::isZeroVector(SDNode *N) { + for (SDNode::op_iterator I = N-op_begin(), E = N-op_end(); + I != E; ++I) { +if (ConstantFPSDNode *FPC = dyn_castConstantFPSDNode(*I)) { + if (!FPC-isExactlyValue(+0.0)) +return false; +} else if (ConstantSDNode *C = dyn_castConstantSDNode(*I)) { + if (!C-isNullValue()) +return false; +} else + return false; + } + + return true; +} + /// LowerOperation - Provide custom lowering hooks for some operations. /// SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG DAG) { @@ -2348,10 +2366,28 @@ return SDOperand(); } -// TODO. -assert(0 TODO); +assert(0 Unexpected VECTOR_SHUFFLE to lower); abort(); } + case ISD::BUILD_VECTOR: { +bool isZero = true; +unsigned NumElems = Op.getNumOperands(); +for (unsigned i = 0; i NumElems; ++i) { + SDOperand V = Op.getOperand(i); + if (ConstantFPSDNode *FPC = dyn_castConstantFPSDNode(V)) { +if (!FPC-isExactlyValue(+0.0)) + isZero = false; + } else if (ConstantSDNode *C = dyn_castConstantSDNode(V)) { +if (!C-isNullValue()) + isZero = false; + } else +isZero = false; +} + +if (isZero) + return Op; +return SDOperand(); + } } } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.40 llvm/lib/Target/X86/X86ISelLowering.h:1.41 --- llvm/lib/Target/X86/X86ISelLowering.h:1.40 Thu Mar 23 20:58:06 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Fri Mar 24 01:29:27 2006 @@ -208,6 +208,9 @@ /// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUF* and SHUFP* /// instructions. unsigned getShuffleSHUFImmediate(SDNode *N); + + /// isZeroVector - Return true if all elements of BUILD_VECTOR are 0 or +0.0. + bool isZeroVector(SDNode *N); } //===--===// Index: llvm/lib/Target/X86/X86InstrFPStack.td diff -u llvm/lib/Target/X86/X86InstrFPStack.td:1.5 llvm/lib/Target/X86/X86InstrFPStack.td:1.6 --- llvm/lib/Target/X86/X86InstrFPStack.td:1.5 Fri Mar 17 19:23:20 2006 +++ llvm/lib/Target/X86/X86InstrFPStack.td Fri Mar 24 01:29:27 2006 @@ -50,10 +50,6 @@ // FPStack pattern fragments //===--===// -def fp32imm0 : PatLeaf(f32 fpimm), [{ - return N-isExactlyValue(+0.0); -}]; - def fp64imm0 : PatLeaf(f64 fpimm), [{ return
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.117 - 1.118 X86ISelLowering.h updated: 1.35 - 1.36 X86InstrSSE.td updated: 1.14 - 1.15 --- Log message: - VECTOR_SHUFFLE of v4i32 / v4f32 with undef second vector always matches PSHUFD. We can make permutes entries which point to the undef pointing anything we want. - Change some names to appease Chris. --- Diffs of the changes: (+55 -45) X86ISelLowering.cpp | 52 +++- X86ISelLowering.h | 15 --- X86InstrSSE.td | 33 - 3 files changed, 55 insertions(+), 45 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.117 llvm/lib/Target/X86/X86ISelLowering.cpp:1.118 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.117 Tue Mar 21 22:18:34 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Mar 22 02:01:21 2006 @@ -1368,27 +1368,6 @@ (GV-isExternal() !GV-hasNotBeenReadFromBytecode())); } -/// isPSHUFDMask - Return true if the specified VECTOR_SHUFFLE operand -/// specifies a shuffle of elements that is suitable for input to PSHUFD. -bool X86::isPSHUFDMask(SDNode *N) { - assert(N-getOpcode() == ISD::BUILD_VECTOR); - - if (N-getNumOperands() != 4) -return false; - - // This is a splat operation if each element of the permute is the same, and - // if the value doesn't reference the second vector. - SDOperand Elt = N-getOperand(0); - assert(isaConstantSDNode(Elt) Invalid VECTOR_SHUFFLE mask!); - for (unsigned i = 1, e = N-getNumOperands(); i != e; ++i) { -assert(isaConstantSDNode(N-getOperand(i)) - Invalid VECTOR_SHUFFLE mask!); -if (castConstantSDNode(N-getOperand(i))-getValue() = 4) return false; - } - - return true; -} - /// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand specifies /// a splat of a single element. bool X86::isSplatMask(SDNode *N) { @@ -1412,9 +1391,10 @@ return castConstantSDNode(Elt)-getValue() N-getNumOperands(); } -/// getShuffleImmediate - Return the appropriate immediate to shuffle -/// the specified isShuffleMask VECTOR_SHUFFLE mask. -unsigned X86::getShuffleImmediate(SDNode *N) { +/// getShuffleSHUFImmediate - Return the appropriate immediate to shuffle +/// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUF* and SHUFP* +/// instructions. +unsigned X86::getShuffleSHUFImmediate(SDNode *N) { unsigned NumOperands = N-getNumOperands(); unsigned Shift = (NumOperands == 4) ? 2 : 1; unsigned Mask = 0; @@ -1428,6 +1408,28 @@ return Mask; } +/// getShufflePSHUFDImmediate - Return the appropriate immediate to shuffle +/// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUFD instruction. +unsigned X86::getShufflePSHUFDImmediate(SDNode *N) { + unsigned NumOperands = N-getNumOperands(); + unsigned Mask = 0; + + assert(NumOperands == 4 Expect v4f32 / v4i32 vector operand); + + unsigned i = NumOperands - 1; + do { +uint64_t Val = castConstantSDNode(N-getOperand(i))-getValue(); +// Second vector operand must be undef. We can have it point to anything +// we want. +if (Val = NumOperands) Val = 0; +Mask |= Val; +Mask = 2; +--i; + } while (i != 0); + + return Mask; +} + /// LowerOperation - Provide custom lowering hooks for some operations. /// SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG DAG) { @@ -2217,7 +2219,7 @@ return DAG.getNode(X86ISD::UNPCKLP, VT, V1, V1); // Leave the VECTOR_SHUFFLE alone. It matches SHUFP*. return SDOperand(); - } else if (VT == MVT::v4f32 X86::isPSHUFDMask(PermMask.Val)) + } else if (VT == MVT::v4f32) // Leave the VECTOR_SHUFFLE alone. It matches PSHUFD. return SDOperand(); } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.35 llvm/lib/Target/X86/X86ISelLowering.h:1.36 --- llvm/lib/Target/X86/X86ISelLowering.h:1.35 Tue Mar 21 20:53:00 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Wed Mar 22 02:01:21 2006 @@ -179,17 +179,18 @@ /// Define some predicates that are used for node matching. namespace X86 { - /// isPSHUFDMask - Return true if the specified VECTOR_SHUFFLE operand - /// specifies a shuffle of elements that is suitable for input to PSHUFD. - bool isPSHUFDMask(SDNode *N); - /// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a splat of a single element. bool isSplatMask(SDNode *N); - /// getShuffleImmediate - Return the appropriate immediate to shuffle - /// the specified isShuffleMask VECTOR_SHUFFLE mask. - unsigned getShuffleImmediate(SDNode *N); + /// getShuffleSHUFImmediate - Return the appropriate immediate to shuffle + /// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUF* and SHUFP* + /// instructions. + unsigned getShuffleSHUFImmediate(SDNode *N); + +
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.118 - 1.119 X86ISelLowering.h updated: 1.36 - 1.37 X86InstrSSE.td updated: 1.15 - 1.16 --- Log message: - Implement X86ISelLowering::isShuffleMaskLegal(). We currently only support splat and PSHUFD cases. - Clean up shuffle / splat matching code. --- Diffs of the changes: (+73 -21) X86ISelLowering.cpp | 52 X86ISelLowering.h |9 + X86InstrSSE.td | 33 - 3 files changed, 73 insertions(+), 21 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.118 llvm/lib/Target/X86/X86ISelLowering.cpp:1.119 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.118 Wed Mar 22 02:01:21 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Mar 22 12:59:22 2006 @@ -1368,6 +1368,26 @@ (GV-isExternal() !GV-hasNotBeenReadFromBytecode())); } +/// isPSHUFDMask - Return true if the specified VECTOR_SHUFFLE operand +/// specifies a shuffle of elements that is suitable for input to PSHUFD. +bool X86::isPSHUFDMask(SDNode *N) { + assert(N-getOpcode() == ISD::BUILD_VECTOR); + + if (N-getNumOperands() != 4) +return false; + + // Check if the value doesn't reference the second vector. + SDOperand Elt = N-getOperand(0); + assert(isaConstantSDNode(Elt) Invalid VECTOR_SHUFFLE mask!); + for (unsigned i = 1, e = N-getNumOperands(); i != e; ++i) { +assert(isaConstantSDNode(N-getOperand(i)) + Invalid VECTOR_SHUFFLE mask!); +if (castConstantSDNode(N-getOperand(i))-getValue() = 4) return false; + } + + return true; +} + /// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand specifies /// a splat of a single element. bool X86::isSplatMask(SDNode *N) { @@ -2211,17 +2231,26 @@ SDOperand PermMask = Op.getOperand(2); MVT::ValueType VT = Op.getValueType(); -if (V2.getOpcode() == ISD::UNDEF) { - // Handle splat cases. - if (X86::isSplatMask(PermMask.Val)) { -if (VT == MVT::v2f64 || VT == MVT::v2i64) - // Use unpcklpd - return DAG.getNode(X86ISD::UNPCKLP, VT, V1, V1); +// Handle splat cases. +if (X86::isSplatMask(PermMask.Val)) { + if (V2.getOpcode() == ISD::UNDEF) // Leave the VECTOR_SHUFFLE alone. It matches SHUFP*. return SDOperand(); - } else if (VT == MVT::v4f32) + else +// Make it match SHUFP* or UNPCKLPD. Second vector is undef since it's +// not needed. +return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, + DAG.getNode(ISD::UNDEF, V1.getValueType()), + PermMask); +} else if (X86::isPSHUFDMask(PermMask.Val)) { + if (V2.getOpcode() == ISD::UNDEF) // Leave the VECTOR_SHUFFLE alone. It matches PSHUFD. return SDOperand(); + else +// Make it match PSHUFD. Second vector is undef since it's not needed. +return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, + DAG.getNode(ISD::UNDEF, V1.getValueType()), + PermMask); } // TODO. @@ -2262,7 +2291,6 @@ case X86ISD::GlobalBaseReg: return X86ISD::GlobalBaseReg; case X86ISD::Wrapper:return X86ISD::Wrapper; case X86ISD::SCALAR_TO_VECTOR: return X86ISD::SCALAR_TO_VECTOR; - case X86ISD::UNPCKLP:return X86ISD::UNPCKLP; } } @@ -2341,3 +2369,11 @@ } else return true; } + +/// isShuffleMaskLegal - Targets can use this to indicate that they only +/// support *some* VECTOR_SHUFFLE operations, those with specific masks. +/// By default, if a target supports the VECTOR_SHUFFLE node, all mask values +/// are assumed to be legal. +bool X86TargetLowering::isShuffleMaskLegal(SDOperand Mask) const { + return (X86::isSplatMask(Mask.Val) || X86::isPSHUFDMask(Mask.Val)); +} Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.36 llvm/lib/Target/X86/X86ISelLowering.h:1.37 --- llvm/lib/Target/X86/X86ISelLowering.h:1.36 Wed Mar 22 02:01:21 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Wed Mar 22 12:59:22 2006 @@ -179,6 +179,10 @@ /// Define some predicates that are used for node matching. namespace X86 { + /// isPSHUFDMask - Return true if the specified VECTOR_SHUFFLE operand + /// specifies a shuffle of elements that is suitable for input to PSHUFD. + bool isPSHUFDMask(SDNode *N); + /// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a splat of a single element. bool isSplatMask(SDNode *N); @@ -259,6 +263,11 @@ virtual bool isLegalAddressImmediate(int64_t V) const; virtual bool isLegalAddressImmediate(GlobalValue *GV) const; +/// isShuffleMaskLegal - Targets can use this to indicate that they only +/// support *some* VECTOR_SHUFFLE operations, those with specific masks. +
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.121 - 1.122 X86ISelLowering.h updated: 1.37 - 1.38 --- Log message: Added a ValueType operand to isShuffleMaskLegal(). For now, x86 will not do 64-bit vector shuffle. --- Diffs of the changes: (+5 -2) X86ISelLowering.cpp |5 - X86ISelLowering.h |2 +- 2 files changed, 5 insertions(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.121 llvm/lib/Target/X86/X86ISelLowering.cpp:1.122 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.121 Wed Mar 22 13:22:18 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Mar 22 16:07:06 2006 @@ -2371,7 +2371,10 @@ /// support *some* VECTOR_SHUFFLE operations, those with specific masks. /// By default, if a target supports the VECTOR_SHUFFLE node, all mask values /// are assumed to be legal. -bool X86TargetLowering::isShuffleMaskLegal(SDOperand Mask) const { +bool +X86TargetLowering::isShuffleMaskLegal(SDOperand Mask, MVT::ValueType VT) const { + // Only do shuffles on 128-bit vector types for now. + if (MVT::getSizeInBits(VT) == 64) return false; return (X86::isSplatMask(Mask.Val) || (Subtarget-hasSSE2() X86::isPSHUFDMask(Mask.Val))); } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.37 llvm/lib/Target/X86/X86ISelLowering.h:1.38 --- llvm/lib/Target/X86/X86ISelLowering.h:1.37 Wed Mar 22 12:59:22 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Wed Mar 22 16:07:06 2006 @@ -267,7 +267,7 @@ /// support *some* VECTOR_SHUFFLE operations, those with specific masks. /// By default, if a target supports the VECTOR_SHUFFLE node, all mask values /// are assumed to be legal. -virtual bool isShuffleMaskLegal(SDOperand Mask) const; +virtual bool isShuffleMaskLegal(SDOperand Mask, MVT::ValueType VT) const; private: // C Calling Convention implementation. std::vectorSDOperand LowerCCCArguments(Function F, SelectionDAG DAG); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrMMX.td X86InstrSSE.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.114 - 1.115 X86ISelLowering.h updated: 1.33 - 1.34 X86InstrMMX.td updated: 1.5 - 1.6 X86InstrSSE.td updated: 1.11 - 1.12 --- Log message: - Use movaps to store 128-bit vector integers. - Each scalar to vector v8i16 and v16i8 is a any_extend followed by a movd. --- Diffs of the changes: (+71 -34) X86ISelLowering.cpp | 41 ++ X86ISelLowering.h |4 +++ X86InstrMMX.td |4 ++- X86InstrSSE.td | 56 +--- 4 files changed, 71 insertions(+), 34 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.114 llvm/lib/Target/X86/X86ISelLowering.cpp:1.115 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.114 Tue Mar 21 14:51:05 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Mar 21 17:01:21 2006 @@ -265,19 +265,19 @@ addRegisterClass(MVT::v2i32, X86::VR64RegisterClass); // FIXME: add MMX packed arithmetics -setOperationAction(ISD::BUILD_VECTOR, MVT::v8i8, Expand); -setOperationAction(ISD::BUILD_VECTOR, MVT::v4i16, Expand); -setOperationAction(ISD::BUILD_VECTOR, MVT::v2i32, Expand); +setOperationAction(ISD::BUILD_VECTOR, MVT::v8i8, Expand); +setOperationAction(ISD::BUILD_VECTOR, MVT::v4i16, Expand); +setOperationAction(ISD::BUILD_VECTOR, MVT::v2i32, Expand); } if (TM.getSubtargetX86Subtarget().hasSSE1()) { addRegisterClass(MVT::v4f32, X86::VR128RegisterClass); -setOperationAction(ISD::ADD, MVT::v4f32, Legal); -setOperationAction(ISD::SUB, MVT::v4f32, Legal); -setOperationAction(ISD::MUL, MVT::v4f32, Legal); -setOperationAction(ISD::LOAD , MVT::v4f32, Legal); -setOperationAction(ISD::BUILD_VECTOR, MVT::v4f32, Expand); +setOperationAction(ISD::ADD, MVT::v4f32, Legal); +setOperationAction(ISD::SUB, MVT::v4f32, Legal); +setOperationAction(ISD::MUL, MVT::v4f32, Legal); +setOperationAction(ISD::LOAD, MVT::v4f32, Legal); +setOperationAction(ISD::BUILD_VECTOR, MVT::v4f32, Expand); } if (TM.getSubtargetX86Subtarget().hasSSE2()) { @@ -288,15 +288,17 @@ addRegisterClass(MVT::v2i64, X86::VR128RegisterClass); -setOperationAction(ISD::ADD, MVT::v2f64, Legal); -setOperationAction(ISD::SUB, MVT::v2f64, Legal); -setOperationAction(ISD::MUL, MVT::v2f64, Legal); -setOperationAction(ISD::LOAD , MVT::v2f64, Legal); -setOperationAction(ISD::BUILD_VECTOR, MVT::v2f64, Expand); -setOperationAction(ISD::BUILD_VECTOR, MVT::v16i8, Expand); -setOperationAction(ISD::BUILD_VECTOR, MVT::v8i16, Expand); -setOperationAction(ISD::BUILD_VECTOR, MVT::v4i32, Expand); -setOperationAction(ISD::BUILD_VECTOR, MVT::v2i64, Expand); +setOperationAction(ISD::ADD, MVT::v2f64, Legal); +setOperationAction(ISD::SUB, MVT::v2f64, Legal); +setOperationAction(ISD::MUL, MVT::v2f64, Legal); +setOperationAction(ISD::LOAD, MVT::v2f64, Legal); +setOperationAction(ISD::BUILD_VECTOR, MVT::v2f64, Expand); +setOperationAction(ISD::BUILD_VECTOR, MVT::v16i8, Expand); +setOperationAction(ISD::BUILD_VECTOR, MVT::v8i16, Expand); +setOperationAction(ISD::BUILD_VECTOR, MVT::v4i32, Expand); +setOperationAction(ISD::BUILD_VECTOR, MVT::v2i64, Expand); +setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v16i8, Custom); +setOperationAction(ISD::SCALAR_TO_VECTOR, MVT::v8i16, Custom); } computeRegisterProperties(); @@ -2135,6 +2137,10 @@ Copy, DAG.getConstant(getBytesToPopOnReturn(), MVT::i16), Copy.getValue(1)); } + case ISD::SCALAR_TO_VECTOR: { +SDOperand AnyExt = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, Op.getOperand(0)); +return DAG.getNode(X86ISD::SCALAR_TO_VECTOR, Op.getValueType(), AnyExt); + } } } @@ -2168,6 +2174,7 @@ case X86ISD::LOAD_PACK: return X86ISD::LOAD_PACK; case X86ISD::GlobalBaseReg: return X86ISD::GlobalBaseReg; case X86ISD::Wrapper:return X86ISD::Wrapper; + case X86ISD::SCALAR_TO_VECTOR: return X86ISD::SCALAR_TO_VECTOR; } } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.33 llvm/lib/Target/X86/X86ISelLowering.h:1.34 --- llvm/lib/Target/X86/X86ISelLowering.h:1.33 Mon Mar 13 17:20:37 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Tue Mar 21 17:01:21 2006 @@ -145,6 +145,10 @@ /// TCPWrapper - A wrapper node for TargetConstantPool, /// TargetExternalSymbol, and TargetGlobalAddress. Wrapper, + + /// SCALAR_TO_VECTOR - X86 version of SCALAR_TO_VECTOR. The destination base + /// type does not have to match the operand type. + SCALAR_TO_VECTOR,
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.90 - 1.91 X86ISelLowering.h updated: 1.28 - 1.29 --- Log message: Updates to match change of getRegForInlineAsmConstraint prototype --- Diffs of the changes: (+5 -3) X86ISelLowering.cpp |5 +++-- X86ISelLowering.h |3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.90 llvm/lib/Target/X86/X86ISelLowering.cpp:1.91 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.90Sat Feb 18 01:26:17 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Feb 21 17:11:00 2006 @@ -1961,7 +1961,8 @@ } std::vectorunsigned X86TargetLowering:: -getRegForInlineAsmConstraint(const std::string Constraint) const { +getRegForInlineAsmConstraint(const std::string Constraint, + MVT::ValueType VT) const { if (Constraint.size() == 1) { // FIXME: not handling fp-stack yet! // FIXME: not handling MMX registers yet ('y' constraint). @@ -1993,5 +1994,5 @@ } // Handle explicit register names. - return TargetLowering::getRegForInlineAsmConstraint(Constraint); + return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.28 llvm/lib/Target/X86/X86ISelLowering.h:1.29 --- llvm/lib/Target/X86/X86ISelLowering.h:1.28 Fri Feb 17 18:15:05 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Tue Feb 21 17:11:00 2006 @@ -224,7 +224,8 @@ SDOperand getReturnAddressFrameIndex(SelectionDAG DAG); std::vectorunsigned - getRegForInlineAsmConstraint(const std::string Constraint) const; + getRegForInlineAsmConstraint(const std::string Constraint, + MVT::ValueType VT) const; private: // C Calling Convention implementation. std::vectorSDOperand LowerCCCArguments(Function F, SelectionDAG DAG); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.91 - 1.92 X86ISelLowering.h updated: 1.29 - 1.30 --- Log message: split register class handling from explicit physreg handling. --- Diffs of the changes: (+5 -6) X86ISelLowering.cpp |7 +++ X86ISelLowering.h |4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.91 llvm/lib/Target/X86/X86ISelLowering.cpp:1.92 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.91Tue Feb 21 17:11:00 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Feb 21 18:56:39 2006 @@ -1961,8 +1961,8 @@ } std::vectorunsigned X86TargetLowering:: -getRegForInlineAsmConstraint(const std::string Constraint, - MVT::ValueType VT) const { +getRegClassForInlineAsmConstraint(const std::string Constraint, + MVT::ValueType VT) const { if (Constraint.size() == 1) { // FIXME: not handling fp-stack yet! // FIXME: not handling MMX registers yet ('y' constraint). @@ -1993,6 +1993,5 @@ } } - // Handle explicit register names. - return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); + return std::vectorunsigned(); } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.29 llvm/lib/Target/X86/X86ISelLowering.h:1.30 --- llvm/lib/Target/X86/X86ISelLowering.h:1.29 Tue Feb 21 17:11:00 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Tue Feb 21 18:56:39 2006 @@ -224,8 +224,8 @@ SDOperand getReturnAddressFrameIndex(SelectionDAG DAG); std::vectorunsigned - getRegForInlineAsmConstraint(const std::string Constraint, - MVT::ValueType VT) const; + getRegClassForInlineAsmConstraint(const std::string Constraint, +MVT::ValueType VT) const; private: // C Calling Convention implementation. std::vectorSDOperand LowerCCCArguments(Function F, SelectionDAG DAG); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.83 - 1.84 X86ISelLowering.h updated: 1.25 - 1.26 --- Log message: Rework the SelectionDAG-based implementations of SimplifyDemandedBits and ComputeMaskedBits to match the new improved versions in instcombine. Tested against all of multisource/benchmarks on ppc. --- Diffs of the changes: (+18 -11) X86ISelLowering.cpp | 14 +- X86ISelLowering.h | 15 +-- 2 files changed, 18 insertions(+), 11 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.83 llvm/lib/Target/X86/X86ISelLowering.cpp:1.84 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.83Wed Feb 15 18:21:07 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Thu Feb 16 15:11:51 2006 @@ -2035,19 +2035,23 @@ } } -bool X86TargetLowering::isMaskedValueZeroForTargetNode(const SDOperand Op, - uint64_t Mask) const { +void X86TargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op, + uint64_t Mask, + uint64_t KnownZero, + uint64_t KnownOne, + unsigned Depth) const { unsigned Opc = Op.getOpcode(); + KnownZero = KnownOne = 0; // Don't know anything. switch (Opc) { default: assert(Opc = ISD::BUILTIN_OP_END Expected a target specific node); break; - case X86ISD::SETCC: return (Mask 1) == 0; + case X86ISD::SETCC: +KnownZero |= (MVT::getIntVTBitMask(Op.getValueType()) ^ 1ULL); +break; } - - return false; } std::vectorunsigned X86TargetLowering:: Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.25 llvm/lib/Target/X86/X86ISelLowering.h:1.26 --- llvm/lib/Target/X86/X86ISelLowering.h:1.25 Fri Feb 3 20:20:30 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Thu Feb 16 15:11:51 2006 @@ -218,12 +218,15 @@ /// DAG node. virtual const char *getTargetNodeName(unsigned Opcode) const; -/// isMaskedValueZeroForTargetNode - Return true if 'Op Mask' is known to -/// be zero. Op is expected to be a target specific node. Used by DAG -/// combiner. -virtual bool isMaskedValueZeroForTargetNode(const SDOperand Op, -uint64_t Mask) const; - +/// computeMaskedBitsForTargetNode - Determine which of the bits specified +/// in Mask are known to be either zero or one and return them in the +/// KnownZero/KnownOne bitsets. +virtual void computeMaskedBitsForTargetNode(const SDOperand Op, +uint64_t Mask, +uint64_t KnownZero, +uint64_t KnownOne, +unsigned Depth = 0) const; + SDOperand getReturnAddressFrameIndex(SelectionDAG DAG); std::vectorunsigned ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.85 - 1.86 X86ISelLowering.h updated: 1.26 - 1.27 X86InstrInfo.td updated: 1.236 - 1.237 --- Log message: kill ADD_PARTS SUB_PARTS and replace them with fancy new ADDC, ADDE, SUBC and SUBE nodes that actually expose what's going on and allow for significant simplifications in the targets. --- Diffs of the changes: (+28 -77) X86ISelLowering.cpp | 30 X86ISelLowering.h | 10 X86InstrInfo.td | 65 ++-- 3 files changed, 28 insertions(+), 77 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.85 llvm/lib/Target/X86/X86ISelLowering.cpp:1.86 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.85Thu Feb 16 18:03:04 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Thu Feb 16 23:43:56 2006 @@ -160,8 +160,6 @@ // Darwin ABI issue. setOperationAction(ISD::GlobalAddress , MVT::i32 , Custom); // 64-bit addm sub, shl, sra, srl (iff 32-bit x86) - setOperationAction(ISD::ADD_PARTS , MVT::i32 , Custom); - setOperationAction(ISD::SUB_PARTS , MVT::i32 , Custom); setOperationAction(ISD::SHL_PARTS , MVT::i32 , Custom); setOperationAction(ISD::SRA_PARTS , MVT::i32 , Custom); setOperationAction(ISD::SRL_PARTS , MVT::i32 , Custom); @@ -1270,30 +1268,6 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG DAG) { switch (Op.getOpcode()) { default: assert(0 Should not custom lower this!); - case ISD::ADD_PARTS: - case ISD::SUB_PARTS: { -assert(Op.getNumOperands() == 4 Op.getValueType() == MVT::i32 - Not an i64 add/sub!); -bool isAdd = Op.getOpcode() == ISD::ADD_PARTS; -std::vectorMVT::ValueType Tys; -Tys.push_back(MVT::i32); -Tys.push_back(MVT::Flag); -std::vectorSDOperand Ops; -Ops.push_back(Op.getOperand(0)); -Ops.push_back(Op.getOperand(2)); -SDOperand Lo = DAG.getNode(isAdd ? X86ISD::ADD_FLAG : X86ISD::SUB_FLAG, - Tys, Ops); -SDOperand Hi = DAG.getNode(isAdd ? X86ISD::ADC : X86ISD::SBB, MVT::i32, - Op.getOperand(1), Op.getOperand(3), - Lo.getValue(1)); -Tys.clear(); -Tys.push_back(MVT::i32); -Tys.push_back(MVT::i32); -Ops.clear(); -Ops.push_back(Lo); -Ops.push_back(Hi); -return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops); - } case ISD::SHL_PARTS: case ISD::SRA_PARTS: case ISD::SRL_PARTS: { @@ -1910,10 +1884,6 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const { switch (Opcode) { default: return NULL; - case X86ISD::ADD_FLAG: return X86ISD::ADD_FLAG; - case X86ISD::SUB_FLAG: return X86ISD::SUB_FLAG; - case X86ISD::ADC:return X86ISD::ADC; - case X86ISD::SBB:return X86ISD::SBB; case X86ISD::SHLD: return X86ISD::SHLD; case X86ISD::SHRD: return X86ISD::SHRD; case X86ISD::FAND: return X86ISD::FAND; Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.26 llvm/lib/Target/X86/X86ISelLowering.h:1.27 --- llvm/lib/Target/X86/X86ISelLowering.h:1.26 Thu Feb 16 15:11:51 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Thu Feb 16 23:43:56 2006 @@ -26,16 +26,6 @@ // Start the numbering where the builtin ops leave off. FIRST_NUMBER = ISD::BUILTIN_OP_END+X86::INSTRUCTION_LIST_END, - /// ADD_FLAG, SUB_FLAG - Same as ISD::ADD and ISD::SUB except it also - /// produces a flag result. - ADD_FLAG, - SUB_FLAG, - - /// ADC, SBB - Add with carry and subtraction with borrow. These - /// correspond to X86::ADCxx and X86::SBBxx instructions. - ADC, - SBB, - /// SHLD, SHRD - Double shift instructions. These correspond to /// X86::SHLDxx and X86::SHRDxx instructions. SHLD, Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.236 llvm/lib/Target/X86/X86InstrInfo.td:1.237 --- llvm/lib/Target/X86/X86InstrInfo.td:1.236 Thu Feb 16 17:59:30 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Thu Feb 16 23:43:56 2006 @@ -56,15 +56,6 @@ def SDTX86RdTsc : SDTypeProfile0, 0, []; -def X86addflag : SDNodeX86ISD::ADD_FLAG, SDTIntBinOp , -[SDNPCommutative, SDNPAssociative, SDNPOutFlag]; -def X86subflag : SDNodeX86ISD::SUB_FLAG, SDTIntBinOp, -[SDNPOutFlag]; -def X86adc : SDNodeX86ISD::ADC , SDTIntBinOp , -[SDNPCommutative, SDNPAssociative, SDNPInFlag]; -def X86sbb : SDNodeX86ISD::SBB , SDTIntBinOp, -[SDNPInFlag]; - def X86shld: SDNodeX86ISD::SHLD, SDTIntShiftDOp; def X86shrd: SDNodeX86ISD::SHRD, SDTIntShiftDOp; @@ -1873,28 +1864,28 @@ let isCommutable =
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.66 - 1.67 X86ISelLowering.h updated: 1.20 - 1.21 X86InstrInfo.td updated: 1.222 - 1.223 --- Log message: Always use FP stack instructions to perform i64 to f64 as well as f64 to i64 conversions. SSE does not have instructions to handle these tasks. --- Diffs of the changes: (+64 -17) X86ISelLowering.cpp | 72 +--- X86ISelLowering.h |2 - X86InstrInfo.td |7 +++-- 3 files changed, 64 insertions(+), 17 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.66 llvm/lib/Target/X86/X86ISelLowering.cpp:1.67 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.66Sun Jan 29 22:09:04 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Mon Jan 30 02:02:57 2006 @@ -68,11 +68,12 @@ setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote); setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote); + // We can handle SINT_TO_FP and FP_TO_SINT from/to i64 even though i64 + // isn't legal. + setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom); + setOperationAction(ISD::FP_TO_SINT , MVT::i64 , Custom); + if (!X86ScalarSSE) { -// We can handle SINT_TO_FP and FP_TO_SINT from/TO i64 even though i64 -// isn't legal. -setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom); -setOperationAction(ISD::FP_TO_SINT , MVT::i64 , Custom); setOperationAction(ISD::FP_TO_SINT , MVT::i32 , Custom); setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Custom); } @@ -526,12 +527,11 @@ Chain = RetVal.getValue(1); InFlag = RetVal.getValue(2); if (X86ScalarSSE) { - // FIXME:Currently the FST is flagged to the FP_GET_RESULT. This - // shouldn't be necessary except for RFP cannot be live across + // FIXME: Currently the FST is flagged to the FP_GET_RESULT. This + // shouldn't be necessary except that RFP cannot be live across // multiple blocks. When stackifier is fixed, they can be uncoupled. - unsigned Size = MVT::getSizeInBits(MVT::f64)/8; MachineFunction MF = DAG.getMachineFunction(); - int SSFI = MF.getFrameInfo()-CreateStackObject(Size, Size); + int SSFI = MF.getFrameInfo()-CreateStackObject(8, 8); SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); Tys.clear(); Tys.push_back(MVT::Other); @@ -1027,12 +1027,11 @@ Chain = RetVal.getValue(1); InFlag = RetVal.getValue(2); if (X86ScalarSSE) { - // FIXME:Currently the FST is flagged to the FP_GET_RESULT. This - // shouldn't be necessary except for RFP cannot be live across + // FIXME: Currently the FST is flagged to the FP_GET_RESULT. This + // shouldn't be necessary except that RFP cannot be live across // multiple blocks. When stackifier is fixed, they can be uncoupled. - unsigned Size = MVT::getSizeInBits(MVT::f64)/8; MachineFunction MF = DAG.getMachineFunction(); - int SSFI = MF.getFrameInfo()-CreateStackObject(Size, Size); + int SSFI = MF.getFrameInfo()-CreateStackObject(8, 8); SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); Tys.clear(); Tys.push_back(MVT::Other); @@ -1461,12 +1460,38 @@ // Build the FILD std::vectorMVT::ValueType Tys; Tys.push_back(MVT::f64); +Tys.push_back(MVT::Other); Tys.push_back(MVT::Flag); std::vectorSDOperand Ops; Ops.push_back(Chain); Ops.push_back(StackSlot); Ops.push_back(DAG.getValueType(SrcVT)); Result = DAG.getNode(X86ISD::FILD, Tys, Ops); + +if (X86ScalarSSE) { + assert(Op.getValueType() == MVT::f64 Invalid SINT_TO_FP to lower!); + Chain = Result.getValue(1); + SDOperand InFlag = Result.getValue(2); + + // FIXME: Currently the FST is flagged to the FILD. This + // shouldn't be necessary except that RFP cannot be live across + // multiple blocks. When stackifier is fixed, they can be uncoupled. + MachineFunction MF = DAG.getMachineFunction(); + int SSFI = MF.getFrameInfo()-CreateStackObject(8, 8); + SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); + std::vectorMVT::ValueType Tys; + Tys.push_back(MVT::Other); + std::vectorSDOperand Ops; + Ops.push_back(Chain); + Ops.push_back(Result); + Ops.push_back(StackSlot); + Ops.push_back(DAG.getValueType(MVT::f64)); + Ops.push_back(InFlag); + Chain = DAG.getNode(X86ISD::FST, Tys, Ops); + Result = DAG.getLoad(Op.getValueType(), Chain, StackSlot, + DAG.getSrcValue(NULL)); +} + return Result; } case ISD::FP_TO_SINT: { @@ -1488,10 +1513,29 @@ case MVT::i64: Opc = X86ISD::FP_TO_INT64_IN_MEM; break; } +
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.64 - 1.65 X86ISelLowering.h updated: 1.18 - 1.19 --- Log message: adjust prototype --- Diffs of the changes: (+4 -2) X86ISelLowering.cpp |3 ++- X86ISelLowering.h |3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.64 llvm/lib/Target/X86/X86ISelLowering.cpp:1.65 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.64Sun Jan 29 00:44:22 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Sun Jan 29 21:49:07 2006 @@ -1932,7 +1932,8 @@ } bool X86TargetLowering::isMaskedValueZeroForTargetNode(const SDOperand Op, - uint64_t Mask) const { + uint64_t Mask, +MVIZFnPtr MVIZ) const { unsigned Opc = Op.getOpcode(); Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.18 llvm/lib/Target/X86/X86ISelLowering.h:1.19 --- llvm/lib/Target/X86/X86ISelLowering.h:1.18 Fri Jan 27 15:09:22 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Sun Jan 29 21:49:07 2006 @@ -208,7 +208,8 @@ /// be zero. Op is expected to be a target specific node. Used by DAG /// combiner. virtual bool isMaskedValueZeroForTargetNode(const SDOperand Op, -uint64_t Mask) const; +uint64_t Mask, +MVIZFnPtr MVIZ) const; SDOperand getReturnAddressFrameIndex(SelectionDAG DAG); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.65 - 1.66 X86ISelLowering.h updated: 1.19 - 1.20 --- Log message: Move MaskedValueIsZero from the DAGCombiner to the TargetLowering interface,making isMaskedValueZeroForTargetNode simpler, and useable from other partsof the compiler. --- Diffs of the changes: (+2 -4) X86ISelLowering.cpp |3 +-- X86ISelLowering.h |3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.65 llvm/lib/Target/X86/X86ISelLowering.cpp:1.66 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.65Sun Jan 29 21:49:07 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Sun Jan 29 22:09:04 2006 @@ -1932,8 +1932,7 @@ } bool X86TargetLowering::isMaskedValueZeroForTargetNode(const SDOperand Op, - uint64_t Mask, -MVIZFnPtr MVIZ) const { + uint64_t Mask) const { unsigned Opc = Op.getOpcode(); Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.19 llvm/lib/Target/X86/X86ISelLowering.h:1.20 --- llvm/lib/Target/X86/X86ISelLowering.h:1.19 Sun Jan 29 21:49:07 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Sun Jan 29 22:09:04 2006 @@ -208,8 +208,7 @@ /// be zero. Op is expected to be a target specific node. Used by DAG /// combiner. virtual bool isMaskedValueZeroForTargetNode(const SDOperand Op, -uint64_t Mask, -MVIZFnPtr MVIZ) const; +uint64_t Mask) const; SDOperand getReturnAddressFrameIndex(SelectionDAG DAG); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.59 - 1.60 X86ISelLowering.h updated: 1.17 - 1.18 --- Log message: Remove TLI.LowerReturnTo, and just let targets custom lower ISD::RET for the same functionality. This addresses another piece of bug 680: http://llvm.cs.uiuc.edu/PR680 . Next, on to fixing Alpha VAARG, which I broke last time. --- Diffs of the changes: (+60 -71) X86ISelLowering.cpp | 128 X86ISelLowering.h |3 - 2 files changed, 60 insertions(+), 71 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.59 llvm/lib/Target/X86/X86ISelLowering.cpp:1.60 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.59Fri Jan 27 02:10:46 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Jan 27 15:09:22 2006 @@ -269,69 +269,6 @@ return LowerallTo(Chain, RetTy, isVarArg, isTailCall, Callee, Args, DAG); } -SDOperand X86TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op, - SelectionDAG DAG) { - if (!X86DAGIsel) -return DAG.getNode(ISD::RET, MVT::Other, Chain, Op); - - SDOperand Copy; - MVT::ValueType OpVT = Op.getValueType(); - switch (OpVT) { -default: assert(0 Unknown type to return!); -case MVT::i32: - Copy = DAG.getCopyToReg(Chain, X86::EAX, Op, SDOperand()); - break; -case MVT::i64: { - SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, - DAG.getConstant(1, MVT::i32)); - SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, - DAG.getConstant(0, MVT::i32)); - Copy = DAG.getCopyToReg(Chain, X86::EDX, Hi, SDOperand()); - Copy = DAG.getCopyToReg(Copy, X86::EAX, Lo, Copy.getValue(1)); - break; -} -case MVT::f32: -case MVT::f64: - if (!X86ScalarSSE) { -std::vectorMVT::ValueType Tys; -Tys.push_back(MVT::Other); -Tys.push_back(MVT::Flag); -std::vectorSDOperand Ops; -Ops.push_back(Chain); -Ops.push_back(Op); -Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops); - } else { -// Spill the value to memory and reload it into top of stack. -unsigned Size = MVT::getSizeInBits(OpVT)/8; -MachineFunction MF = DAG.getMachineFunction(); -int SSFI = MF.getFrameInfo()-CreateStackObject(Size, Size); -SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); -Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, Op, -StackSlot, DAG.getSrcValue(NULL)); -std::vectorMVT::ValueType Tys; -Tys.push_back(MVT::f64); -Tys.push_back(MVT::Other); -std::vectorSDOperand Ops; -Ops.push_back(Chain); -Ops.push_back(StackSlot); -Ops.push_back(DAG.getValueType(OpVT)); -Copy = DAG.getNode(X86ISD::FLD, Tys, Ops); -Tys.clear(); -Tys.push_back(MVT::Other); -Tys.push_back(MVT::Flag); -Ops.clear(); -Ops.push_back(Copy.getValue(1)); -Ops.push_back(Copy); -Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops); - } - break; - } - - return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, - Copy, DAG.getConstant(getBytesToPopOnReturn(), MVT::i16), - Copy.getValue(1)); -} - //===--===// //C Calling Convention implementation //===--===// @@ -1766,11 +1703,6 @@ return DAG.getNode(X86ISD::BRCOND, Op.getValueType(), Op.getOperand(0), Op.getOperand(2), CC, Cond); } - case ISD::RET: { -// Can only be return void. -return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, Op.getOperand(0), - DAG.getConstant(getBytesToPopOnReturn(), MVT::i16)); - } case ISD::MEMSET: { SDOperand InFlag; SDOperand Chain = Op.getOperand(0); @@ -1897,6 +1829,66 @@ return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), FR, Op.getOperand(1), Op.getOperand(2)); } + case ISD::RET: { +SDOperand Copy; + +switch(Op.getNumOperands()) { +default: + assert(0 Do not know how to return this many arguments!); + abort(); +case 1: + return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, Op.getOperand(0), + DAG.getConstant(getBytesToPopOnReturn(), MVT::i16)); +case 2: { + MVT::ValueType ArgVT = Op.getOperand(1).getValueType(); + if (MVT::isInteger(ArgVT)) +Copy = DAG.getCopyToReg(Op.getOperand(0), X86::EAX, Op.getOperand(1), +SDOperand()); + else if (!X86ScalarSSE) { +std::vectorMVT::ValueType Tys; +Tys.push_back(MVT::Other); +
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.56 - 1.57 X86ISelLowering.h updated: 1.15 - 1.16 --- Log message: First part of bug 680: http://llvm.cs.uiuc.edu/PR680 : Remove TLI.LowerVA* and replace it with SDNodes that are lowered the same way as everything else. --- Diffs of the changes: (+15 -41) X86ISelLowering.cpp | 50 +++--- X86ISelLowering.h |6 -- 2 files changed, 15 insertions(+), 41 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.56 llvm/lib/Target/X86/X86ISelLowering.cpp:1.57 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.56Wed Jan 25 03:15:17 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Jan 25 12:21:52 2006 @@ -169,7 +169,13 @@ setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand); - // Expand to the default code. + // VASTART needs to be custom lowered to use the VarArgsFrameIndex + setOperationAction(ISD::VASTART , MVT::Other, Custom); + + // Use the default implementation. + setOperationAction(ISD::VAARG , MVT::Other, Expand); + setOperationAction(ISD::VACOPY, MVT::Other, Expand); + setOperationAction(ISD::VAEND , MVT::Other, Expand); setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand); @@ -641,40 +647,6 @@ } } -SDOperand -X86TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP, -Value *VAListV, SelectionDAG DAG) { - // vastart just stores the address of the VarArgsFrameIndex slot. - SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); - return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP, - DAG.getSrcValue(VAListV)); -} - - -std::pairSDOperand,SDOperand -X86TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, - Value *VAListV, const Type *ArgTy, - SelectionDAG DAG) { - MVT::ValueType ArgVT = getValueType(ArgTy); - SDOperand Val = DAG.getLoad(MVT::i32, Chain, - VAListP, DAG.getSrcValue(VAListV)); - SDOperand Result = DAG.getLoad(ArgVT, Chain, Val, - DAG.getSrcValue(NULL)); - unsigned Amt; - if (ArgVT == MVT::i32) -Amt = 4; - else { -assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) - Other types should have been promoted for varargs!); -Amt = 8; - } - Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val, -DAG.getConstant(Amt, Val.getValueType())); - Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, - Val, VAListP, DAG.getSrcValue(VAListV)); - return std::make_pair(Result, Chain); -} - //===--===// //Fast Calling Convention implementation //===--===// @@ -1898,6 +1870,14 @@ DAG.getSrcValue(NULL)); return Result; } + case ISD::VASTART: { +// vastart just stores the address of the VarArgsFrameIndex slot into the +// memory location argument. +// FIXME: Replace MVT::i32 with PointerTy +SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32); +return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), FR, + Op.getOperand(1), Op.getOperand(2)); + } } } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.15 llvm/lib/Target/X86/X86ISelLowering.h:1.16 --- llvm/lib/Target/X86/X86ISelLowering.h:1.15 Thu Jan 12 16:54:21 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Wed Jan 25 12:21:52 2006 @@ -195,12 +195,6 @@ virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op, SelectionDAG DAG); -virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, - Value *VAListV, SelectionDAG DAG); -virtual std::pairSDOperand,SDOperand -LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG DAG); - virtual std::pairSDOperand, SDOperand LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG DAG); ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.26 - 1.27 X86ISelLowering.h updated: 1.12 - 1.13 X86InstrInfo.td updated: 1.194 - 1.195 --- Log message: SSE cmov support. --- Diffs of the changes: (+121 -17) X86ISelLowering.cpp | 109 X86ISelLowering.h |3 + X86InstrInfo.td | 26 +++- 3 files changed, 121 insertions(+), 17 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.26 llvm/lib/Target/X86/X86ISelLowering.cpp:1.27 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.26Tue Jan 10 14:26:56 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Jan 10 18:33:36 2006 @@ -17,8 +17,9 @@ #include X86TargetMachine.h #include llvm/CallingConv.h #include llvm/Function.h -#include llvm/CodeGen/MachineFunction.h #include llvm/CodeGen/MachineFrameInfo.h +#include llvm/CodeGen/MachineFunction.h +#include llvm/CodeGen/MachineInstrBuilder.h #include llvm/CodeGen/SelectionDAG.h #include llvm/CodeGen/SSARegMap.h #include llvm/Target/TargetOptions.h @@ -1140,14 +1141,34 @@ return std::make_pair(Result, Chain); } -//===--===// -// X86 Custom Lowering Hooks -//===--===// +/// getCondBrOpcodeForX86CC - Returns the X86 conditional branch opcode +/// which corresponds to the condition code. +static unsigned getCondBrOpcodeForX86CC(unsigned X86CC) { + switch (X86CC) { + default: assert(0 Unknown X86 conditional code!); + case X86ISD::COND_A: return X86::JA; + case X86ISD::COND_AE: return X86::JAE; + case X86ISD::COND_B: return X86::JB; + case X86ISD::COND_BE: return X86::JBE; + case X86ISD::COND_E: return X86::JE; + case X86ISD::COND_G: return X86::JG; + case X86ISD::COND_GE: return X86::JGE; + case X86ISD::COND_L: return X86::JL; + case X86ISD::COND_LE: return X86::JLE; + case X86ISD::COND_NE: return X86::JNE; + case X86ISD::COND_NO: return X86::JNO; + case X86ISD::COND_NP: return X86::JNP; + case X86ISD::COND_NS: return X86::JNS; + case X86ISD::COND_O: return X86::JO; + case X86ISD::COND_P: return X86::JP; + case X86ISD::COND_S: return X86::JS; + } +} -/// SetCCToX86CondCode - do a one to one translation of a ISD::CondCode to -/// X86 specific CondCode. It returns a X86ISD::COND_INVALID if it cannot +/// getX86CC - do a one to one translation of a ISD::CondCode to the X86 +/// specific condition code. It returns a X86ISD::COND_INVALID if it cannot /// do a direct translation. -static unsigned CCToX86CondCode(SDOperand CC, bool isFP) { +static unsigned getX86CC(SDOperand CC, bool isFP) { ISD::CondCode SetCCOpcode = castCondCodeSDNode(CC)-get(); unsigned X86CC = X86ISD::COND_INVALID; if (!isFP) { @@ -1192,11 +1213,10 @@ return X86CC; } -/// SupportedByFPCMOV - is there a floating point cmov for the specific -/// X86 condition code. -/// Current x86 isa includes the following FP cmov instructions: +/// hasFPCMov - is there a floating point cmov for the specific X86 condition +/// code. Current x86 isa includes the following FP cmov instructions: /// fcmovb, fcomvbe, fcomve, fcmovu, fcmovae, fcmova, fcmovne, fcmovnu. -static bool SupportedByFPCMOV(unsigned X86CC) { +static bool hasFPCMov(unsigned X86CC) { switch (X86CC) { default: return false; @@ -1212,6 +1232,64 @@ } } +MachineBasicBlock * +X86TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, + MachineBasicBlock *BB) { + assert((MI-getOpcode() == X86::CMOV_FR32 || + MI-getOpcode() == X86::CMOV_FR64) + Unexpected instr type to insert); + + // To insert a SELECT_CC instruction, we actually have to insert the diamond + // control-flow pattern. The incoming instruction knows the destination vreg + // to set, the condition code register to branch on, the true/false values to + // select between, and a branch opcode to use. + const BasicBlock *LLVM_BB = BB-getBasicBlock(); + ilistMachineBasicBlock::iterator It = BB; + ++It; + + // thisMBB: + // ... + // TrueVal = ... + // cmpTY ccX, r1, r2 + // bCC copy1MBB + // fallthrough -- copy0MBB + MachineBasicBlock *thisMBB = BB; + MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB); + MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB); + unsigned Opc = getCondBrOpcodeForX86CC(MI-getOperand(3).getImmedValue()); + BuildMI(BB, Opc, 1).addMBB(sinkMBB); + MachineFunction *F = BB-getParent(); + F-getBasicBlockList().insert(It, copy0MBB); + F-getBasicBlockList().insert(It, sinkMBB); + // Update machine-CFG edges + BB-addSuccessor(copy0MBB); + BB-addSuccessor(sinkMBB); + + // copy0MBB: + // %FalseValue = ... + // # fallthrough to sinkMBB + BB = copy0MBB; + + // Update machine-CFG edges +
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td X86RegisterInfo.cpp
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.22 - 1.23 X86ISelLowering.h updated: 1.11 - 1.12 X86InstrInfo.td updated: 1.190 - 1.191 X86RegisterInfo.cpp updated: 1.116 - 1.117 --- Log message: Support for ADD_PARTS, SUB_PARTS, SHL_PARTS, SHR_PARTS, and SRA_PARTS. --- Diffs of the changes: (+313 -103) X86ISelLowering.cpp | 126 ++-- X86ISelLowering.h | 21 +++- X86InstrInfo.td | 267 ++-- X86RegisterInfo.cpp |2 4 files changed, 313 insertions(+), 103 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.22 llvm/lib/Target/X86/X86ISelLowering.cpp:1.23 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.22Thu Jan 5 18:43:03 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Mon Jan 9 12:33:28 2006 @@ -133,6 +133,12 @@ setOperationAction(ISD::RET, MVT::Other, Custom); // Darwin ABI issue. setOperationAction(ISD::GlobalAddress , MVT::i32 , Custom); +// 64-bit addm sub, shl, sra, srl (iff 32-bit x86) +setOperationAction(ISD::ADD_PARTS , MVT::i32 , Custom); +setOperationAction(ISD::SUB_PARTS , MVT::i32 , Custom); +setOperationAction(ISD::SHL_PARTS , MVT::i32 , Custom); +setOperationAction(ISD::SRA_PARTS , MVT::i32 , Custom); +setOperationAction(ISD::SRL_PARTS , MVT::i32 , Custom); } // We don't have line number support yet. @@ -243,13 +249,13 @@ case MVT::f32: case MVT::f64: if (!X86ScalarSSE) { +if (OpVT == MVT::f32) + Op = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Op); std::vectorMVT::ValueType Tys; Tys.push_back(MVT::Other); Tys.push_back(MVT::Flag); std::vectorSDOperand Ops; Ops.push_back(Chain); -if (OpVT == MVT::f32) - Op = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Op); Ops.push_back(Op); Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops); } else { @@ -476,7 +482,6 @@ std::vectorMVT::ValueType NodeTys; NodeTys.push_back(MVT::Other); // Returns a chain NodeTys.push_back(MVT::Flag);// Returns a flag for retval copy to use. - std::vectorSDOperand Ops; Ops.push_back(Chain); Ops.push_back(Callee); @@ -991,7 +996,6 @@ std::vectorMVT::ValueType NodeTys; NodeTys.push_back(MVT::Other); // Returns a chain NodeTys.push_back(MVT::Flag);// Returns a flag for retval copy to use. - std::vectorSDOperand Ops; Ops.push_back(Chain); Ops.push_back(Callee); @@ -1193,6 +1197,99 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG DAG) { switch (Op.getOpcode()) { default: assert(0 Should not custom lower this!); + case ISD::ADD_PARTS: + case ISD::SUB_PARTS: { +assert(Op.getNumOperands() == 4 Op.getValueType() == MVT::i32 + Not an i64 add/sub!); +bool isAdd = Op.getOpcode() == ISD::ADD_PARTS; +std::vectorMVT::ValueType Tys; +Tys.push_back(MVT::i32); +Tys.push_back(MVT::Flag); +std::vectorSDOperand Ops; +Ops.push_back(Op.getOperand(0)); +Ops.push_back(Op.getOperand(2)); +SDOperand Lo = DAG.getNode(isAdd ? X86ISD::ADD_FLAG : X86ISD::SUB_FLAG, + Tys, Ops); +SDOperand Hi = DAG.getNode(isAdd ? X86ISD::ADC : X86ISD::SBB, MVT::i32, + Op.getOperand(1), Op.getOperand(3), + Lo.getValue(1)); +Tys.clear(); +Tys.push_back(MVT::i32); +Tys.push_back(MVT::i32); +Ops.clear(); +Ops.push_back(Lo); +Ops.push_back(Hi); +return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops); + } + case ISD::SHL_PARTS: + case ISD::SRA_PARTS: + case ISD::SRL_PARTS: { +assert(Op.getNumOperands() == 3 Op.getValueType() == MVT::i32 + Not an i64 shift!); +bool isSRA = Op.getOpcode() == ISD::SRA_PARTS; +SDOperand ShOpLo = Op.getOperand(0); +SDOperand ShOpHi = Op.getOperand(1); +SDOperand ShAmt = Op.getOperand(2); +SDOperand Tmp1 = isSRA ? DAG.getNode(ISD::SRA, MVT::i32, ShOpHi, + DAG.getConstant(32, MVT::i32)) + : DAG.getConstant(0, MVT::i32); + +SDOperand Tmp2, Tmp3; +if (Op.getOpcode() == ISD::SHL_PARTS) { + Tmp2 = DAG.getNode(X86ISD::SHLD, MVT::i32, ShOpHi, ShOpLo, ShAmt); + Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, ShOpLo, ShAmt); +} else { + Tmp2 = DAG.getNode(X86ISD::SHRD, MVT::i32, ShOpLo, ShOpHi, ShAmt); + Tmp3 = DAG.getNode(isSRA ? ISD::SRA : ISD::SHL, MVT::i32, ShOpHi, ShAmt); +} + +SDOperand InFlag = DAG.getNode(X86ISD::TEST, MVT::Flag, + ShAmt, DAG.getConstant(32, MVT::i8)); + +SDOperand Hi, Lo; +SDOperand CC = DAG.getConstant(X86ISD::COND_E, MVT::i8); + +std::vectorMVT::ValueType Tys; +Tys.push_back(MVT::i32); +
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.12 - 1.13 X86ISelLowering.h updated: 1.6 - 1.7 X86InstrInfo.td updated: 1.179 - 1.180 --- Log message: * Added support for X86 RET with an additional operand to specify number of bytes to pop off stack. * Added support for X86 SETCC. --- Diffs of the changes: (+122 -64) X86ISelLowering.cpp | 27 - X86ISelLowering.h | 17 +- X86InstrInfo.td | 142 +++- 3 files changed, 122 insertions(+), 64 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.12 llvm/lib/Target/X86/X86ISelLowering.cpp:1.13 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.12Tue Dec 20 20:39:21 2005 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Dec 21 14:21:51 2005 @@ -119,6 +119,9 @@ if (X86DAGIsel) { setOperationAction(ISD::SELECT , MVT::i16 , Custom); setOperationAction(ISD::SELECT , MVT::i32 , Custom); +setOperationAction(ISD::SETCC , MVT::i8 , Custom); +setOperationAction(ISD::SETCC , MVT::i16 , Custom); +setOperationAction(ISD::SETCC , MVT::i32 , Custom); } // We don't have line number support yet. @@ -256,7 +259,10 @@ } break; } - return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1)); + + return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, + Copy, DAG.getConstant(getBytesToPopOnReturn(), MVT::i16), + Copy.getValue(1)); } //===--===// @@ -999,10 +1005,20 @@ Tys.push_back(MVT::Other); return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops); } + case ISD::SETCC: { +assert(Op.getValueType() == MVT::i8 SetCC type must be 8-bit integer); +SDOperand CC = Op.getOperand(2); +SDOperand Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, + Op.getOperand(0), Op.getOperand(1)); +return DAG.getNode(X86ISD::SETCC, MVT::i8, CC, Cond); + } case ISD::SELECT: { SDOperand Cond = Op.getOperand(0); SDOperand CC; -if (Cond.getOpcode() == ISD::SETCC) { +if (Cond.getOpcode() == X86ISD::SETCC) { + CC = Cond.getOperand(0); + Cond = Cond.getOperand(1); +} else if (Cond.getOpcode() == ISD::SETCC) { CC = Cond.getOperand(2); Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, Cond.getOperand(0), Cond.getOperand(1)); @@ -1014,12 +1030,14 @@ Op.getOperand(1), Op.getOperand(2), CC, Cond); } case ISD::BRCOND: { -SDOperand Chain = Op.getOperand(0); SDOperand Cond = Op.getOperand(1); SDOperand Dest = Op.getOperand(2); SDOperand CC; // TODO: handle Cond == OR / AND / XOR -if (Cond.getOpcode() == ISD::SETCC) { +if (Cond.getOpcode() == X86ISD::SETCC) { + CC = Cond.getOperand(0); + Cond = Cond.getOperand(1); +} else if (Cond.getOpcode() == ISD::SETCC) { CC = Cond.getOperand(2); Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, Cond.getOperand(0), Cond.getOperand(1)); @@ -1061,6 +1079,7 @@ case X86ISD::RDTSC_DAG: return X86ISD::RDTSC_DAG; case X86ISD::CMP:return X86ISD::CMP; case X86ISD::TEST: return X86ISD::TEST; + case X86ISD::SETCC: return X86ISD::SETCC; case X86ISD::CMOV: return X86ISD::CMOV; case X86ISD::BRCOND: return X86ISD::BRCOND; case X86ISD::RET_FLAG: return X86ISD::RET_FLAG; Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.6 llvm/lib/Target/X86/X86ISelLowering.h:1.7 --- llvm/lib/Target/X86/X86ISelLowering.h:1.6 Tue Dec 20 20:39:21 2005 +++ llvm/lib/Target/X86/X86ISelLowering.h Wed Dec 21 14:21:51 2005 @@ -81,13 +81,24 @@ /// X86 compare and logical compare instructions. CMP, TEST, - /// X86 conditional moves. + /// X86 SetCC. Operand 1 is condition code, and operand 2 is the flag + /// operand produced by a CMP instruction. + SETCC, + + /// X86 conditional moves. Operand 1 and operand 2 are the two values + /// to select from (operand 1 is a R/W operand). Operand 3 is the condition + /// code, and operand 4 is the flag operand produced by a CMP or TEST + /// instruction. CMOV, - /// X86 conditional branches. + /// X86 conditional branches. Operand 1 is the chain operand, operand 2 + /// is the block to branch if condition is true, operand 3 is the + /// condition code, and operand 4 is the flag operand produced by a CMP + /// or TEST instruction. BRCOND, - // Return with a flag operand. + /// Return with a flag operand. Operand 1 is the number of bytes of stack + /// to pop, operand 2 is the chain and operand 3 is a flag
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.9 - 1.10 X86ISelLowering.h updated: 1.3 - 1.4 X86InstrInfo.td updated: 1.172 - 1.173 --- Log message: X86 conditional branch support. --- Diffs of the changes: (+53 -14) X86ISelLowering.cpp | 21 - X86ISelLowering.h |3 +++ X86InstrInfo.td | 43 ++- 3 files changed, 53 insertions(+), 14 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.9 llvm/lib/Target/X86/X86ISelLowering.cpp:1.10 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.9 Sat Dec 17 01:18:44 2005 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Mon Dec 19 17:12:38 2005 @@ -31,7 +31,6 @@ X86TargetLowering::X86TargetLowering(TargetMachine TM) : TargetLowering(TM) { - // Set up the TargetLowering object. // X86 is weird, it always uses i8 for shift amounts and setcc results. @@ -81,6 +80,9 @@ setOperationAction(ISD::FP_TO_SINT , MVT::i8 , Promote); setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Promote); + if (X86DAGIsel) { +setOperationAction(ISD::BRCOND , MVT::Other, Custom); + } setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand); setOperationAction(ISD::BRTWOWAY_CC , MVT::Other, Expand); setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); @@ -949,5 +951,22 @@ return DAG.getNode(X86ISD::CMOV, Op.getValueType(), Op.getOperand(1), Op.getOperand(2), CC, Cond); } + case ISD::BRCOND: { +SDOperand Chain = Op.getOperand(0); +SDOperand Cond = Op.getOperand(1); +SDOperand Dest = Op.getOperand(2); +SDOperand CC; +// TODO: handle Cond == OR / AND / XOR +if (Cond.getOpcode() == ISD::SETCC) { + CC = Cond.getOperand(2); + Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, + Cond.getOperand(0), Cond.getOperand(1)); +} else { + CC = DAG.getCondCode(ISD::SETNE); + Cond = DAG.getNode(X86ISD::TEST, MVT::Flag, Cond, Cond); +} +return DAG.getNode(X86ISD::BRCOND, Op.getValueType(), + Op.getOperand(0), Op.getOperand(2), CC, Cond); + } } } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.3 llvm/lib/Target/X86/X86ISelLowering.h:1.4 --- llvm/lib/Target/X86/X86ISelLowering.h:1.3 Fri Dec 16 19:21:05 2005 +++ llvm/lib/Target/X86/X86ISelLowering.h Mon Dec 19 17:12:38 2005 @@ -72,6 +72,9 @@ /// X86 conditional moves. CMOV, + + /// X86 conditional branches. + BRCOND, }; } Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.172 llvm/lib/Target/X86/X86InstrInfo.td:1.173 --- llvm/lib/Target/X86/X86InstrInfo.td:1.172 Sat Dec 17 13:47:05 2005 +++ llvm/lib/Target/X86/X86InstrInfo.td Mon Dec 19 17:12:38 2005 @@ -24,10 +24,15 @@ [SDTCisSameAs0, 1, SDTCisSameAs1, 2, SDTCisVT3, OtherVT, SDTCisVT4, FlagVT]; -def X86cmp : SDNodeX86ISD::CMP , SDTX86CmpTest, []; -def X86test : SDNodeX86ISD::TEST, SDTX86CmpTest, []; +def SDTX86BrCond : SDTypeProfile0, 3, + [SDTCisVT0, OtherVT, + SDTCisVT1, OtherVT, SDTCisVT2, FlagVT]; -def X86cmov : SDNodeX86ISD::CMOV, SDTX86Cmov,[]; +def X86cmp: SDNodeX86ISD::CMP , SDTX86CmpTest, []; +def X86test : SDNodeX86ISD::TEST, SDTX86CmpTest, []; + +def X86cmov : SDNodeX86ISD::CMOV, SDTX86Cmov,[]; +def X86Brcond : SDNodeX86ISD::BRCOND, SDTX86BrCond, [SDNPHasChain]; //===--===// // X86 Operand Definitions. @@ -268,21 +273,33 @@ let isBarrier = 1 in def JMP : IBr0xE9, (ops brtarget:$dst), jmp $dst, [(br bb:$dst)]; + +def JE : IBr0x84, (ops brtarget:$dst), je $dst, + [(X86Brcond bb:$dst, SETEQ, STATUS)], Imp[STATUS],[], TB; +def JNE : IBr0x85, (ops brtarget:$dst), jne $dst, + [(X86Brcond bb:$dst, SETNE, STATUS)], Imp[STATUS],[], TB; +def JL : IBr0x8C, (ops brtarget:$dst), jl $dst, + [(X86Brcond bb:$dst, SETLT, STATUS)], Imp[STATUS],[], TB; +def JLE : IBr0x8E, (ops brtarget:$dst), jle $dst, + [(X86Brcond bb:$dst, SETLE, STATUS)], Imp[STATUS],[], TB; +def JG : IBr0x8F, (ops brtarget:$dst), jg $dst, + [(X86Brcond bb:$dst, SETGT, STATUS)], Imp[STATUS],[], TB; +def JGE : IBr0x8D, (ops brtarget:$dst), jge $dst, + [(X86Brcond bb:$dst, SETGE, STATUS)], Imp[STATUS],[], TB; + def JB : IBr0x82, (ops brtarget:$dst), jb $dst, - [], TB; -def JAE : IBr0x83, (ops brtarget:$dst), jae $dst, [], TB; -def JE : IBr0x84, (ops brtarget:$dst), je $dst, [], TB; -def JNE : IBr0x85, (ops brtarget:$dst), jne $dst, [], TB; -def JBE : IBr0x86, (ops brtarget:$dst), jbe $dst, [], TB; -def JA : IBr0x87,
[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h
Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.10 - 1.11 X86ISelLowering.h updated: 1.4 - 1.5 --- Log message: Added a hook to print out names of target specific DAG nodes. --- Diffs of the changes: (+21 -0) X86ISelLowering.cpp | 17 + X86ISelLowering.h |4 2 files changed, 21 insertions(+) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.10 llvm/lib/Target/X86/X86ISelLowering.cpp:1.11 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.10Mon Dec 19 17:12:38 2005 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Dec 20 00:22:03 2005 @@ -970,3 +970,20 @@ } } } + +const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const { + switch (Opcode) { + default: return NULL; + case X86ISD::FILD64m:return X86ISD::FILD64m; + case X86ISD::FP_TO_INT16_IN_MEM: return X86ISD::FP_TO_INT16_IN_MEM; + case X86ISD::FP_TO_INT32_IN_MEM: return X86ISD::FP_TO_INT32_IN_MEM; + case X86ISD::FP_TO_INT64_IN_MEM: return X86ISD::FP_TO_INT64_IN_MEM; + case X86ISD::CALL: return X86ISD::CALL; + case X86ISD::TAILCALL: return X86ISD::TAILCALL; + case X86ISD::RDTSC_DAG: return X86ISD::RDTSC_DAG; + case X86ISD::CMP:return X86ISD::CMP; + case X86ISD::TEST: return X86ISD::TEST; + case X86ISD::CMOV: return X86ISD::CMOV; + case X86ISD::BRCOND: return X86ISD::BRCOND; + } +} Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.4 llvm/lib/Target/X86/X86ISelLowering.h:1.5 --- llvm/lib/Target/X86/X86ISelLowering.h:1.4 Mon Dec 19 17:12:38 2005 +++ llvm/lib/Target/X86/X86ISelLowering.h Tue Dec 20 00:22:03 2005 @@ -123,6 +123,10 @@ LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG DAG); +/// getTargetNodeName - This method returns the name of a target specific +/// DAG node. +virtual const char *getTargetNodeName(unsigned Opcode) const; + SDOperand getReturnAddressFrameIndex(SelectionDAG DAG); private: ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits