Index: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -368,6 +368,11 @@ return CurDAG->getTargetConstant(Imm, DL, MVT::i32); } + /// Return a target constant with the specified value, of type i64. + inline SDValue getI64Imm(uint64_t Imm, const SDLoc &DL) { + return CurDAG->getTargetConstant(Imm, DL, MVT::i64); + } + SDValue getExtractVEXTRACTImmediate(SDNode *N, unsigned VecWidth, const SDLoc &DL) { assert((VecWidth == 128 || VecWidth == 256) && "Unexpected vector width"); Index: llvm/trunk/lib/Target/X86/X86InstrCompiler.td =================================================================== --- llvm/trunk/lib/Target/X86/X86InstrCompiler.td +++ llvm/trunk/lib/Target/X86/X86InstrCompiler.td @@ -1471,6 +1471,37 @@ } // AddedComplexity = 1 +// Try to use BTS/BTR/BTC for single bit operations on the upper 32-bits. + +def BTRXForm : SDNodeXFormgetAPIntValue().countTrailingOnes(), SDLoc(N)); +}]>; + +def BTCBTSXForm : SDNodeXFormgetAPIntValue().countTrailingZeros(), SDLoc(N)); +}]>; + +def BTRMask64 : ImmLeaf(Imm) && !isInt<32>(Imm) && isPowerOf2_64(~Imm); +}]>; + +def BTCBTSMask64 : ImmLeaf(Imm) && isPowerOf2_64(Imm); +}]>; + +// For now only do this for optsize. +let AddedComplexity = 1, Predicates=[OptForSize] in { + def : Pat<(and GR64:$src1, BTRMask64:$mask), + (BTR64ri8 GR64:$src1, (BTRXForm imm:$mask))>; + def : Pat<(or GR64:$src1, BTCBTSMask64:$mask), + (BTS64ri8 GR64:$src1, (BTCBTSXForm imm:$mask))>; + def : Pat<(xor GR64:$src1, BTCBTSMask64:$mask), + (BTC64ri8 GR64:$src1, (BTCBTSXForm imm:$mask))>; +} + + // sext_inreg patterns def : Pat<(sext_inreg GR32:$src, i16), (MOVSX32rr16 (EXTRACT_SUBREG GR32:$src, sub_16bit))>; Index: llvm/trunk/lib/Target/X86/X86InstrInfo.td =================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.td +++ llvm/trunk/lib/Target/X86/X86InstrInfo.td @@ -2407,7 +2407,7 @@ }]>; def AndMask64 : ImmLeaf UINT32_MAX; + return isMask_64(Imm) && !isUInt<32>(Imm); }]>; // Use BEXTR for 64-bit 'and' with large immediate 'mask'.