Skip to content

Commit 758d97d

Browse files
authored
[MIPS]: Rework atomic max/min expand for subword (#89575)
The current code is so buggy: it can work for few cases. The problems include: 1. ll/sc works on a whole word, while other parts other than we rmw are dropped. 2. The oprands are not well zero-extended for unsigned ops. 3. It doesn't work for big-endian, as the postion of subword differs with little endian. And in fact, we can set the return value correct in ll/sc scope, so we can skip the sinkMBB.
1 parent f94ed6f commit 758d97d

File tree

2 files changed

+823
-766
lines changed

2 files changed

+823
-766
lines changed

llvm/lib/Target/Mips/MipsExpandPseudo.cpp

Lines changed: 54 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
342342
bool IsMin = false;
343343
bool IsMax = false;
344344
bool IsUnsigned = false;
345+
bool DestOK = false;
345346

346347
unsigned Opcode = 0;
347348
switch (I->getOpcode()) {
@@ -388,6 +389,7 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
388389
Opcode = Mips::XOR;
389390
break;
390391
case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:
392+
SEOp = Mips::SEB;
391393
IsUnsigned = true;
392394
IsMin = true;
393395
break;
@@ -403,6 +405,7 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
403405
IsMin = true;
404406
break;
405407
case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:
408+
SEOp = Mips::SEB;
406409
IsUnsigned = true;
407410
IsMax = true;
408411
break;
@@ -473,48 +476,38 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
473476
unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;
474477
unsigned MOVIncr = IsMax ? MOVN : MOVZ;
475478

476-
// For little endian we need to clear uninterested bits.
477-
if (STI->isLittle()) {
478-
if (!IsUnsigned) {
479-
BuildMI(loopMBB, DL, TII->get(Mips::SRAV), OldVal)
480-
.addReg(OldVal)
481-
.addReg(ShiftAmnt);
482-
BuildMI(loopMBB, DL, TII->get(Mips::SRAV), Incr)
483-
.addReg(Incr)
484-
.addReg(ShiftAmnt);
485-
if (STI->hasMips32r2()) {
486-
BuildMI(loopMBB, DL, TII->get(SEOp), OldVal).addReg(OldVal);
487-
BuildMI(loopMBB, DL, TII->get(SEOp), Incr).addReg(Incr);
488-
} else {
489-
const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
490-
BuildMI(loopMBB, DL, TII->get(Mips::SLL), OldVal)
491-
.addReg(OldVal, RegState::Kill)
492-
.addImm(ShiftImm);
493-
BuildMI(loopMBB, DL, TII->get(Mips::SRA), OldVal)
494-
.addReg(OldVal, RegState::Kill)
495-
.addImm(ShiftImm);
496-
BuildMI(loopMBB, DL, TII->get(Mips::SLL), Incr)
497-
.addReg(Incr, RegState::Kill)
498-
.addImm(ShiftImm);
499-
BuildMI(loopMBB, DL, TII->get(Mips::SRA), Incr)
500-
.addReg(Incr, RegState::Kill)
501-
.addImm(ShiftImm);
502-
}
503-
} else {
504-
// and OldVal, OldVal, Mask
505-
// and Incr, Incr, Mask
506-
BuildMI(loopMBB, DL, TII->get(Mips::AND), OldVal)
507-
.addReg(OldVal)
508-
.addReg(Mask);
509-
BuildMI(loopMBB, DL, TII->get(Mips::AND), Incr)
510-
.addReg(Incr)
511-
.addReg(Mask);
512-
}
479+
BuildMI(loopMBB, DL, TII->get(Mips::SRAV), StoreVal)
480+
.addReg(OldVal)
481+
.addReg(ShiftAmnt);
482+
if (STI->hasMips32r2() && !IsUnsigned) {
483+
BuildMI(loopMBB, DL, TII->get(SEOp), StoreVal).addReg(StoreVal);
484+
} else if (STI->hasMips32r2() && IsUnsigned) {
485+
const unsigned OpMask = SEOp == Mips::SEH ? 0xffff : 0xff;
486+
BuildMI(loopMBB, DL, TII->get(Mips::ANDi), StoreVal)
487+
.addReg(StoreVal)
488+
.addImm(OpMask);
489+
} else {
490+
const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
491+
const unsigned SROp = IsUnsigned ? Mips::SRL : Mips::SRA;
492+
BuildMI(loopMBB, DL, TII->get(Mips::SLL), StoreVal)
493+
.addReg(StoreVal, RegState::Kill)
494+
.addImm(ShiftImm);
495+
BuildMI(loopMBB, DL, TII->get(SROp), StoreVal)
496+
.addReg(StoreVal, RegState::Kill)
497+
.addImm(ShiftImm);
513498
}
514-
// unsigned: sltu Scratch4, oldVal, Incr
515-
// signed: slt Scratch4, oldVal, Incr
499+
BuildMI(loopMBB, DL, TII->get(Mips::OR), Dest)
500+
.addReg(Mips::ZERO)
501+
.addReg(StoreVal);
502+
DestOK = true;
503+
BuildMI(loopMBB, DL, TII->get(Mips::SLLV), StoreVal)
504+
.addReg(StoreVal)
505+
.addReg(ShiftAmnt);
506+
507+
// unsigned: sltu Scratch4, StoreVal, Incr
508+
// signed: slt Scratch4, StoreVal, Incr
516509
BuildMI(loopMBB, DL, TII->get(SLTScratch4), Scratch4)
517-
.addReg(OldVal)
510+
.addReg(StoreVal)
518511
.addReg(Incr);
519512

520513
if (STI->hasMips64r6() || STI->hasMips32r6()) {
@@ -525,7 +518,7 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
525518
// seleqz Scratch4, Incr, Scratch4
526519
// or BinOpRes, BinOpRes, Scratch4
527520
BuildMI(loopMBB, DL, TII->get(SELOldVal), BinOpRes)
528-
.addReg(OldVal)
521+
.addReg(StoreVal)
529522
.addReg(Scratch4);
530523
BuildMI(loopMBB, DL, TII->get(SELIncr), Scratch4)
531524
.addReg(Incr)
@@ -534,12 +527,12 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
534527
.addReg(BinOpRes)
535528
.addReg(Scratch4);
536529
} else {
537-
// max: move BinOpRes, OldVal
530+
// max: move BinOpRes, StoreVal
538531
// movn BinOpRes, Incr, Scratch4, BinOpRes
539-
// min: move BinOpRes, OldVal
532+
// min: move BinOpRes, StoreVal
540533
// movz BinOpRes, Incr, Scratch4, BinOpRes
541534
BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)
542-
.addReg(OldVal)
535+
.addReg(StoreVal)
543536
.addReg(Mips::ZERO);
544537
BuildMI(loopMBB, DL, TII->get(MOVIncr), BinOpRes)
545538
.addReg(Incr)
@@ -586,23 +579,24 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
586579
// srl srlres,maskedoldval1,shiftamt
587580
// sign_extend dest,srlres
588581

589-
sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne());
590-
591-
BuildMI(sinkMBB, DL, TII->get(Mips::AND), Dest)
592-
.addReg(OldVal).addReg(Mask);
593-
BuildMI(sinkMBB, DL, TII->get(Mips::SRLV), Dest)
594-
.addReg(Dest).addReg(ShiftAmnt);
582+
if (!DestOK) {
583+
sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne());
584+
BuildMI(sinkMBB, DL, TII->get(Mips::AND), Dest).addReg(OldVal).addReg(Mask);
585+
BuildMI(sinkMBB, DL, TII->get(Mips::SRLV), Dest)
586+
.addReg(Dest)
587+
.addReg(ShiftAmnt);
595588

596-
if (STI->hasMips32r2()) {
597-
BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest);
598-
} else {
599-
const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
600-
BuildMI(sinkMBB, DL, TII->get(Mips::SLL), Dest)
601-
.addReg(Dest, RegState::Kill)
602-
.addImm(ShiftImm);
603-
BuildMI(sinkMBB, DL, TII->get(Mips::SRA), Dest)
604-
.addReg(Dest, RegState::Kill)
605-
.addImm(ShiftImm);
589+
if (STI->hasMips32r2()) {
590+
BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest);
591+
} else {
592+
const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
593+
BuildMI(sinkMBB, DL, TII->get(Mips::SLL), Dest)
594+
.addReg(Dest, RegState::Kill)
595+
.addImm(ShiftImm);
596+
BuildMI(sinkMBB, DL, TII->get(Mips::SRA), Dest)
597+
.addReg(Dest, RegState::Kill)
598+
.addImm(ShiftImm);
599+
}
606600
}
607601

608602
LivePhysRegs LiveRegs;

0 commit comments

Comments
 (0)