Commit fc8f6bfa by Jaydeep Patil Committed by Jim Stichnoth

[SubZero] Fix code generation of AtomicCmpxchg

The patch fixes a code generation issue occurred in the 2nd iteration of LL-SC loop. R=stichnot@chromium.org Patch from Jaydeep Patil <jaydeep.patil@imgtec.com>. Review-Url: https://codereview.chromium.org/2656723003 .
parent 8bd18e1b
...@@ -4554,7 +4554,8 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4554,7 +4554,8 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
auto *T2 = I32Reg(); auto *T2 = I32Reg();
auto *T3 = I32Reg(); auto *T3 = I32Reg();
auto *T4 = I32Reg(); auto *T4 = I32Reg();
_sync(); auto *T5 = I32Reg();
auto *T6 = I32Reg();
Variable *ValHi, *ValLo, *ExpectedLo, *ExpectedHi; Variable *ValHi, *ValLo, *ExpectedLo, *ExpectedHi;
if (llvm::isa<ConstantUndef>(Expected)) { if (llvm::isa<ConstantUndef>(Expected)) {
ExpectedLo = legalizeToReg(Ctx->getConstantZero(IceType_i32)); ExpectedLo = legalizeToReg(Ctx->getConstantZero(IceType_i32));
...@@ -4593,16 +4594,23 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4593,16 +4594,23 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(4))); llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(4)));
lowerLoad(InstLoad::create(Func, T3, AddrLo)); lowerLoad(InstLoad::create(Func, T3, AddrLo));
lowerLoad(InstLoad::create(Func, T4, AddrHi)); lowerLoad(InstLoad::create(Func, T4, AddrHi));
_sync();
Context.insert(Retry); Context.insert(Retry);
Sandboxer(this).ll(T1, AddrLo); Sandboxer(this).ll(T1, AddrLo);
_br(NoTarget, NoTarget, T1, ExpectedLo, Exit, CondMIPS32::Cond::NE); _br(NoTarget, NoTarget, T1, ExpectedLo, Exit, CondMIPS32::Cond::NE);
Sandboxer(this).sc(ValLo, AddrLo); _mov(T5, ValLo);
_br(NoTarget, NoTarget, ValLo, getZero(), Retry, CondMIPS32::Cond::EQ); Sandboxer(this).sc(T5, AddrLo);
Context.insert<InstFakeUse>(ValLo);
Context.insert<InstFakeUse>(ExpectedLo);
_br(NoTarget, NoTarget, T5, getZero(), Retry, CondMIPS32::Cond::EQ);
Context.insert(Retry1); Context.insert(Retry1);
Sandboxer(this).ll(T2, AddrHi); Sandboxer(this).ll(T2, AddrHi);
_br(NoTarget, NoTarget, T2, ExpectedHi, Exit, CondMIPS32::Cond::NE); _br(NoTarget, NoTarget, T2, ExpectedHi, Exit, CondMIPS32::Cond::NE);
Sandboxer(this).sc(ValHi, AddrHi); _mov(T6, ValHi);
_br(NoTarget, NoTarget, ValHi, getZero(), Retry1, CondMIPS32::Cond::EQ); Sandboxer(this).sc(T6, AddrHi);
Context.insert<InstFakeUse>(ValHi);
Context.insert<InstFakeUse>(ExpectedHi);
_br(NoTarget, NoTarget, T6, getZero(), Retry1, CondMIPS32::Cond::EQ);
Context.insert<InstFakeUse>(getZero()); Context.insert<InstFakeUse>(getZero());
Context.insert(Exit); Context.insert(Exit);
_mov(Dest64->getLo(), T3); _mov(Dest64->getLo(), T3);
...@@ -4625,7 +4633,6 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4625,7 +4633,6 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
auto *T7 = I32Reg(); auto *T7 = I32Reg();
auto *T8 = I32Reg(); auto *T8 = I32Reg();
auto *T9 = I32Reg(); auto *T9 = I32Reg();
_sync();
_addiu(RegAt, getZero(), -4); _addiu(RegAt, getZero(), -4);
_and(T1, ActualAddressR, RegAt); _and(T1, ActualAddressR, RegAt);
_andi(RegAt, ActualAddressR, 3); _andi(RegAt, ActualAddressR, 3);
...@@ -4637,6 +4644,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4637,6 +4644,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
_sllv(T5, RegAt, T2); _sllv(T5, RegAt, T2);
_andi(RegAt, NewR, Mask); _andi(RegAt, NewR, Mask);
_sllv(T6, RegAt, T2); _sllv(T6, RegAt, T2);
_sync();
Context.insert(Retry); Context.insert(Retry);
Sandboxer(this).ll(T7, formMemoryOperand(T1, DestTy)); Sandboxer(this).ll(T7, formMemoryOperand(T1, DestTy));
_and(T8, T7, T3); _and(T8, T7, T3);
...@@ -4644,6 +4652,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4644,6 +4652,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
_and(RegAt, T7, T4); _and(RegAt, T7, T4);
_or(T9, RegAt, T6); _or(T9, RegAt, T6);
Sandboxer(this).sc(T9, formMemoryOperand(T1, DestTy)); Sandboxer(this).sc(T9, formMemoryOperand(T1, DestTy));
Context.insert<InstFakeUse>(T6);
_br(NoTarget, NoTarget, getZero(), T9, Retry, CondMIPS32::Cond::EQ); _br(NoTarget, NoTarget, getZero(), T9, Retry, CondMIPS32::Cond::EQ);
Context.insert<InstFakeUse>(getZero()); Context.insert<InstFakeUse>(getZero());
Context.insert(Exit); Context.insert(Exit);
...@@ -4656,15 +4665,17 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4656,15 +4665,17 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
Context.insert<InstFakeUse>(NewR); Context.insert<InstFakeUse>(NewR);
} else { } else {
auto *T1 = I32Reg(); auto *T1 = I32Reg();
_sync(); auto *T2 = I32Reg();
Context.insert(Retry);
auto *NewR = legalizeToReg(New); auto *NewR = legalizeToReg(New);
auto *ExpectedR = legalizeToReg(Expected); auto *ExpectedR = legalizeToReg(Expected);
auto *ActualAddressR = legalizeToReg(ActualAddress); auto *ActualAddressR = legalizeToReg(ActualAddress);
_sync();
Context.insert(Retry);
Sandboxer(this).ll(T1, formMemoryOperand(ActualAddressR, DestTy)); Sandboxer(this).ll(T1, formMemoryOperand(ActualAddressR, DestTy));
_br(NoTarget, NoTarget, T1, ExpectedR, Exit, CondMIPS32::Cond::NE); _br(NoTarget, NoTarget, T1, ExpectedR, Exit, CondMIPS32::Cond::NE);
Sandboxer(this).sc(NewR, formMemoryOperand(ActualAddressR, DestTy)); _mov(T2, NewR);
_br(NoTarget, NoTarget, NewR, getZero(), Retry, CondMIPS32::Cond::EQ); Sandboxer(this).sc(T2, formMemoryOperand(ActualAddressR, DestTy));
_br(NoTarget, NoTarget, T2, getZero(), Retry, CondMIPS32::Cond::EQ);
Context.insert<InstFakeUse>(getZero()); Context.insert<InstFakeUse>(getZero());
Context.insert(Exit); Context.insert(Exit);
_mov(Dest, T1); _mov(Dest, T1);
......
...@@ -1638,7 +1638,6 @@ entry: ...@@ -1638,7 +1638,6 @@ entry:
; ARM32: bne ; ARM32: bne
; ARM32: dmb ; ARM32: dmb
; MIPS32-LABEL: test_atomic_cmpxchg_8 ; MIPS32-LABEL: test_atomic_cmpxchg_8
; MIPS32: sync
; MIPS32: addiu {{.*}}, $zero, -4 ; MIPS32: addiu {{.*}}, $zero, -4
; MIPS32: and ; MIPS32: and
; MIPS32: andi {{.*}}, {{.*}}, 3 ; MIPS32: andi {{.*}}, {{.*}}, 3
...@@ -1650,6 +1649,7 @@ entry: ...@@ -1650,6 +1649,7 @@ entry:
; MIPS32: sllv ; MIPS32: sllv
; MIPS32: andi {{.*}}, {{.*}}, 255 ; MIPS32: andi {{.*}}, {{.*}}, 255
; MIPS32: sllv ; MIPS32: sllv
; MIPS32: sync
; MIPS32: ll ; MIPS32: ll
; MIPS32: and ; MIPS32: and
; MIPS32: bne ; MIPS32: bne
...@@ -1687,7 +1687,6 @@ entry: ...@@ -1687,7 +1687,6 @@ entry:
; ARM32: bne ; ARM32: bne
; ARM32: dmb ; ARM32: dmb
; MIPS32-LABEL: test_atomic_cmpxchg_16 ; MIPS32-LABEL: test_atomic_cmpxchg_16
; MIPS32: sync
; MIPS32: addiu {{.*}}, $zero, -4 ; MIPS32: addiu {{.*}}, $zero, -4
; MIPS32: and ; MIPS32: and
; MIPS32: andi {{.*}}, {{.*}}, 3 ; MIPS32: andi {{.*}}, {{.*}}, 3
...@@ -1699,6 +1698,7 @@ entry: ...@@ -1699,6 +1698,7 @@ entry:
; MIPS32: sllv ; MIPS32: sllv
; MIPS32: andi {{.*}}, {{.*}}, 65535 ; MIPS32: andi {{.*}}, {{.*}}, 65535
; MIPS32: sllv ; MIPS32: sllv
; MIPS32: sync
; MIPS32: ll ; MIPS32: ll
; MIPS32: and ; MIPS32: and
; MIPS32: bne ; MIPS32: bne
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment