[PATCH] D36129: [X86] Use BEXTRI for 64-bit 'and' with a large mask
Craig Topper via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 31 23:57:26 PDT 2017
craig.topper created this revision.
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.
https://reviews.llvm.org/D36129
Files:
lib/Target/X86/X86InstrInfo.td
test/CodeGen/X86/tbm_patterns.ll
Index: test/CodeGen/X86/tbm_patterns.ll
===================================================================
--- test/CodeGen/X86/tbm_patterns.ll
+++ test/CodeGen/X86/tbm_patterns.ll
@@ -253,3 +253,23 @@
ret i64 %t2
}
+define i64 @test_and_large_constant_mask(i64 %x) {
+; CHECK-LABEL: test_and_large_constant_mask:
+; CHECK: # BB#0: # %entry
+; CHECK-NEXT: bextr $15872, %rdi, %rax # imm = 0x3E00
+; CHECK-NEXT: retq
+entry:
+ %and = and i64 %x, 4611686018427387903
+ ret i64 %and
+}
+
+define i64 @test_and_large_constant_mask_load(i64* %x) {
+; CHECK-LABEL: test_and_large_constant_mask_load:
+; CHECK: # BB#0: # %entry
+; CHECK-NEXT: bextr $15872, (%rdi), %rax # imm = 0x3E00
+; CHECK-NEXT: retq
+entry:
+ %x1 = load i64, i64* %x
+ %and = and i64 %x1, 4611686018427387903
+ ret i64 %and
+}
Index: lib/Target/X86/X86InstrInfo.td
===================================================================
--- lib/Target/X86/X86InstrInfo.td
+++ lib/Target/X86/X86InstrInfo.td
@@ -2352,16 +2352,16 @@
return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N));
}]>;
-def BZHIMask : ImmLeaf<i64, [{
- return isMask_64(Imm) && (countTrailingOnes<uint64_t>(Imm) > 32);
+def AndMask64 : ImmLeaf<i64, [{
+ return isMask_64(Imm) && Imm > UINT32_MAX;
}]>;
let Predicates = [HasBMI2] in {
- def : Pat<(and GR64:$src, BZHIMask:$mask),
+ 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))>;
@@ -2511,6 +2511,20 @@
defm TZMSK : tbm_binary_intr<0x01, "tzmsk", MRM4r, MRM4m>;
} // HasTBM, EFLAGS
+def BEXTRIMaskXForm : SDNodeXForm<imm, [{
+ unsigned Length = countTrailingOnes(N->getZExtValue());
+ return getI32Imm(Length << 8, SDLoc(N));
+}]>;
+
+// Use BEXTRI for 64-bit 'and' with large immediates.
+let Predicates = [HasTBM], AddedComplexity = 1 in {
+ def : Pat<(and GR64:$src, AndMask64:$mask),
+ (BEXTRI64ri GR64:$src, (BEXTRIMaskXForm imm:$mask))>;
+
+ def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
+ (BEXTRI64mi addr:$src, (BEXTRIMaskXForm imm:$mask))>;
+}
+
//===----------------------------------------------------------------------===//
// Lightweight Profiling Instructions
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D36129.109052.patch
Type: text/x-patch
Size: 2607 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170801/cc043bdc/attachment.bin>
More information about the llvm-commits
mailing list