-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[MIPS]: Rework atomic max/min expand for subword #89575
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -342,6 +342,7 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( | |
bool IsMin = false; | ||
bool IsMax = false; | ||
bool IsUnsigned = false; | ||
bool DestOK = false; | ||
|
||
unsigned Opcode = 0; | ||
switch (I->getOpcode()) { | ||
|
@@ -388,6 +389,7 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( | |
Opcode = Mips::XOR; | ||
break; | ||
case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA: | ||
SEOp = Mips::SEB; | ||
IsUnsigned = true; | ||
IsMin = true; | ||
break; | ||
|
@@ -403,6 +405,7 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( | |
IsMin = true; | ||
break; | ||
case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA: | ||
SEOp = Mips::SEB; | ||
IsUnsigned = true; | ||
IsMax = true; | ||
break; | ||
|
@@ -473,48 +476,38 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( | |
unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ; | ||
unsigned MOVIncr = IsMax ? MOVN : MOVZ; | ||
|
||
// For little endian we need to clear uninterested bits. | ||
if (STI->isLittle()) { | ||
if (!IsUnsigned) { | ||
BuildMI(loopMBB, DL, TII->get(Mips::SRAV), OldVal) | ||
.addReg(OldVal) | ||
.addReg(ShiftAmnt); | ||
BuildMI(loopMBB, DL, TII->get(Mips::SRAV), Incr) | ||
.addReg(Incr) | ||
.addReg(ShiftAmnt); | ||
if (STI->hasMips32r2()) { | ||
BuildMI(loopMBB, DL, TII->get(SEOp), OldVal).addReg(OldVal); | ||
BuildMI(loopMBB, DL, TII->get(SEOp), Incr).addReg(Incr); | ||
} else { | ||
const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24; | ||
BuildMI(loopMBB, DL, TII->get(Mips::SLL), OldVal) | ||
.addReg(OldVal, RegState::Kill) | ||
.addImm(ShiftImm); | ||
BuildMI(loopMBB, DL, TII->get(Mips::SRA), OldVal) | ||
.addReg(OldVal, RegState::Kill) | ||
.addImm(ShiftImm); | ||
BuildMI(loopMBB, DL, TII->get(Mips::SLL), Incr) | ||
.addReg(Incr, RegState::Kill) | ||
.addImm(ShiftImm); | ||
BuildMI(loopMBB, DL, TII->get(Mips::SRA), Incr) | ||
.addReg(Incr, RegState::Kill) | ||
.addImm(ShiftImm); | ||
} | ||
} else { | ||
// and OldVal, OldVal, Mask | ||
// and Incr, Incr, Mask | ||
BuildMI(loopMBB, DL, TII->get(Mips::AND), OldVal) | ||
.addReg(OldVal) | ||
.addReg(Mask); | ||
BuildMI(loopMBB, DL, TII->get(Mips::AND), Incr) | ||
.addReg(Incr) | ||
.addReg(Mask); | ||
} | ||
BuildMI(loopMBB, DL, TII->get(Mips::SRAV), StoreVal) | ||
.addReg(OldVal) | ||
.addReg(ShiftAmnt); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: ShiftAmnt may be zero. In this case, the high-part of OldVal will be keeped. |
||
if (STI->hasMips32r2() && !IsUnsigned) { | ||
BuildMI(loopMBB, DL, TII->get(SEOp), StoreVal).addReg(StoreVal); | ||
} else if (STI->hasMips32r2() && IsUnsigned) { | ||
const unsigned OpMask = SEOp == Mips::SEH ? 0xffff : 0xff; | ||
BuildMI(loopMBB, DL, TII->get(Mips::ANDi), StoreVal) | ||
.addReg(StoreVal) | ||
.addImm(OpMask); | ||
} else { | ||
const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24; | ||
const unsigned SROp = IsUnsigned ? Mips::SRL : Mips::SRA; | ||
BuildMI(loopMBB, DL, TII->get(Mips::SLL), StoreVal) | ||
.addReg(StoreVal, RegState::Kill) | ||
.addImm(ShiftImm); | ||
BuildMI(loopMBB, DL, TII->get(SROp), StoreVal) | ||
.addReg(StoreVal, RegState::Kill) | ||
.addImm(ShiftImm); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @yingopq You talked about here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why unsigned have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right.
So that we can save an INSN for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I submit and thank you for helping to solve this problem and explaining it carefully. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One question: is it valid to specify |
||
} | ||
// unsigned: sltu Scratch4, oldVal, Incr | ||
// signed: slt Scratch4, oldVal, Incr | ||
BuildMI(loopMBB, DL, TII->get(Mips::OR), Dest) | ||
.addReg(Mips::ZERO) | ||
.addReg(StoreVal); | ||
DestOK = true; | ||
BuildMI(loopMBB, DL, TII->get(Mips::SLLV), StoreVal) | ||
.addReg(StoreVal) | ||
.addReg(ShiftAmnt); | ||
|
||
// unsigned: sltu Scratch4, StoreVal, Incr | ||
// signed: slt Scratch4, StoreVal, Incr | ||
BuildMI(loopMBB, DL, TII->get(SLTScratch4), Scratch4) | ||
.addReg(OldVal) | ||
.addReg(StoreVal) | ||
.addReg(Incr); | ||
|
||
if (STI->hasMips64r6() || STI->hasMips32r6()) { | ||
|
@@ -525,7 +518,7 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( | |
// seleqz Scratch4, Incr, Scratch4 | ||
// or BinOpRes, BinOpRes, Scratch4 | ||
BuildMI(loopMBB, DL, TII->get(SELOldVal), BinOpRes) | ||
.addReg(OldVal) | ||
.addReg(StoreVal) | ||
.addReg(Scratch4); | ||
BuildMI(loopMBB, DL, TII->get(SELIncr), Scratch4) | ||
.addReg(Incr) | ||
|
@@ -534,12 +527,12 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( | |
.addReg(BinOpRes) | ||
.addReg(Scratch4); | ||
} else { | ||
// max: move BinOpRes, OldVal | ||
// max: move BinOpRes, StoreVal | ||
// movn BinOpRes, Incr, Scratch4, BinOpRes | ||
// min: move BinOpRes, OldVal | ||
// min: move BinOpRes, StoreVal | ||
// movz BinOpRes, Incr, Scratch4, BinOpRes | ||
BuildMI(loopMBB, DL, TII->get(OR), BinOpRes) | ||
.addReg(OldVal) | ||
.addReg(StoreVal) | ||
.addReg(Mips::ZERO); | ||
BuildMI(loopMBB, DL, TII->get(MOVIncr), BinOpRes) | ||
.addReg(Incr) | ||
|
@@ -586,23 +579,24 @@ bool MipsExpandPseudo::expandAtomicBinOpSubword( | |
// srl srlres,maskedoldval1,shiftamt | ||
// sign_extend dest,srlres | ||
|
||
sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne()); | ||
|
||
BuildMI(sinkMBB, DL, TII->get(Mips::AND), Dest) | ||
.addReg(OldVal).addReg(Mask); | ||
BuildMI(sinkMBB, DL, TII->get(Mips::SRLV), Dest) | ||
.addReg(Dest).addReg(ShiftAmnt); | ||
if (!DestOK) { | ||
sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne()); | ||
BuildMI(sinkMBB, DL, TII->get(Mips::AND), Dest).addReg(OldVal).addReg(Mask); | ||
BuildMI(sinkMBB, DL, TII->get(Mips::SRLV), Dest) | ||
.addReg(Dest) | ||
.addReg(ShiftAmnt); | ||
|
||
if (STI->hasMips32r2()) { | ||
BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest); | ||
} else { | ||
const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24; | ||
BuildMI(sinkMBB, DL, TII->get(Mips::SLL), Dest) | ||
.addReg(Dest, RegState::Kill) | ||
.addImm(ShiftImm); | ||
BuildMI(sinkMBB, DL, TII->get(Mips::SRA), Dest) | ||
.addReg(Dest, RegState::Kill) | ||
.addImm(ShiftImm); | ||
if (STI->hasMips32r2()) { | ||
BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest); | ||
} else { | ||
const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24; | ||
BuildMI(sinkMBB, DL, TII->get(Mips::SLL), Dest) | ||
.addReg(Dest, RegState::Kill) | ||
.addImm(ShiftImm); | ||
BuildMI(sinkMBB, DL, TII->get(Mips::SRA), Dest) | ||
.addReg(Dest, RegState::Kill) | ||
.addImm(ShiftImm); | ||
} | ||
} | ||
|
||
LivePhysRegs LiveRegs; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have noticed that sign-extension of
Incr
subword is removed. Why is that?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For
RegState::Kill
, I noticed that it is also used when dest reg is same with one of src regs, not only in MIPS code.In fact I am not sure about its really meanings.
Incr
is an argument of this function passed by register $5. We can assume that it has been well sign-/zero- extended.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wzssyqa Do I need to remove the
RegState::Kill
ofStoreVal
? The current test has not found any problems related to this. But I once encountered a problem related toRegState::Kill
when I create a new reg likeScratch
in functionMachineBasicBlock *MipsTargetLowering::emitAtomicBinaryPartword
and use it in functionbool MipsExpandPseudo::expandAtomicBinOpSubword
to replaceOldVal
, and when the code is executed toslt
, an error is reported.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems it's safe to use
RegState::Kill
for something likea <- op(a)
.I guess it is even more friendly to register allocator, Since the register allocator can even use different hardware register for before/after this
RegState::Kill
note.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, now it is OK for
a <- op(a)
, the scenario where my lab error reported isb <- op(a, RegState::Kill) + op(a)
.