@@ -440,20 +440,10 @@ def GIImmSubFrom32 : GICustomOperandRenderer<"renderImmSubFrom32">,
440440// in which imm = imm0 + imm1 and both imm0 and imm1 are simm12. We make imm0
441441// as large as possible and imm1 as small as possible so that we might be able
442442// to use c.addi for the small immediate.
443- def AddiPair : PatLeaf<(imm), [{
444- if (!N->hasOneUse())
445- return false;
443+ def AddiPair : ImmLeaf<XLenVT, [{
446444 // The immediate operand must be in range [-4096,-2049] or [2048,4094].
447- int64_t Imm = N->getSExtValue();
448445 return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094);
449- }]> {
450- let GISelPredicateCode = [{
451- if (!MRI.hasOneNonDBGUse(MI.getOperand(0).getReg()))
452- return false;
453- int64_t Imm = MI.getOperand(1).getCImm()->getSExtValue();
454- return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094);
455- }];
456- }
446+ }]>;
457447
458448// Return imm - (imm < 0 ? -2048 : 2047).
459449def AddiPairImmSmall : SDNodeXForm<imm, [{
@@ -492,55 +482,23 @@ def GIXLenSubTrailingOnes : GICustomOperandRenderer<"renderXLenSubTrailingOnes">
492482
493483// Checks if this mask is a non-empty sequence of ones starting at the
494484// most/least significant bit with the remainder zero and exceeds simm32/simm12.
495- def LeadingOnesMask : PatLeaf<(imm), [{
496- if (!N->hasOneUse())
497- return false;
498- return !isInt<32>(N->getSExtValue()) && isMask_64(~N->getSExtValue());
499- }], TrailingZeros> {
500- let GISelPredicateCode = [{
501- if (!MRI.hasOneNonDBGUse(MI.getOperand(0).getReg()))
502- return false;
503- const auto &MO = MI.getOperand(1);
504- return !isInt<32>(MO.getCImm()->getSExtValue()) &&
505- isMask_64(~MO.getCImm()->getSExtValue());
506- }];
507- }
485+ def LeadingOnesMask : ImmLeaf<XLenVT, [{
486+ return !isInt<32>(Imm) && isMask_64(~Imm);
487+ }], TrailingZeros>;
508488
509- def TrailingOnesMask : PatLeaf<(imm), [{
510- if (!N->hasOneUse())
511- return false;
512- return !isInt<12>(N->getSExtValue()) && isMask_64(N->getZExtValue());
513- }], XLenSubTrailingOnes> {
514- let GISelPredicateCode = [{
515- if (!MRI.hasOneNonDBGUse(MI.getOperand(0).getReg()))
516- return false;
517- const auto &MO = MI.getOperand(1);
518- return !isInt<12>(MO.getCImm()->getSExtValue()) &&
519- isMask_64(MO.getCImm()->getZExtValue());
520- }];
521- }
489+ def TrailingOnesMask : IntImmLeaf<XLenVT, [{
490+ return !isInt<12>(Imm.getSExtValue()) && isMask_64(Imm.getZExtValue());
491+ }], XLenSubTrailingOnes>;
522492
523493// Similar to LeadingOnesMask, but only consider leading ones in the lower 32
524494// bits.
525- def LeadingOnesWMask : PatLeaf<(imm), [{
526- if (!N->hasOneUse())
527- return false;
495+ def LeadingOnesWMask : ImmLeaf<XLenVT, [{
528496 // If the value is a uint32 but not an int32, it must have bit 31 set and
529497 // bits 63:32 cleared. After that we're looking for a shifted mask but not
530498 // an all ones mask.
531- int64_t Imm = N->getSExtValue();
532499 return !isInt<32>(Imm) && isUInt<32>(Imm) && isShiftedMask_64(Imm) &&
533500 Imm != UINT64_C(0xffffffff);
534- }], TrailingZeros> {
535- let GISelPredicateCode = [{
536- if (!MRI.hasOneNonDBGUse(MI.getOperand(0).getReg()))
537- return false;
538- const auto &MO = MI.getOperand(1);
539- int64_t Imm = MO.getCImm()->getSExtValue();
540- return !isInt<32>(Imm) && isUInt<32>(Imm) && isShiftedMask_64(Imm) &&
541- Imm != UINT64_C(0xffffffff);
542- }];
543- }
501+ }], TrailingZeros>;
544502
545503//===----------------------------------------------------------------------===//
546504// Instruction Formats
@@ -1350,6 +1308,14 @@ def 33signbits_node : PatLeaf<(i64 GPR:$src), [{
13501308 return CurDAG->ComputeNumSignBits(SDValue(N, 0)) > 32;
13511309}]>;
13521310
1311+ class immop_oneuse<ImmLeaf leaf> : PatLeaf<(leaf), [{
1312+ return N->hasOneUse();
1313+ }]> {
1314+ let GISelPredicateCode = [{
1315+ return MRI.hasOneNonDBGUse(MI.getOperand(0).getReg());
1316+ }];
1317+ }
1318+
13531319/// Simple arithmetic operations
13541320
13551321def : PatGprGpr<add, ADD>;
@@ -1387,10 +1353,12 @@ def : Pat<(XLenVT (sub 0, (and_oneuse GPR:$rs, 1))),
13871353 (ImmSubFromXLen (XLenVT 1)))>;
13881354
13891355// AND with leading/trailing ones mask exceeding simm32/simm12.
1390- def : Pat<(i64 (and GPR:$rs, LeadingOnesMask:$mask)),
1391- (SLLI (i64 (SRLI $rs, LeadingOnesMask:$mask)), LeadingOnesMask:$mask)>;
1392- def : Pat<(XLenVT (and GPR:$rs, TrailingOnesMask:$mask)),
1393- (SRLI (XLenVT (SLLI $rs, TrailingOnesMask:$mask)), TrailingOnesMask:$mask)>;
1356+ def : Pat<(i64 (and GPR:$rs, immop_oneuse<LeadingOnesMask>:$mask)),
1357+ (SLLI (i64 (SRLI $rs, (TrailingZeros imm:$mask))),
1358+ (TrailingZeros imm:$mask))>;
1359+ def : Pat<(XLenVT (and GPR:$rs, immop_oneuse<TrailingOnesMask>:$mask)),
1360+ (SRLI (XLenVT (SLLI $rs, (XLenSubTrailingOnes imm:$mask))),
1361+ (XLenSubTrailingOnes imm:$mask))>;
13941362
13951363// Match both a plain shift and one where the shift amount is masked (this is
13961364// typically introduced when the legalizer promotes the shift amount and
@@ -1981,8 +1949,9 @@ def u32simm12 : ImmLeaf<XLenVT, [{
19811949
19821950let Predicates = [IsRV64] in {
19831951
1984- def : Pat<(i64 (and GPR:$rs, LeadingOnesWMask:$mask)),
1985- (SLLI (i64 (SRLIW $rs, LeadingOnesWMask:$mask)), LeadingOnesWMask:$mask)>;
1952+ def : Pat<(i64 (and GPR:$rs, immop_oneuse<LeadingOnesWMask>:$mask)),
1953+ (SLLI (i64 (SRLIW $rs, (TrailingZeros imm:$mask))),
1954+ (TrailingZeros imm:$mask))>;
19861955
19871956/// sext and zext
19881957
@@ -2081,15 +2050,15 @@ def KCFI_CHECK
20812050}
20822051
20832052/// Simple optimization
2084- def : Pat<(XLenVT (add GPR:$rs1, ( AddiPair:$rs2) )),
2085- (ADDI (XLenVT (ADDI GPR:$rs1, (AddiPairImmLarge AddiPair :$rs2))),
2086- (AddiPairImmSmall GPR :$rs2))>;
2053+ def : Pat<(XLenVT (add GPR:$rs1, immop_oneuse< AddiPair> :$rs2)),
2054+ (ADDI (XLenVT (ADDI GPR:$rs1, (AddiPairImmLarge imm :$rs2))),
2055+ (AddiPairImmSmall imm :$rs2))>;
20872056
20882057let Predicates = [IsRV64] in {
20892058// Select W instructions if only the lower 32-bits of the result are used.
2090- def : Pat<(binop_allwusers<add> GPR:$rs1, ( AddiPair:$rs2) ),
2091- (ADDIW (i64 (ADDIW GPR:$rs1, (AddiPairImmLarge AddiPair :$rs2))),
2092- (AddiPairImmSmall AddiPair :$rs2))>;
2059+ def : Pat<(binop_allwusers<add> GPR:$rs1, immop_oneuse< AddiPair> :$rs2),
2060+ (ADDIW (i64 (ADDIW GPR:$rs1, (AddiPairImmLarge imm :$rs2))),
2061+ (AddiPairImmSmall imm :$rs2))>;
20932062}
20942063
20952064//===----------------------------------------------------------------------===//
0 commit comments