Subzero. ARM32. Fix bugs uncovered by scons tests.
BUG= https://bugs.chromium.org/p/nativeclient/issues/detail?id=4076
R=eholk@chromium.org, kschimpf@google.com, stichnot@chromium.org
Review URL: https://codereview.chromium.org/1768823002 .
diff --git a/src/IceTargetLoweringARM32.cpp b/src/IceTargetLoweringARM32.cpp
index 6efee62..e3f46ea 100644
--- a/src/IceTargetLoweringARM32.cpp
+++ b/src/IceTargetLoweringARM32.cpp
@@ -1412,17 +1412,18 @@
void TargetARM32::finishArgumentLowering(Variable *Arg, Variable *FramePtr,
size_t BasicFrameOffset,
size_t *InArgsSizeBytes) {
+ const Type Ty = Arg->getType();
+ *InArgsSizeBytes = applyStackAlignmentTy(*InArgsSizeBytes, Ty);
+
if (auto *Arg64On32 = llvm::dyn_cast<Variable64On32>(Arg)) {
- Variable *Lo = Arg64On32->getLo();
- Variable *Hi = Arg64On32->getHi();
+ Variable *const Lo = Arg64On32->getLo();
+ Variable *const Hi = Arg64On32->getHi();
finishArgumentLowering(Lo, FramePtr, BasicFrameOffset, InArgsSizeBytes);
finishArgumentLowering(Hi, FramePtr, BasicFrameOffset, InArgsSizeBytes);
return;
}
- Type Ty = Arg->getType();
assert(Ty != IceType_i64);
- *InArgsSizeBytes = applyStackAlignmentTy(*InArgsSizeBytes, Ty);
const int32_t ArgStackOffset = BasicFrameOffset + *InArgsSizeBytes;
*InArgsSizeBytes += typeWidthInBytesOnStack(Ty);
@@ -4603,9 +4604,10 @@
CondARM32::Cond Cond) {
auto *Retry = Context.insert<InstARM32Label>(this);
+
{ // scoping for loop highlighting.
+ Variable *Success = makeReg(IceType_i32);
Variable *Tmp = (Ty == IceType_i64) ? makeI64RegPair() : makeReg(Ty);
- auto *Success = makeReg(IceType_i32);
auto *_0 = Ctx->getConstantZero(IceType_i32);
Context.insert<InstFakeDef>(Tmp);
@@ -4614,9 +4616,19 @@
_ldrex(Tmp, formMemoryOperand(AddrR, Ty))->setDestRedefined();
auto *StoreValue = Operation(Tmp);
assert(StoreValue->mustHaveReg());
- _strex(Success, StoreValue, formMemoryOperand(AddrR, Ty), Cond);
- _cmp(Success, _0, Cond);
+ // strex requires Dest to be a register other than Value or Addr. This
+ // restriction is cleanly represented by adding an "early" definition of
+ // Dest (or a latter use of all the sources.)
+ Context.insert<InstFakeDef>(Success);
+ if (Cond != CondARM32::AL) {
+ _mov_redefined(Success, legalize(_0, Legal_Reg | Legal_Flex),
+ InstARM32::getOppositeCondition(Cond));
+ }
+ _strex(Success, StoreValue, formMemoryOperand(AddrR, Ty), Cond)
+ ->setDestRedefined();
+ _cmp(Success, _0);
}
+
_br(Retry, CondARM32::NE);
}
@@ -4887,6 +4899,8 @@
}
if (DestTy == IceType_i64) {
+ Variable *LoadedValue = nullptr;
+
auto *New = makeI64RegPair();
Context.insert<InstFakeDef>(New);
lowerAssign(InstAssign::create(Func, New, Instr->getArg(2)));
@@ -4898,26 +4912,21 @@
_dmb();
lowerLoadLinkedStoreExclusive(
DestTy, Instr->getArg(0),
- [this, Expected, New, Instr, DestTy](Variable *Tmp) {
+ [this, Expected, New, Instr, DestTy, &LoadedValue](Variable *Tmp) {
auto *ExpectedLoR = llvm::cast<Variable>(loOperand(Expected));
auto *ExpectedHiR = llvm::cast<Variable>(hiOperand(Expected));
auto *TmpLoR = llvm::cast<Variable>(loOperand(Tmp));
auto *TmpHiR = llvm::cast<Variable>(hiOperand(Tmp));
_cmp(TmpLoR, ExpectedLoR);
_cmp(TmpHiR, ExpectedHiR, CondARM32::EQ);
- // Adding an explicit use of Tmp here, or its live range will not
- // reach here (only those of Tmp.Lo and Tmp.Hi will.)
- Context.insert<InstFakeUse>(Tmp);
- _mov_redefined(ExpectedLoR, TmpLoR);
- _mov_redefined(ExpectedHiR, TmpHiR);
- // Same as above.
- Context.insert<InstFakeUse>(Tmp);
+ LoadedValue = Tmp;
return New;
},
CondARM32::EQ);
_dmb();
- lowerAssign(InstAssign::create(Func, Dest, Expected));
+ Context.insert<InstFakeUse>(LoadedValue);
+ lowerAssign(InstAssign::create(Func, Dest, LoadedValue));
// The fake-use Expected prevents the assignments to Expected (above)
// from being removed if Dest is not used.
Context.insert<InstFakeUse>(Expected);
@@ -4929,18 +4938,20 @@
auto *New = legalizeToReg(Instr->getArg(2));
auto *Expected = legalizeToReg(Instr->getArg(1));
+ Variable *LoadedValue = nullptr;
_dmb();
lowerLoadLinkedStoreExclusive(
- DestTy,
- Instr->getArg(0), [this, Expected, New, Instr, DestTy](Variable *Tmp) {
+ DestTy, Instr->getArg(0),
+ [this, Expected, New, Instr, DestTy, &LoadedValue](Variable *Tmp) {
lowerIcmpCond(InstIcmp::Eq, Tmp, Expected);
- _mov_redefined(Expected, Tmp);
+ LoadedValue = Tmp;
return New;
- }, CondARM32::EQ);
+ },
+ CondARM32::EQ);
_dmb();
- lowerAssign(InstAssign::create(Func, Dest, Expected));
+ lowerAssign(InstAssign::create(Func, Dest, LoadedValue));
Context.insert<InstFakeUse>(Expected);
Context.insert<InstFakeUse>(New);
return;