Skip to content

Commit 9a30550

Browse files
committed
[MIPS]: Rework atomic max/min expand for subword
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.
1 parent 16fed31 commit 9a30550

File tree

2 files changed

+821
-766
lines changed

2 files changed

+821
-766
lines changed

llvm/lib/Target/Mips/MipsExpandPseudo.cpp

Lines changed: 52 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,36 @@ 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).addReg(StoreVal).addImm(OpMask);
487+
} else {
488+
const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
489+
const unsigned SROp = IsUnsigned ? Mips::SRL : Mips::SRA;
490+
BuildMI(loopMBB, DL, TII->get(Mips::SLL), StoreVal)
491+
.addReg(StoreVal, RegState::Kill)
492+
.addImm(ShiftImm);
493+
BuildMI(loopMBB, DL, TII->get(SROp), StoreVal)
494+
.addReg(StoreVal, RegState::Kill)
495+
.addImm(ShiftImm);
513496
}
514-
// unsigned: sltu Scratch4, oldVal, Incr
515-
// signed: slt Scratch4, oldVal, Incr
497+
BuildMI(loopMBB, DL, TII->get(Mips::OR), Dest)
498+
.addReg(Mips::ZERO)
499+
.addReg(StoreVal);
500+
DestOK = true;
501+
BuildMI(loopMBB, DL, TII->get(Mips::SLLV), StoreVal)
502+
.addReg(StoreVal)
503+
.addReg(ShiftAmnt);
504+
505+
// unsigned: sltu Scratch4, StoreVal, Incr
506+
// signed: slt Scratch4, StoreVal, Incr
516507
BuildMI(loopMBB, DL, TII->get(SLTScratch4), Scratch4)
517-
.addReg(OldVal)
508+
.addReg(StoreVal)
518509
.addReg(Incr);
519510

520511
if (STI->hasMips64r6() || STI->hasMips32r6()) {
@@ -525,7 +516,7 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
525516
// seleqz Scratch4, Incr, Scratch4
526517
// or BinOpRes, BinOpRes, Scratch4
527518
BuildMI(loopMBB, DL, TII->get(SELOldVal), BinOpRes)
528-
.addReg(OldVal)
519+
.addReg(StoreVal)
529520
.addReg(Scratch4);
530521
BuildMI(loopMBB, DL, TII->get(SELIncr), Scratch4)
531522
.addReg(Incr)
@@ -534,12 +525,12 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
534525
.addReg(BinOpRes)
535526
.addReg(Scratch4);
536527
} else {
537-
// max: move BinOpRes, OldVal
528+
// max: move BinOpRes, StoreVal
538529
// movn BinOpRes, Incr, Scratch4, BinOpRes
539-
// min: move BinOpRes, OldVal
530+
// min: move BinOpRes, StoreVal
540531
// movz BinOpRes, Incr, Scratch4, BinOpRes
541532
BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)
542-
.addReg(OldVal)
533+
.addReg(StoreVal)
543534
.addReg(Mips::ZERO);
544535
BuildMI(loopMBB, DL, TII->get(MOVIncr), BinOpRes)
545536
.addReg(Incr)
@@ -586,23 +577,24 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
586577
// srl srlres,maskedoldval1,shiftamt
587578
// sign_extend dest,srlres
588579

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);
580+
if (!DestOK) {
581+
sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne());
582+
BuildMI(sinkMBB, DL, TII->get(Mips::AND), Dest).addReg(OldVal).addReg(Mask);
583+
BuildMI(sinkMBB, DL, TII->get(Mips::SRLV), Dest)
584+
.addReg(Dest)
585+
.addReg(ShiftAmnt);
595586

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);
587+
if (STI->hasMips32r2()) {
588+
BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest);
589+
} else {
590+
const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
591+
BuildMI(sinkMBB, DL, TII->get(Mips::SLL), Dest)
592+
.addReg(Dest, RegState::Kill)
593+
.addImm(ShiftImm);
594+
BuildMI(sinkMBB, DL, TII->get(Mips::SRA), Dest)
595+
.addReg(Dest, RegState::Kill)
596+
.addImm(ShiftImm);
597+
}
606598
}
607599

608600
LivePhysRegs LiveRegs;

0 commit comments

Comments
 (0)