diff options
author | Craig Topper <craig.topper@intel.com> | 2018-06-27 16:47:39 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@intel.com> | 2018-06-27 16:47:39 +0000 |
commit | 812fcb35e79ac3aab4c3ec8ae239ab54f820d94c (patch) | |
tree | 672953bf6893a5d42d106dd9b935a4ac7f4a6e6d /llvm/lib | |
parent | 069628b4dff2f358da7b94f76410060c2dacaad1 (diff) | |
download | bcm5719-llvm-812fcb35e79ac3aab4c3ec8ae239ab54f820d94c.tar.gz bcm5719-llvm-812fcb35e79ac3aab4c3ec8ae239ab54f820d94c.zip |
[X86] Use bts/btr/btc for single bit set/clear/complement of a variable bit position
If we are just modifying a single bit at a variable bit position we can use the BT* instructions to make the change instead of shifting a 1(or rotating a -1) and doing a binop. These instruction also ignore the upper bits of their index input so we can also remove an and if one is present on the index.
Fixes PR37938.
llvm-svn: 335754
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/X86/X86InstrCompiler.td | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td index 44fb44d55c1..5915e363aa6 100644 --- a/llvm/lib/Target/X86/X86InstrCompiler.td +++ b/llvm/lib/Target/X86/X86InstrCompiler.td @@ -1804,6 +1804,37 @@ let Predicates = [HasBMI2] in { } } +// Use BTR/BTS/BTC for clearing/setting/toggling a bit in a variable location. +multiclass one_bit_patterns<RegisterClass RC, ValueType VT, Instruction BTR, + Instruction BTS, Instruction BTC, + ImmLeaf ImmShift> { + def : Pat<(and RC:$src1, (rotl -2, GR8:$src2)), + (BTR RC:$src1, + (INSERT_SUBREG (VT (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; + def : Pat<(or RC:$src1, (shl 1, GR8:$src2)), + (BTS RC:$src1, + (INSERT_SUBREG (VT (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; + def : Pat<(xor RC:$src1, (shl 1, GR8:$src2)), + (BTC RC:$src1, + (INSERT_SUBREG (VT (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; + + // Similar to above, but removing unneeded masking of the shift amount. + def : Pat<(and RC:$src1, (rotl -2, (and GR8:$src2, ImmShift))), + (BTR RC:$src1, + (INSERT_SUBREG (VT (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; + def : Pat<(or RC:$src1, (shl 1, (and GR8:$src2, ImmShift))), + (BTS RC:$src1, + (INSERT_SUBREG (VT (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; + def : Pat<(xor RC:$src1, (shl 1, (and GR8:$src2, ImmShift))), + (BTC RC:$src1, + (INSERT_SUBREG (VT (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>; +} + +defm : one_bit_patterns<GR16, i16, BTR16rr, BTS16rr, BTC16rr, immShift16>; +defm : one_bit_patterns<GR32, i32, BTR32rr, BTS32rr, BTC32rr, immShift32>; +defm : one_bit_patterns<GR64, i64, BTR64rr, BTS64rr, BTC64rr, immShift64>; + + // (anyext (setcc_carry)) -> (setcc_carry) def : Pat<(i16 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), (SETB_C16r)>; |