diff options
author | Craig Topper <craig.topper@intel.com> | 2017-08-01 17:18:14 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@intel.com> | 2017-08-01 17:18:14 +0000 |
commit | 2a5bba73255f54338f0d6862bf5bf3a6de6cbd8d (patch) | |
tree | 55bc68122c7308b3f92994d7e230de58ff87d862 /llvm/lib/Target | |
parent | e925caf41659d059457561484267b3c286d2d58a (diff) | |
download | bcm5719-llvm-2a5bba73255f54338f0d6862bf5bf3a6de6cbd8d.tar.gz bcm5719-llvm-2a5bba73255f54338f0d6862bf5bf3a6de6cbd8d.zip |
[X86] Use BEXTR/BEXTRI for 64-bit 'and' with a large mask
Summary: The 64-bit 'and' with immediate instruction only supports a 32-bit immediate. So for larger constants we have to load the constant into a register first. If the immediate happens to be a mask we can use the BEXTRI instruction to perform the masking. We already do something similar using the BZHI instruction from the BMI2 instruction set.
Reviewers: RKSimon, spatel
Reviewed By: RKSimon
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D36129
llvm-svn: 309706
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.td | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index 75638f24bfe..1fc174750c7 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -844,6 +844,7 @@ def HasFMA : Predicate<"Subtarget->hasFMA()">; def HasFMA4 : Predicate<"Subtarget->hasFMA4()">; def HasXOP : Predicate<"Subtarget->hasXOP()">; def HasTBM : Predicate<"Subtarget->hasTBM()">; +def NoTBM : Predicate<"!Subtarget->hasTBM()">; def HasLWP : Predicate<"Subtarget->hasLWP()">; def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">; def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">; @@ -853,6 +854,7 @@ def HasFSGSBase : Predicate<"Subtarget->hasFSGSBase()">; def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">; def HasBMI : Predicate<"Subtarget->hasBMI()">; def HasBMI2 : Predicate<"Subtarget->hasBMI2()">; +def NoBMI2 : Predicate<"!Subtarget->hasBMI2()">; def HasVBMI : Predicate<"Subtarget->hasVBMI()">, AssemblerPredicate<"FeatureVBMI", "AVX-512 VBMI ISA">; def HasIFMA : Predicate<"Subtarget->hasIFMA()">, @@ -2352,20 +2354,40 @@ def CountTrailingOnes : SDNodeXForm<imm, [{ return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N)); }]>; -def BZHIMask : ImmLeaf<i64, [{ - return isMask_64(Imm) && (countTrailingOnes<uint64_t>(Imm) > 32); +def BEXTRMaskXForm : SDNodeXForm<imm, [{ + unsigned Length = countTrailingOnes(N->getZExtValue()); + return getI32Imm(Length << 8, SDLoc(N)); }]>; -let Predicates = [HasBMI2] in { - def : Pat<(and GR64:$src, BZHIMask:$mask), +def AndMask64 : ImmLeaf<i64, [{ + return isMask_64(Imm) && Imm > UINT32_MAX; +}]>; + +// Use BEXTR for 64-bit 'and' with large immediate 'mask'. +let Predicates = [HasBMI, NoBMI2, NoTBM] in { + def : Pat<(and GR64:$src, AndMask64:$mask), + (BEXTR64rr GR64:$src, + (SUBREG_TO_REG (i64 0), + (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>; + def : Pat<(and (loadi64 addr:$src), AndMask64:$mask), + (BEXTR64rm addr:$src, + (SUBREG_TO_REG (i64 0), + (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>; +} + +// Use BZHI for 64-bit 'and' with large immediate 'mask'. +let Predicates = [HasBMI2, NoTBM] in { + def : Pat<(and GR64:$src, AndMask64:$mask), (BZHI64rr GR64:$src, (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>; - def : Pat<(and (loadi64 addr:$src), BZHIMask:$mask), + def : Pat<(and (loadi64 addr:$src), AndMask64:$mask), (BZHI64rm addr:$src, (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>; +} +let Predicates = [HasBMI2] in { def : Pat<(and GR32:$src, (add (shl 1, GR8:$lz), -1)), (BZHI32rr GR32:$src, (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>; @@ -2511,6 +2533,15 @@ defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", MRM7r, MRM7m>; defm TZMSK : tbm_binary_intr<0x01, "tzmsk", MRM4r, MRM4m>; } // HasTBM, EFLAGS +// Use BEXTRI for 64-bit 'and' with large immediate 'mask'. +let Predicates = [HasTBM] in { + def : Pat<(and GR64:$src, AndMask64:$mask), + (BEXTRI64ri GR64:$src, (BEXTRMaskXForm imm:$mask))>; + + def : Pat<(and (loadi64 addr:$src), AndMask64:$mask), + (BEXTRI64mi addr:$src, (BEXTRMaskXForm imm:$mask))>; +} + //===----------------------------------------------------------------------===// // Lightweight Profiling Instructions |