@@ -448,20 +448,10 @@ def GIImmSubFrom32 : GICustomOperandRenderer<"renderImmSubFrom32">,
448448// in which imm = imm0 + imm1 and both imm0 and imm1 are simm12. We make imm0
449449// as large as possible and imm1 as small as possible so that we might be able
450450// to use c.addi for the small immediate.
451- def AddiPair : PatLeaf<(imm), [{
452- if (!N->hasOneUse())
453- return false;
451+ def AddiPair : ImmLeaf<XLenVT, [{
454452 // The immediate operand must be in range [-4096,-2049] or [2048,4094].
455- int64_t Imm = N->getSExtValue();
456453 return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094);
457- }]> {
458- let GISelPredicateCode = [{
459- if (!MRI.hasOneNonDBGUse(MI.getOperand(0).getReg()))
460- return false;
461- int64_t Imm = MI.getOperand(1).getCImm()->getSExtValue();
462- return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094);
463- }];
464- }
454+ }]>;
465455
466456// Return imm - (imm < 0 ? -2048 : 2047).
467457def AddiPairImmSmall : SDNodeXForm<imm, [{
@@ -500,55 +490,23 @@ def GIXLenSubTrailingOnes : GICustomOperandRenderer<"renderXLenSubTrailingOnes">
500490
501491// Checks if this mask is a non-empty sequence of ones starting at the
502492// most/least significant bit with the remainder zero and exceeds simm32/simm12.
503- def LeadingOnesMask : PatLeaf<(imm), [{
504- if (!N->hasOneUse())
505- return false;
506- return !isInt<32>(N->getSExtValue()) && isMask_64(~N->getSExtValue());
507- }], TrailingZeros> {
508- let GISelPredicateCode = [{
509- if (!MRI.hasOneNonDBGUse(MI.getOperand(0).getReg()))
510- return false;
511- const auto &MO = MI.getOperand(1);
512- return !isInt<32>(MO.getCImm()->getSExtValue()) &&
513- isMask_64(~MO.getCImm()->getSExtValue());
514- }];
515- }
493+ def LeadingOnesMask : ImmLeaf<XLenVT, [{
494+ return !isInt<32>(Imm) && isMask_64(~Imm);
495+ }], TrailingZeros>;
516496
517- def TrailingOnesMask : PatLeaf<(imm), [{
518- if (!N->hasOneUse())
519- return false;
520- return !isInt<12>(N->getSExtValue()) && isMask_64(N->getZExtValue());
521- }], XLenSubTrailingOnes> {
522- let GISelPredicateCode = [{
523- if (!MRI.hasOneNonDBGUse(MI.getOperand(0).getReg()))
524- return false;
525- const auto &MO = MI.getOperand(1);
526- return !isInt<12>(MO.getCImm()->getSExtValue()) &&
527- isMask_64(MO.getCImm()->getZExtValue());
528- }];
529- }
497+ def TrailingOnesMask : IntImmLeaf<XLenVT, [{
498+ return !isInt<12>(Imm.getSExtValue()) && isMask_64(Imm.getZExtValue());
499+ }], XLenSubTrailingOnes>;
530500
531501// Similar to LeadingOnesMask, but only consider leading ones in the lower 32
532502// bits.
533- def LeadingOnesWMask : PatLeaf<(imm), [{
534- if (!N->hasOneUse())
535- return false;
503+ def LeadingOnesWMask : ImmLeaf<XLenVT, [{
536504 // If the value is a uint32 but not an int32, it must have bit 31 set and
537505 // bits 63:32 cleared. After that we're looking for a shifted mask but not
538506 // an all ones mask.
539- int64_t Imm = N->getSExtValue();
540507 return !isInt<32>(Imm) && isUInt<32>(Imm) && isShiftedMask_64(Imm) &&
541508 Imm != UINT64_C(0xffffffff);
542- }], TrailingZeros> {
543- let GISelPredicateCode = [{
544- if (!MRI.hasOneNonDBGUse(MI.getOperand(0).getReg()))
545- return false;
546- const auto &MO = MI.getOperand(1);
547- int64_t Imm = MO.getCImm()->getSExtValue();
548- return !isInt<32>(Imm) && isUInt<32>(Imm) && isShiftedMask_64(Imm) &&
549- Imm != UINT64_C(0xffffffff);
550- }];
551- }
509+ }], TrailingZeros>;
552510
553511//===----------------------------------------------------------------------===//
554512// Instruction Formats
@@ -1358,6 +1316,14 @@ def 33signbits_node : PatLeaf<(i64 GPR:$src), [{
13581316 return CurDAG->ComputeNumSignBits(SDValue(N, 0)) > 32;
13591317}]>;
13601318
1319+ class immop_oneuse<ImmLeaf leaf> : PatLeaf<(leaf), [{
1320+ return N->hasOneUse();
1321+ }]> {
1322+ let GISelPredicateCode = [{
1323+ return MRI.hasOneNonDBGUse(MI.getOperand(0).getReg());
1324+ }];
1325+ }
1326+
13611327/// Simple arithmetic operations
13621328
13631329def : PatGprGpr<add, ADD>;
@@ -1395,10 +1361,12 @@ def : Pat<(XLenVT (sub 0, (and_oneuse GPR:$rs, 1))),
13951361 (ImmSubFromXLen (XLenVT 1)))>;
13961362
13971363// AND with leading/trailing ones mask exceeding simm32/simm12.
1398- def : Pat<(i64 (and GPR:$rs, LeadingOnesMask:$mask)),
1399- (SLLI (i64 (SRLI $rs, LeadingOnesMask:$mask)), LeadingOnesMask:$mask)>;
1400- def : Pat<(XLenVT (and GPR:$rs, TrailingOnesMask:$mask)),
1401- (SRLI (XLenVT (SLLI $rs, TrailingOnesMask:$mask)), TrailingOnesMask:$mask)>;
1364+ def : Pat<(i64 (and GPR:$rs, immop_oneuse<LeadingOnesMask>:$mask)),
1365+ (SLLI (i64 (SRLI $rs, (TrailingZeros imm:$mask))),
1366+ (TrailingZeros imm:$mask))>;
1367+ def : Pat<(XLenVT (and GPR:$rs, immop_oneuse<TrailingOnesMask>:$mask)),
1368+ (SRLI (XLenVT (SLLI $rs, (XLenSubTrailingOnes imm:$mask))),
1369+ (XLenSubTrailingOnes imm:$mask))>;
14021370
14031371// Match both a plain shift and one where the shift amount is masked (this is
14041372// typically introduced when the legalizer promotes the shift amount and
@@ -1989,8 +1957,9 @@ def u32simm12 : ImmLeaf<XLenVT, [{
19891957
19901958let Predicates = [IsRV64] in {
19911959
1992- def : Pat<(i64 (and GPR:$rs, LeadingOnesWMask:$mask)),
1993- (SLLI (i64 (SRLIW $rs, LeadingOnesWMask:$mask)), LeadingOnesWMask:$mask)>;
1960+ def : Pat<(i64 (and GPR:$rs, immop_oneuse<LeadingOnesWMask>:$mask)),
1961+ (SLLI (i64 (SRLIW $rs, (TrailingZeros imm:$mask))),
1962+ (TrailingZeros imm:$mask))>;
19941963
19951964/// sext and zext
19961965
@@ -2089,15 +2058,15 @@ def KCFI_CHECK
20892058}
20902059
20912060/// Simple optimization
2092- def : Pat<(XLenVT (add GPR:$rs1, ( AddiPair:$rs2) )),
2093- (ADDI (XLenVT (ADDI GPR:$rs1, (AddiPairImmLarge AddiPair :$rs2))),
2094- (AddiPairImmSmall GPR :$rs2))>;
2061+ def : Pat<(XLenVT (add GPR:$rs1, immop_oneuse< AddiPair> :$rs2)),
2062+ (ADDI (XLenVT (ADDI GPR:$rs1, (AddiPairImmLarge imm :$rs2))),
2063+ (AddiPairImmSmall imm :$rs2))>;
20952064
20962065let Predicates = [IsRV64] in {
20972066// Select W instructions if only the lower 32-bits of the result are used.
2098- def : Pat<(binop_allwusers<add> GPR:$rs1, ( AddiPair:$rs2) ),
2099- (ADDIW (i64 (ADDIW GPR:$rs1, (AddiPairImmLarge AddiPair :$rs2))),
2100- (AddiPairImmSmall AddiPair :$rs2))>;
2067+ def : Pat<(binop_allwusers<add> GPR:$rs1, immop_oneuse< AddiPair> :$rs2),
2068+ (ADDIW (i64 (ADDIW GPR:$rs1, (AddiPairImmLarge imm :$rs2))),
2069+ (AddiPairImmSmall imm :$rs2))>;
21012070}
21022071
21032072//===----------------------------------------------------------------------===//
0 commit comments