Commit 324334e5 by John Porto

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 .
parent c8f56a39
...@@ -1412,17 +1412,18 @@ void TargetARM32::lowerArguments() { ...@@ -1412,17 +1412,18 @@ void TargetARM32::lowerArguments() {
void TargetARM32::finishArgumentLowering(Variable *Arg, Variable *FramePtr, void TargetARM32::finishArgumentLowering(Variable *Arg, Variable *FramePtr,
size_t BasicFrameOffset, size_t BasicFrameOffset,
size_t *InArgsSizeBytes) { size_t *InArgsSizeBytes) {
const Type Ty = Arg->getType();
*InArgsSizeBytes = applyStackAlignmentTy(*InArgsSizeBytes, Ty);
if (auto *Arg64On32 = llvm::dyn_cast<Variable64On32>(Arg)) { if (auto *Arg64On32 = llvm::dyn_cast<Variable64On32>(Arg)) {
Variable *Lo = Arg64On32->getLo(); Variable *const Lo = Arg64On32->getLo();
Variable *Hi = Arg64On32->getHi(); Variable *const Hi = Arg64On32->getHi();
finishArgumentLowering(Lo, FramePtr, BasicFrameOffset, InArgsSizeBytes); finishArgumentLowering(Lo, FramePtr, BasicFrameOffset, InArgsSizeBytes);
finishArgumentLowering(Hi, FramePtr, BasicFrameOffset, InArgsSizeBytes); finishArgumentLowering(Hi, FramePtr, BasicFrameOffset, InArgsSizeBytes);
return; return;
} }
Type Ty = Arg->getType();
assert(Ty != IceType_i64); assert(Ty != IceType_i64);
*InArgsSizeBytes = applyStackAlignmentTy(*InArgsSizeBytes, Ty);
const int32_t ArgStackOffset = BasicFrameOffset + *InArgsSizeBytes; const int32_t ArgStackOffset = BasicFrameOffset + *InArgsSizeBytes;
*InArgsSizeBytes += typeWidthInBytesOnStack(Ty); *InArgsSizeBytes += typeWidthInBytesOnStack(Ty);
...@@ -4603,9 +4604,10 @@ void TargetARM32::lowerLoadLinkedStoreExclusive( ...@@ -4603,9 +4604,10 @@ void TargetARM32::lowerLoadLinkedStoreExclusive(
CondARM32::Cond Cond) { CondARM32::Cond Cond) {
auto *Retry = Context.insert<InstARM32Label>(this); auto *Retry = Context.insert<InstARM32Label>(this);
{ // scoping for loop highlighting. { // scoping for loop highlighting.
Variable *Success = makeReg(IceType_i32);
Variable *Tmp = (Ty == IceType_i64) ? makeI64RegPair() : makeReg(Ty); Variable *Tmp = (Ty == IceType_i64) ? makeI64RegPair() : makeReg(Ty);
auto *Success = makeReg(IceType_i32);
auto *_0 = Ctx->getConstantZero(IceType_i32); auto *_0 = Ctx->getConstantZero(IceType_i32);
Context.insert<InstFakeDef>(Tmp); Context.insert<InstFakeDef>(Tmp);
...@@ -4614,9 +4616,19 @@ void TargetARM32::lowerLoadLinkedStoreExclusive( ...@@ -4614,9 +4616,19 @@ void TargetARM32::lowerLoadLinkedStoreExclusive(
_ldrex(Tmp, formMemoryOperand(AddrR, Ty))->setDestRedefined(); _ldrex(Tmp, formMemoryOperand(AddrR, Ty))->setDestRedefined();
auto *StoreValue = Operation(Tmp); auto *StoreValue = Operation(Tmp);
assert(StoreValue->mustHaveReg()); assert(StoreValue->mustHaveReg());
_strex(Success, StoreValue, formMemoryOperand(AddrR, Ty), Cond); // strex requires Dest to be a register other than Value or Addr. This
_cmp(Success, _0, Cond); // 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); _br(Retry, CondARM32::NE);
} }
...@@ -4887,6 +4899,8 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4887,6 +4899,8 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
} }
if (DestTy == IceType_i64) { if (DestTy == IceType_i64) {
Variable *LoadedValue = nullptr;
auto *New = makeI64RegPair(); auto *New = makeI64RegPair();
Context.insert<InstFakeDef>(New); Context.insert<InstFakeDef>(New);
lowerAssign(InstAssign::create(Func, New, Instr->getArg(2))); lowerAssign(InstAssign::create(Func, New, Instr->getArg(2)));
...@@ -4898,26 +4912,21 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4898,26 +4912,21 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
_dmb(); _dmb();
lowerLoadLinkedStoreExclusive( lowerLoadLinkedStoreExclusive(
DestTy, Instr->getArg(0), 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 *ExpectedLoR = llvm::cast<Variable>(loOperand(Expected));
auto *ExpectedHiR = llvm::cast<Variable>(hiOperand(Expected)); auto *ExpectedHiR = llvm::cast<Variable>(hiOperand(Expected));
auto *TmpLoR = llvm::cast<Variable>(loOperand(Tmp)); auto *TmpLoR = llvm::cast<Variable>(loOperand(Tmp));
auto *TmpHiR = llvm::cast<Variable>(hiOperand(Tmp)); auto *TmpHiR = llvm::cast<Variable>(hiOperand(Tmp));
_cmp(TmpLoR, ExpectedLoR); _cmp(TmpLoR, ExpectedLoR);
_cmp(TmpHiR, ExpectedHiR, CondARM32::EQ); _cmp(TmpHiR, ExpectedHiR, CondARM32::EQ);
// Adding an explicit use of Tmp here, or its live range will not LoadedValue = Tmp;
// 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);
return New; return New;
}, },
CondARM32::EQ); CondARM32::EQ);
_dmb(); _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) // The fake-use Expected prevents the assignments to Expected (above)
// from being removed if Dest is not used. // from being removed if Dest is not used.
Context.insert<InstFakeUse>(Expected); Context.insert<InstFakeUse>(Expected);
...@@ -4929,18 +4938,20 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4929,18 +4938,20 @@ void TargetARM32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
auto *New = legalizeToReg(Instr->getArg(2)); auto *New = legalizeToReg(Instr->getArg(2));
auto *Expected = legalizeToReg(Instr->getArg(1)); auto *Expected = legalizeToReg(Instr->getArg(1));
Variable *LoadedValue = nullptr;
_dmb(); _dmb();
lowerLoadLinkedStoreExclusive( lowerLoadLinkedStoreExclusive(
DestTy, DestTy, Instr->getArg(0),
Instr->getArg(0), [this, Expected, New, Instr, DestTy](Variable *Tmp) { [this, Expected, New, Instr, DestTy, &LoadedValue](Variable *Tmp) {
lowerIcmpCond(InstIcmp::Eq, Tmp, Expected); lowerIcmpCond(InstIcmp::Eq, Tmp, Expected);
_mov_redefined(Expected, Tmp); LoadedValue = Tmp;
return New; return New;
}, CondARM32::EQ); },
CondARM32::EQ);
_dmb(); _dmb();
lowerAssign(InstAssign::create(Func, Dest, Expected)); lowerAssign(InstAssign::create(Func, Dest, LoadedValue));
Context.insert<InstFakeUse>(Expected); Context.insert<InstFakeUse>(Expected);
Context.insert<InstFakeUse>(New); Context.insert<InstFakeUse>(New);
return; return;
......
...@@ -785,18 +785,13 @@ protected: ...@@ -785,18 +785,13 @@ protected:
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
Context.insert<InstARM32Str>(Value, Addr, Pred); Context.insert<InstARM32Str>(Value, Addr, Pred);
} }
void _strex(Variable *Dest, Variable *Value, OperandARM32Mem *Addr, InstARM32Strex *_strex(Variable *Dest, Variable *Value, OperandARM32Mem *Addr,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
// 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>(Dest);
if (auto *Value64 = llvm::dyn_cast<Variable64On32>(Value)) { if (auto *Value64 = llvm::dyn_cast<Variable64On32>(Value)) {
Context.insert<InstFakeUse>(Value64->getLo()); Context.insert<InstFakeUse>(Value64->getLo());
Context.insert<InstFakeUse>(Value64->getHi()); Context.insert<InstFakeUse>(Value64->getHi());
} }
auto *Instr = Context.insert<InstARM32Strex>(Dest, Value, Addr, Pred); return Context.insert<InstARM32Strex>(Dest, Value, Addr, Pred);
Instr->setDestRedefined();
} }
void _sub(Variable *Dest, Variable *Src0, Operand *Src1, void _sub(Variable *Dest, Variable *Src0, Operand *Src1,
CondARM32::Cond Pred = CondARM32::AL) { CondARM32::Cond Pred = CondARM32::AL) {
......
...@@ -1065,11 +1065,12 @@ entry: ...@@ -1065,11 +1065,12 @@ entry:
; CHECK: lock cmpxchg BYTE PTR [e{{[^a].}}],{{[^a]}}l ; CHECK: lock cmpxchg BYTE PTR [e{{[^a].}}],{{[^a]}}l
; ARM32-LABEL: test_atomic_cmpxchg_8 ; ARM32-LABEL: test_atomic_cmpxchg_8
; ARM32: dmb ; ARM32: dmb
; ARM32: ldrexb ; ARM32: ldrexb [[V:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}}
; ARM32: cmp ; ARM32: lsl [[VV:r[0-9]+]], [[V]], #24
; ARM32: {{strb|mov}} ; ARM32: cmp [[VV]], {{r[0-9]+}}, lsl #24
; ARM32: strexbeq ; ARM32: movne [[SUCCESS:r[0-9]+]],
; ARM32: cmpeq ; ARM32: strexbeq [[SUCCESS]], {{r[0-9]+}}, {{[[]}}[[A]]{{[]]}}
; ARM32: cmp [[SUCCESS]], #0
; ARM32: bne ; ARM32: bne
; ARM32: dmb ; ARM32: dmb
...@@ -1089,11 +1090,12 @@ entry: ...@@ -1089,11 +1090,12 @@ entry:
; CHECK: lock cmpxchg WORD PTR [e{{[^a].}}],{{[^a]}}x ; CHECK: lock cmpxchg WORD PTR [e{{[^a].}}],{{[^a]}}x
; ARM32-LABEL: test_atomic_cmpxchg_16 ; ARM32-LABEL: test_atomic_cmpxchg_16
; ARM32: dmb ; ARM32: dmb
; ARM32: ldrexh ; ARM32: ldrexh [[V:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}}
; ARM32: cmp ; ARM32: lsl [[VV:r[0-9]+]], [[V]], #16
; ARM32: {{strh|mov}} ; ARM32: cmp [[VV]], {{r[0-9]+}}, lsl #16
; ARM32: strexheq ; ARM32: movne [[SUCCESS:r[0-9]+]],
; ARM32: cmpeq ; ARM32: strexheq [[SUCCESS]], {{r[0-9]+}}, {{[[]}}[[A]]{{[]]}}
; ARM32: cmp [[SUCCESS]], #0
; ARM32: bne ; ARM32: bne
; ARM32: dmb ; ARM32: dmb
...@@ -1110,11 +1112,11 @@ entry: ...@@ -1110,11 +1112,11 @@ entry:
; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}],e{{[^a]}} ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}],e{{[^a]}}
; ARM32-LABEL: test_atomic_cmpxchg_32 ; ARM32-LABEL: test_atomic_cmpxchg_32
; ARM32: dmb ; ARM32: dmb
; ARM32: ldrex ; ARM32: ldrex [[V:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}}
; ARM32: cmp ; ARM32: cmp [[V]], {{r[0-9]+}}
; ARM32: {{str|mov}} ; ARM32: movne [[SUCCESS:r[0-9]+]],
; ARM32: strexeq ; ARM32: strexeq [[SUCCESS]], {{r[0-9]+}}, {{[[]}}[[A]]{{[]]}}
; ARM32: cmpeq ; ARM32: cmp [[SUCCESS]], #0
; ARM32: bne ; ARM32: bne
; ARM32: dmb ; ARM32: dmb
...@@ -1138,13 +1140,12 @@ entry: ...@@ -1138,13 +1140,12 @@ entry:
; somewhere, so in that case they do need to be mov'ed. ; somewhere, so in that case they do need to be mov'ed.
; ARM32-LABEL: test_atomic_cmpxchg_64 ; ARM32-LABEL: test_atomic_cmpxchg_64
; ARM32: dmb ; ARM32: dmb
; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}}
; ARM32: cmp ; ARM32: cmp [[V0]], {{r[0-9]+}}
; ARM32: cmpeq ; ARM32: cmpeq [[V1]], {{r[0-9]+}}
; ARM32: mov ; ARM32: movne [[SUCCESS:r[0-9]+]],
; ARM32: mov ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[A]]{{[]]}}
; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} ; ARM32: cmp [[SUCCESS]], #0
; ARM32: cmpeq
; ARM32: bne ; ARM32: bne
; ARM32: dmb ; ARM32: dmb
...@@ -1161,13 +1162,12 @@ entry: ...@@ -1161,13 +1162,12 @@ entry:
; ARM32: mov r{{[0-9]+}}, #0 ; ARM32: mov r{{[0-9]+}}, #0
; ARM32: mov r{{[0-9]+}}, #0 ; ARM32: mov r{{[0-9]+}}, #0
; ARM32: dmb ; ARM32: dmb
; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}}
; ARM32: cmp ; ARM32: cmp [[V0]], {{r[0-9]+}}
; ARM32: cmpeq ; ARM32: cmpeq [[V1]], {{r[0-9]+}}
; ARM32: mov ; ARM32: movne [[SUCCESS:r[0-9]+]],
; ARM32: mov ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[A]]{{[]]}}
; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} ; ARM32: cmp [[SUCCESS]], #0
; ARM32: cmpeq
; ARM32: bne ; ARM32: bne
; ARM32: dmb ; ARM32: dmb
...@@ -1193,13 +1193,12 @@ entry: ...@@ -1193,13 +1193,12 @@ entry:
; CHECK-DAG: mov {{.*}},eax ; CHECK-DAG: mov {{.*}},eax
; ARM32-LABEL: test_atomic_cmpxchg_64_store ; ARM32-LABEL: test_atomic_cmpxchg_64_store
; ARM32: dmb ; ARM32: dmb
; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}}
; ARM32: cmp ; ARM32: cmp [[V0]], {{r[0-9]+}}
; ARM32: cmpeq ; ARM32: cmpeq [[V1]], {{r[0-9]+}}
; ARM32: mov ; ARM32: movne [[SUCCESS:r[0-9]+]],
; ARM32: mov ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[A]]{{[]]}}
; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} ; ARM32: cmp [[SUCCESS]], #0
; ARM32: cmpeq
; ARM32: bne ; ARM32: bne
; ARM32: dmb ; ARM32: dmb
; ARM32: str ; ARM32: str
...@@ -1239,13 +1238,12 @@ eblock: ...@@ -1239,13 +1238,12 @@ eblock:
; CHECK: call {{.*}} R_{{.*}} use_ptr ; CHECK: call {{.*}} R_{{.*}} use_ptr
; ARM32-LABEL: test_atomic_cmpxchg_64_alloca ; ARM32-LABEL: test_atomic_cmpxchg_64_alloca
; ARM32: dmb ; ARM32: dmb
; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}}
; ARM32: cmp ; ARM32: cmp [[V0]], {{r[0-9]+}}
; ARM32: cmpeq ; ARM32: cmpeq [[V1]], {{r[0-9]+}}
; ARM32: mov ; ARM32: movne [[SUCCESS:r[0-9]+]],
; ARM32: mov ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[A]]{{[]]}}
; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} ; ARM32: cmp [[SUCCESS]], #0
; ARM32: cmpeq
; ARM32: bne ; ARM32: bne
; ARM32: dmb ; ARM32: dmb
...@@ -1262,10 +1260,11 @@ entry: ...@@ -1262,10 +1260,11 @@ entry:
; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}] ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}]
; ARM32-LABEL: test_atomic_cmpxchg_32_ignored ; ARM32-LABEL: test_atomic_cmpxchg_32_ignored
; ARM32: dmb ; ARM32: dmb
; ARM32: ldrex ; ARM32: ldrex [[V:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}}
; ARM32: cmp ; ARM32: cmp [[V]], {{r[0-9]+}}
; ARM32: strexeq ; ARM32: movne [[SUCCESS:r[0-9]+]],
; ARM32: cmpeq ; ARM32: strexeq [[SUCCESS]]
; ARM32: cmp [[SUCCESS]], #0
; ARM32: bne ; ARM32: bne
; ARM32: dmb ; ARM32: dmb
...@@ -1286,13 +1285,12 @@ entry: ...@@ -1286,13 +1285,12 @@ entry:
; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0]
; ARM32-LABEL: test_atomic_cmpxchg_64_ignored ; ARM32-LABEL: test_atomic_cmpxchg_64_ignored
; ARM32: dmb ; ARM32: dmb
; ARM32: ldrexd [[R0:r[0-9]+]], [[R1:r[0-9]+]], {{[[]}}[[PTR:r[0-9]+]]{{[]]}} ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}}
; ARM32: cmp ; ARM32: cmp [[V0]], {{r[0-9]+}}
; ARM32-NEXT: cmpeq ; ARM32: cmpeq [[V1]], {{r[0-9]+}}
; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} ; ARM32: movne [[SUCCESS:r[0-9]+]],
; ARM32O2-NOT: {{str|mov}}ne [[R0]] ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}}
; ARM32O2-NOT: {{str|mov}}ne [[R1]] ; ARM32: cmp [[SUCCESS]], #0
; ARM32: cmpeq
; ARM32: bne ; ARM32: bne
; ARM32: dmb ; ARM32: dmb
......
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