Commit a1cdd57e by John Porto

Subzero. ARM32. Fixes bugs uncovered by the gcc torture tests.

parent 3d5e08dc
...@@ -2729,7 +2729,7 @@ void TargetARM32::lowerInt64Arithmetic(InstArithmetic::OpKind Op, ...@@ -2729,7 +2729,7 @@ void TargetARM32::lowerInt64Arithmetic(InstArithmetic::OpKind Op,
Variable *T2 = makeReg(IceType_i32); Variable *T2 = makeReg(IceType_i32);
Variable *TA_Hi = makeReg(IceType_i32); Variable *TA_Hi = makeReg(IceType_i32);
Variable *TA_Lo = makeReg(IceType_i32); Variable *TA_Lo = makeReg(IceType_i32);
Variable *Src0RLo = SrcsLo.src0R(this); Variable *Src0RLo = SrcsLo.unswappedSrc0R(this);
Variable *Src0RHi = SrcsHi.unswappedSrc0R(this); Variable *Src0RHi = SrcsHi.unswappedSrc0R(this);
Variable *Src1RLo = SrcsLo.unswappedSrc1R(this); Variable *Src1RLo = SrcsLo.unswappedSrc1R(this);
_rsb(T0, Src1RLo, _32); _rsb(T0, Src1RLo, _32);
...@@ -6488,7 +6488,7 @@ void TargetARM32::ComputationTracker::recordProducers(CfgNode *Node) { ...@@ -6488,7 +6488,7 @@ void TargetARM32::ComputationTracker::recordProducers(CfgNode *Node) {
TargetARM32::Sandboxer::Sandboxer(TargetARM32 *Target, TargetARM32::Sandboxer::Sandboxer(TargetARM32 *Target,
InstBundleLock::Option BundleOption) InstBundleLock::Option BundleOption)
: Bundler(Target, BundleOption), Target(Target) {} : Target(Target), BundleOption(BundleOption) {}
TargetARM32::Sandboxer::~Sandboxer() {} TargetARM32::Sandboxer::~Sandboxer() {}
...@@ -6511,25 +6511,36 @@ static bool baseNeedsBic(Variable *Base) { ...@@ -6511,25 +6511,36 @@ static bool baseNeedsBic(Variable *Base) {
} }
} // end of anonymous namespace } // end of anonymous namespace
void TargetARM32::Sandboxer::createAutoBundle() {
Bundler = makeUnique<AutoBundle>(Target, BundleOption);
}
void TargetARM32::Sandboxer::add_sp(Operand *AddAmount) { void TargetARM32::Sandboxer::add_sp(Operand *AddAmount) {
Variable *SP = Target->getPhysicalRegister(RegARM32::Reg_sp); Variable *SP = Target->getPhysicalRegister(RegARM32::Reg_sp);
Target->_add(SP, SP, AddAmount); if (!Target->NeedSandboxing) {
if (Target->NeedSandboxing) { Target->_add(SP, SP, AddAmount);
Target->_bic(SP, SP, memOpBicMask(Target->Func)); return;
} }
createAutoBundle();
Target->_add(SP, SP, AddAmount);
Target->_bic(SP, SP, memOpBicMask(Target->Func));
} }
void TargetARM32::Sandboxer::align_sp(size_t Alignment) { void TargetARM32::Sandboxer::align_sp(size_t Alignment) {
Variable *SP = Target->getPhysicalRegister(RegARM32::Reg_sp); Variable *SP = Target->getPhysicalRegister(RegARM32::Reg_sp);
Target->alignRegisterPow2(SP, Alignment); if (!Target->NeedSandboxing) {
if (Target->NeedSandboxing) { Target->alignRegisterPow2(SP, Alignment);
Target->_bic(SP, SP, memOpBicMask(Target->Func)); return;
} }
createAutoBundle();
Target->alignRegisterPow2(SP, Alignment);
Target->_bic(SP, SP, memOpBicMask(Target->Func));
} }
InstARM32Call *TargetARM32::Sandboxer::bl(Variable *ReturnReg, InstARM32Call *TargetARM32::Sandboxer::bl(Variable *ReturnReg,
Operand *CallTarget) { Operand *CallTarget) {
if (Target->NeedSandboxing) { if (Target->NeedSandboxing) {
createAutoBundle();
if (auto *CallTargetR = llvm::dyn_cast<Variable>(CallTarget)) { if (auto *CallTargetR = llvm::dyn_cast<Variable>(CallTarget)) {
Target->_bic(CallTargetR, CallTargetR, Target->_bic(CallTargetR, CallTargetR,
indirectBranchBicMask(Target->Func)); indirectBranchBicMask(Target->Func));
...@@ -6542,6 +6553,7 @@ void TargetARM32::Sandboxer::ldr(Variable *Dest, OperandARM32Mem *Mem, ...@@ -6542,6 +6553,7 @@ void TargetARM32::Sandboxer::ldr(Variable *Dest, OperandARM32Mem *Mem,
CondARM32::Cond Pred) { CondARM32::Cond Pred) {
Variable *MemBase = Mem->getBase(); Variable *MemBase = Mem->getBase();
if (Target->NeedSandboxing && baseNeedsBic(MemBase)) { if (Target->NeedSandboxing && baseNeedsBic(MemBase)) {
createAutoBundle();
assert(!Mem->isRegReg()); assert(!Mem->isRegReg());
Target->_bic(MemBase, MemBase, memOpBicMask(Target->Func), Pred); Target->_bic(MemBase, MemBase, memOpBicMask(Target->Func), Pred);
} }
...@@ -6552,6 +6564,7 @@ void TargetARM32::Sandboxer::ldrex(Variable *Dest, OperandARM32Mem *Mem, ...@@ -6552,6 +6564,7 @@ void TargetARM32::Sandboxer::ldrex(Variable *Dest, OperandARM32Mem *Mem,
CondARM32::Cond Pred) { CondARM32::Cond Pred) {
Variable *MemBase = Mem->getBase(); Variable *MemBase = Mem->getBase();
if (Target->NeedSandboxing && baseNeedsBic(MemBase)) { if (Target->NeedSandboxing && baseNeedsBic(MemBase)) {
createAutoBundle();
assert(!Mem->isRegReg()); assert(!Mem->isRegReg());
Target->_bic(MemBase, MemBase, memOpBicMask(Target->Func), Pred); Target->_bic(MemBase, MemBase, memOpBicMask(Target->Func), Pred);
} }
...@@ -6560,14 +6573,18 @@ void TargetARM32::Sandboxer::ldrex(Variable *Dest, OperandARM32Mem *Mem, ...@@ -6560,14 +6573,18 @@ void TargetARM32::Sandboxer::ldrex(Variable *Dest, OperandARM32Mem *Mem,
void TargetARM32::Sandboxer::reset_sp(Variable *Src) { void TargetARM32::Sandboxer::reset_sp(Variable *Src) {
Variable *SP = Target->getPhysicalRegister(RegARM32::Reg_sp); Variable *SP = Target->getPhysicalRegister(RegARM32::Reg_sp);
Target->_mov_redefined(SP, Src); if (!Target->NeedSandboxing) {
if (Target->NeedSandboxing) { Target->_mov_redefined(SP, Src);
Target->_bic(SP, SP, memOpBicMask(Target->Func)); return;
} }
createAutoBundle();
Target->_mov_redefined(SP, Src);
Target->_bic(SP, SP, memOpBicMask(Target->Func));
} }
void TargetARM32::Sandboxer::ret(Variable *RetAddr, Variable *RetValue) { void TargetARM32::Sandboxer::ret(Variable *RetAddr, Variable *RetValue) {
if (Target->NeedSandboxing) { if (Target->NeedSandboxing) {
createAutoBundle();
Target->_bic(RetAddr, RetAddr, indirectBranchBicMask(Target->Func)); Target->_bic(RetAddr, RetAddr, indirectBranchBicMask(Target->Func));
} }
Target->_ret(RetAddr, RetValue); Target->_ret(RetAddr, RetValue);
...@@ -6577,6 +6594,7 @@ void TargetARM32::Sandboxer::str(Variable *Src, OperandARM32Mem *Mem, ...@@ -6577,6 +6594,7 @@ void TargetARM32::Sandboxer::str(Variable *Src, OperandARM32Mem *Mem,
CondARM32::Cond Pred) { CondARM32::Cond Pred) {
Variable *MemBase = Mem->getBase(); Variable *MemBase = Mem->getBase();
if (Target->NeedSandboxing && baseNeedsBic(MemBase)) { if (Target->NeedSandboxing && baseNeedsBic(MemBase)) {
createAutoBundle();
assert(!Mem->isRegReg()); assert(!Mem->isRegReg());
Target->_bic(MemBase, MemBase, memOpBicMask(Target->Func), Pred); Target->_bic(MemBase, MemBase, memOpBicMask(Target->Func), Pred);
} }
...@@ -6587,6 +6605,7 @@ void TargetARM32::Sandboxer::strex(Variable *Dest, Variable *Src, ...@@ -6587,6 +6605,7 @@ void TargetARM32::Sandboxer::strex(Variable *Dest, Variable *Src,
OperandARM32Mem *Mem, CondARM32::Cond Pred) { OperandARM32Mem *Mem, CondARM32::Cond Pred) {
Variable *MemBase = Mem->getBase(); Variable *MemBase = Mem->getBase();
if (Target->NeedSandboxing && baseNeedsBic(MemBase)) { if (Target->NeedSandboxing && baseNeedsBic(MemBase)) {
createAutoBundle();
assert(!Mem->isRegReg()); assert(!Mem->isRegReg());
Target->_bic(MemBase, MemBase, memOpBicMask(Target->Func), Pred); Target->_bic(MemBase, MemBase, memOpBicMask(Target->Func), Pred);
} }
...@@ -6595,10 +6614,13 @@ void TargetARM32::Sandboxer::strex(Variable *Dest, Variable *Src, ...@@ -6595,10 +6614,13 @@ void TargetARM32::Sandboxer::strex(Variable *Dest, Variable *Src,
void TargetARM32::Sandboxer::sub_sp(Operand *SubAmount) { void TargetARM32::Sandboxer::sub_sp(Operand *SubAmount) {
Variable *SP = Target->getPhysicalRegister(RegARM32::Reg_sp); Variable *SP = Target->getPhysicalRegister(RegARM32::Reg_sp);
Target->_sub(SP, SP, SubAmount); if (!Target->NeedSandboxing) {
if (Target->NeedSandboxing) { Target->_sub(SP, SP, SubAmount);
Target->_bic(SP, SP, memOpBicMask(Target->Func)); return;
} }
createAutoBundle();
Target->_sub(SP, SP, SubAmount);
Target->_bic(SP, SP, memOpBicMask(Target->Func));
} }
TargetDataARM32::TargetDataARM32(GlobalContext *Ctx) TargetDataARM32::TargetDataARM32(GlobalContext *Ctx)
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#include "IceRegistersARM32.h" #include "IceRegistersARM32.h"
#include "IceTargetLowering.h" #include "IceTargetLowering.h"
#include <utility>
namespace Ice { namespace Ice {
namespace ARM32 { namespace ARM32 {
...@@ -802,10 +804,14 @@ protected: ...@@ -802,10 +804,14 @@ protected:
} }
void _umull(Variable *DestLo, Variable *DestHi, Variable *Src0, void _umull(Variable *DestLo, Variable *DestHi, Variable *Src0,
Variable *Src1, CondARM32::Cond Pred = CondARM32::AL) { Variable *Src1, CondARM32::Cond Pred = CondARM32::AL) {
// umull requires DestLo and DestHi to be assigned to different GPRs. The
// following lines create overlapping liveness ranges for both variables. If
// either one of them is live, then they are both going to be live, and thus
// assigned to different registers; if they are both dead, then DCE will
// kick in and delete the following three instructions.
Context.insert<InstFakeDef>(DestHi);
Context.insert<InstARM32Umull>(DestLo, DestHi, Src0, Src1, Pred); Context.insert<InstARM32Umull>(DestLo, DestHi, Src0, Src1, Pred);
// Model the modification to the second dest as a fake def. Note that the Context.insert<InstFakeDef>(DestHi, DestLo)->setDestRedefined();
// def is not predicated.
Context.insert<InstFakeDef>(DestHi, DestLo);
Context.insert<InstFakeUse>(DestHi); Context.insert<InstFakeUse>(DestHi);
} }
void _uxt(Variable *Dest, Variable *Src0, void _uxt(Variable *Dest, Variable *Src0,
...@@ -1040,8 +1046,11 @@ protected: ...@@ -1040,8 +1046,11 @@ protected:
void sub_sp(Operand *SubAmount); void sub_sp(Operand *SubAmount);
private: private:
AutoBundle Bundler; TargetARM32 *const Target;
TargetARM32 *Target; const InstBundleLock::Option BundleOption;
std::unique_ptr<AutoBundle> Bundler;
void createAutoBundle();
}; };
class PostLoweringLegalizer { class PostLoweringLegalizer {
......
...@@ -26,18 +26,12 @@ define internal i32 @MulTwoRegs(i32 %a, i32 %b) { ...@@ -26,18 +26,12 @@ define internal i32 @MulTwoRegs(i32 %a, i32 %b) {
} }
; ASM-LABEL:MulTwoRegs: ; ASM-LABEL:MulTwoRegs:
; ASM-NEXT:.LMulTwoRegs$__0: ; DIS-LABEL:<MulTwoRegs>:
; ASM-NEXT: mul r0, r0, r1
; DIS-LABEL:00000000 <MulTwoRegs>:
; DIS-NEXT: 0: e0000190
; IASM-LABEL:MulTwoRegs: ; IASM-LABEL:MulTwoRegs:
; IASM-NEXT:.LMulTwoRegs$__0:
; IASM-NEXT: .byte 0x90 ; ASM: mul r0, r0, r1
; IASM-NEXT: .byte 0x1 ; DIS: e0000190
; IASM-NEXT: .byte 0x0 ; IASM-NOT: mul
; IASM-NEXT: .byte 0xe0
define internal i64 @MulTwoI64Regs(i64 %a, i64 %b) { define internal i64 @MulTwoI64Regs(i64 %a, i64 %b) {
%v = mul i64 %a, %b %v = mul i64 %a, %b
...@@ -45,52 +39,22 @@ define internal i64 @MulTwoI64Regs(i64 %a, i64 %b) { ...@@ -45,52 +39,22 @@ define internal i64 @MulTwoI64Regs(i64 %a, i64 %b) {
} }
; ASM-LABEL:MulTwoI64Regs: ; ASM-LABEL:MulTwoI64Regs:
; ASM-NEXT:.LMulTwoI64Regs$__0: ; DIS-LABEL:<MulTwoI64Regs>:
; ASM-NEXT: mul r3, r0, r3
; ASM-NEXT: mla r1, r2, r1, r3
; ASM-NEXT: umull r0, r2, r0, r2
; ASM-NEXT: # r2 = def.pseudo r0
; ASM-NEXT: add r2, r2, r1
; ASM-NEXT: mov r1, r2
; ASM-NEXT: bx lr
; DIS-LABEL:00000010 <MulTwoI64Regs>:
; DIS-NEXT: 10: e0030390
; DIS-NEXT: 14: e0213192
; DIS-NEXT: 18: e0820290
; DIS-NEXT: 1c: e0822001
; DIS-NEXT: 20: e1a01002
; DIS-NEXT: 24: e12fff1e
; IASM-LABEL:MulTwoI64Regs: ; IASM-LABEL:MulTwoI64Regs:
; IASM-NEXT:.LMulTwoI64Regs$__0:
; IASM-NEXT: .byte 0x90
; IASM-NEXT: .byte 0x3
; IASM-NEXT: .byte 0x3
; IASM-NEXT: .byte 0xe0
; IASM-NEXT: .byte 0x92
; IASM-NEXT: .byte 0x31
; IASM-NEXT: .byte 0x21
; IASM-NEXT: .byte 0xe0
; IASM-NEXT: .byte 0x90
; IASM-NEXT: .byte 0x2
; IASM-NEXT: .byte 0x82
; IASM-NEXT: .byte 0xe0
; IASM-NEXT: .byte 0x1 ; ASM: mul r3, r0, r3
; IASM-NEXT: .byte 0x20 ; ASM-NEXT: mla r1, r2, r1, r3
; IASM-NEXT: .byte 0x82 ; ASM-NEXT: # r3 = def.pseudo
; IASM-NEXT: .byte 0xe0 ; ASM-NEXT: umull r0, r3, r0, r2
; ASM-NEXT: # r3 = def.pseudo r0
; IASM-NEXT: .byte 0x2 ; ASM-NEXT: add r3, r3, r1
; IASM-NEXT: .byte 0x10
; IASM-NEXT: .byte 0xa0 ; DIS: e0030390
; IASM-NEXT: .byte 0xe1 ; DIS-NEXT: e0213192
; DIS-NEXT: e0830290
; IASM-NEXT: .byte 0x1e ; DIS-NEXT: e0833001
; IASM-NEXT: .byte 0xff
; IASM-NEXT: .byte 0x2f ; IASM-NOT: mul
; IASM-NEXT: .byte 0xe1 ; IASM-NOT: mla
; IASM-NOT: umull
; IASM-NOT: add
...@@ -149,31 +149,39 @@ entry: ...@@ -149,31 +149,39 @@ entry:
; ARM110P2-NEXT: .bundle_unlock ; ARM110P2-NEXT: .bundle_unlock
; ARM110P2-NEXT: nop ; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop ; ARM110P2-NEXT: nop
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: add ip, sp, #32 ; ARM110P2-NEXT: add ip, sp, #32
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: bic ip, ip, #3221225472 ; ARM110P2-NEXT: bic ip, ip, #3221225472
; ARM110P2-NEXT: vst1.32 q0, [ip] ; ARM110P2-NEXT: vst1.32 q0, [ip]
; ARM110P2-NEXT: .bundle_unlock ; ARM110P2-NEXT: .bundle_unlock
; ARM110P2-NEXT: nop ; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop ; ARM110P2-NEXT: nop
; ARM110P2-NEXT: # [sp, #32] = def.pseudo ; ARM110P2-NEXT: # [sp, #32] = def.pseudo
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: add ip, sp, #16 ; ARM110P2-NEXT: add ip, sp, #16
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: bic ip, ip, #3221225472 ; ARM110P2-NEXT: bic ip, ip, #3221225472
; ARM110P2-NEXT: vst1.32 q1, [ip] ; ARM110P2-NEXT: vst1.32 q1, [ip]
; ARM110P2-NEXT: .bundle_unlock ; ARM110P2-NEXT: .bundle_unlock
; ARM110P2-NEXT: nop ; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop ; ARM110P2-NEXT: nop
; ARM110P2-NEXT: # [sp, #16] = def.pseudo ; ARM110P2-NEXT: # [sp, #16] = def.pseudo
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: add ip, sp, #32 ; ARM110P2-NEXT: add ip, sp, #32
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: bic ip, ip, #3221225472 ; ARM110P2-NEXT: bic ip, ip, #3221225472
; ARM110P2-NEXT: vld1.32 q0, [ip] ; ARM110P2-NEXT: vld1.32 q0, [ip]
; ARM110P2-NEXT: .bundle_unlock ; ARM110P2-NEXT: .bundle_unlock
; ARM110P2-NEXT: nop ; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop ; ARM110P2-NEXT: nop
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: add ip, sp, #16 ; ARM110P2-NEXT: add ip, sp, #16
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: bic ip, ip, #3221225472 ; ARM110P2-NEXT: bic ip, ip, #3221225472
; ARM110P2-NEXT: vld1.32 q1, [ip] ; ARM110P2-NEXT: vld1.32 q1, [ip]
; ARM110P2-NEXT: .bundle_unlock ; ARM110P2-NEXT: .bundle_unlock
...@@ -182,15 +190,11 @@ entry: ...@@ -182,15 +190,11 @@ entry:
; ARM110P2-NEXT: vmul.i32 q0, q0, q1 ; ARM110P2-NEXT: vmul.i32 q0, q0, q1
; ARM110P2-NEXT: nop ; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop ; ARM110P2-NEXT: nop
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: vst1.32 q0, [sp] ; ARM110P2-NEXT: vst1.32 q0, [sp]
; ARM110P2-NEXT: .bundle_unlock
; ARM110P2-NEXT: nop ; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop ; ARM110P2-NEXT: nop
; ARM110P2-NEXT: # [sp] = def.pseudo ; ARM110P2-NEXT: # [sp] = def.pseudo
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: vld1.32 q0, [sp] ; ARM110P2-NEXT: vld1.32 q0, [sp]
; ARM110P2-NEXT: .bundle_unlock
; ARM110P2-NEXT: nop ; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop ; ARM110P2-NEXT: nop
; ARM110P2-NEXT: .bundle_lock ; ARM110P2-NEXT: .bundle_lock
......
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