[llvm] r345584 - [X86][BMI1] X86DAGToDAGISel: select BEXTR from x & (-1 >> (32 - y)) pattern
Roman Lebedev via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 30 04:12:35 PDT 2018
Author: lebedevri
Date: Tue Oct 30 04:12:34 2018
New Revision: 345584
URL: http://llvm.org/viewvc/llvm-project?rev=345584&view=rev
Log:
[X86][BMI1] X86DAGToDAGISel: select BEXTR from x & (-1 >> (32 - y)) pattern
Summary:
The final pattern.
There is no test changes:
* We are looking for the pattern with one-use of it's mask,
* If the mask is one-use, D48768 will unfold it into pattern d.
* Thus, the tests have extra-use on the mask.
* Thus, only the BMI2 BZHI can be tested, and it already worked.
* So there is no BMI1 test coverage, we just assume it works since it uses the same codepath.
Reviewers: craig.topper, RKSimon
Reviewed By: RKSimon
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D53575
Modified:
llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
llvm/trunk/lib/Target/X86/X86InstrInfo.td
Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=345584&r1=345583&r2=345584&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Oct 30 04:12:34 2018
@@ -2749,11 +2749,45 @@ bool X86DAGToDAGISel::matchBitExtract(SD
return true;
};
+ // Match potentially-truncated (bitwidth - y)
+ auto matchShiftAmt = [checkOneUse, Size, &NBits](SDValue ShiftAmt) {
+ // Skip over a truncate of the shift amount.
+ if (ShiftAmt.getOpcode() == ISD::TRUNCATE) {
+ ShiftAmt = ShiftAmt.getOperand(0);
+ // The trunc should have been the only user of the real shift amount.
+ if (!checkOneUse(ShiftAmt))
+ return false;
+ }
+ // Match the shift amount as: (bitwidth - y). It should go away, too.
+ if (ShiftAmt.getOpcode() != ISD::SUB)
+ return false;
+ auto V0 = dyn_cast<ConstantSDNode>(ShiftAmt.getOperand(0));
+ if (!V0 || V0->getZExtValue() != Size)
+ return false;
+ NBits = ShiftAmt.getOperand(1);
+ return true;
+ };
+
+ // c) x & (-1 >> (32 - y))
+ auto matchPatternC = [&checkOneUse, matchShiftAmt](SDValue Mask) -> bool {
+ // Match `l>>`. Must only have one use!
+ if (Mask.getOpcode() != ISD::SRL || !checkOneUse(Mask))
+ return false;
+ // We should be shifting all-ones constant.
+ if (!isAllOnesConstant(Mask.getOperand(0)))
+ return false;
+ SDValue M1 = Mask.getOperand(1);
+ // The shift amount should not be used externally.
+ if (!checkOneUse(M1))
+ return false;
+ return matchShiftAmt(M1);
+ };
+
SDValue X;
// d) x << (32 - y) >> (32 - y)
- auto matchPatternD = [&checkOneUse, &checkTwoUse, Size, &X,
- &NBits](SDNode *Node) -> bool {
+ auto matchPatternD = [&checkOneUse, &checkTwoUse, matchShiftAmt,
+ &X](SDNode *Node) -> bool {
if (Node->getOpcode() != ISD::SRL)
return false;
SDValue N0 = Node->getOperand(0);
@@ -2765,28 +2799,16 @@ bool X86DAGToDAGISel::matchBitExtract(SD
// There should not be any uses of the shift amount outside of the pattern.
if (N1 != N01 || !checkTwoUse(N1))
return false;
- // Skip over a truncate of the shift amount.
- if (N1->getOpcode() == ISD::TRUNCATE) {
- N1 = N1->getOperand(0);
- // The trunc should have been the only user of the real shift amount.
- if (!checkOneUse(N1))
- return false;
- }
- // Match the shift amount as: (bitwidth - y). It should go away, too.
- if (N1.getOpcode() != ISD::SUB)
- return false;
- auto N10 = dyn_cast<ConstantSDNode>(N1.getOperand(0));
- if (!N10 || N10->getZExtValue() != Size)
+ if (!matchShiftAmt(N1))
return false;
X = N0->getOperand(0);
- NBits = N1.getOperand(1);
return true;
};
- auto matchLowBitMask = [&matchPatternA,
- &matchPatternB](SDValue Mask) -> bool {
+ auto matchLowBitMask = [&matchPatternA, &matchPatternB,
+ &matchPatternC](SDValue Mask) -> bool {
// FIXME: pattern c.
- return matchPatternA(Mask) || matchPatternB(Mask);
+ return matchPatternA(Mask) || matchPatternB(Mask) || matchPatternC(Mask);
};
if (Node->getOpcode() == ISD::AND) {
Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=345584&r1=345583&r2=345584&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Tue Oct 30 04:12:34 2018
@@ -2499,46 +2499,6 @@ let Predicates = [HasBMI2, NoTBM] in {
(MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
}
-let Predicates = [HasBMI2] in {
- multiclass _bmi_bzhi_pattern<dag regpattern, dag mempattern, RegisterClass RC,
- ValueType VT, Instruction DstInst,
- Instruction DstMemInst> {
- def : Pat<regpattern,
- (DstInst RC:$src,
- (INSERT_SUBREG (VT (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
- def : Pat<mempattern,
- (DstMemInst addr:$src,
- (INSERT_SUBREG (VT (IMPLICIT_DEF)), GR8:$lz, sub_8bit))>;
- }
-
- multiclass bmi_bzhi_patterns<RegisterClass RC, int bitwidth, ValueType VT,
- Instruction DstInst, X86MemOperand x86memop,
- Instruction DstMemInst> {
- // x & (-1 >> (bitwidth - y))
- defm : _bmi_bzhi_pattern<(and RC:$src, (srl -1, (sub bitwidth, GR8:$lz))),
- (and (x86memop addr:$src),
- (srl -1, (sub bitwidth, GR8:$lz))),
- RC, VT, DstInst, DstMemInst>;
- }
-
- defm : bmi_bzhi_patterns<GR32, 32, i32, BZHI32rr, loadi32, BZHI32rm>;
- defm : bmi_bzhi_patterns<GR64, 64, i64, BZHI64rr, loadi64, BZHI64rm>;
-
- // x & (-1 >> (32 - y))
- def : Pat<(and GR32:$src, (srl -1, (i8 (trunc (sub 32, GR32:$lz))))),
- (BZHI32rr GR32:$src, GR32:$lz)>;
- def : Pat<(and (loadi32 addr:$src), (srl -1, (i8 (trunc (sub 32, GR32:$lz))))),
- (BZHI32rm addr:$src, GR32:$lz)>;
-
- // x & (-1 >> (64 - y))
- def : Pat<(and GR64:$src, (srl -1, (i8 (trunc (sub 64, GR32:$lz))))),
- (BZHI64rr GR64:$src,
- (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
- def : Pat<(and (loadi64 addr:$src), (srl -1, (i8 (trunc (sub 64, GR32:$lz))))),
- (BZHI64rm addr:$src,
- (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$lz, sub_32bit))>;
-} // HasBMI2
-
multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC,
X86MemOperand x86memop, Intrinsic Int,
PatFrag ld_frag> {
More information about the llvm-commits
mailing list