Skip to content

Commit fbb27d1

Browse files
yingopqtstellar
authored andcommitted
[Mips] Fix missing sign extension in expansion of sub-word atomic max (#77072)
Add sign extension "SEB/SEH" before compare. Fix #61881 (cherry picked from commit 755b439)
1 parent e74c167 commit fbb27d1

File tree

2 files changed

+577
-129
lines changed

2 files changed

+577
-129
lines changed

llvm/lib/Target/Mips/MipsExpandPseudo.cpp

+42-9
Original file line numberDiff line numberDiff line change
@@ -388,18 +388,32 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
388388
Opcode = Mips::XOR;
389389
break;
390390
case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:
391+
IsUnsigned = true;
392+
IsMin = true;
393+
break;
391394
case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:
392395
IsUnsigned = true;
393-
[[fallthrough]];
396+
IsMin = true;
397+
break;
394398
case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:
399+
SEOp = Mips::SEB;
400+
IsMin = true;
401+
break;
395402
case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:
396403
IsMin = true;
397404
break;
398405
case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:
406+
IsUnsigned = true;
407+
IsMax = true;
408+
break;
399409
case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:
400410
IsUnsigned = true;
401-
[[fallthrough]];
411+
IsMax = true;
412+
break;
402413
case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:
414+
SEOp = Mips::SEB;
415+
IsMax = true;
416+
break;
403417
case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:
404418
IsMax = true;
405419
break;
@@ -461,14 +475,33 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword(
461475

462476
// For little endian we need to clear uninterested bits.
463477
if (STI->isLittle()) {
464-
// and OldVal, OldVal, Mask
465-
// and Incr, Incr, Mask
466-
BuildMI(loopMBB, DL, TII->get(Mips::AND), OldVal)
467-
.addReg(OldVal)
468-
.addReg(Mask);
469-
BuildMI(loopMBB, DL, TII->get(Mips::AND), Incr).addReg(Incr).addReg(Mask);
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+
}
470504
}
471-
472505
// unsigned: sltu Scratch4, oldVal, Incr
473506
// signed: slt Scratch4, oldVal, Incr
474507
BuildMI(loopMBB, DL, TII->get(SLTScratch4), Scratch4)

0 commit comments

Comments
 (0)