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,
Variable *T2 = makeReg(IceType_i32);
Variable *TA_Hi = 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 *Src1RLo = SrcsLo.unswappedSrc1R(this);
_rsb(T0, Src1RLo, _32);
......@@ -6488,7 +6488,7 @@ void TargetARM32::ComputationTracker::recordProducers(CfgNode *Node) {
TargetARM32::Sandboxer::Sandboxer(TargetARM32 *Target,
InstBundleLock::Option BundleOption)
: Bundler(Target, BundleOption), Target(Target) {}
: Target(Target), BundleOption(BundleOption) {}
TargetARM32::Sandboxer::~Sandboxer() {}
......@@ -6511,25 +6511,36 @@ static bool baseNeedsBic(Variable *Base) {
}
} // end of anonymous namespace
void TargetARM32::Sandboxer::createAutoBundle() {
Bundler = makeUnique<AutoBundle>(Target, BundleOption);
}
void TargetARM32::Sandboxer::add_sp(Operand *AddAmount) {
Variable *SP = Target->getPhysicalRegister(RegARM32::Reg_sp);
Target->_add(SP, SP, AddAmount);
if (Target->NeedSandboxing) {
Target->_bic(SP, SP, memOpBicMask(Target->Func));
if (!Target->NeedSandboxing) {
Target->_add(SP, SP, AddAmount);
return;
}
createAutoBundle();
Target->_add(SP, SP, AddAmount);
Target->_bic(SP, SP, memOpBicMask(Target->Func));
}
void TargetARM32::Sandboxer::align_sp(size_t Alignment) {
Variable *SP = Target->getPhysicalRegister(RegARM32::Reg_sp);
Target->alignRegisterPow2(SP, Alignment);
if (Target->NeedSandboxing) {
Target->_bic(SP, SP, memOpBicMask(Target->Func));
if (!Target->NeedSandboxing) {
Target->alignRegisterPow2(SP, Alignment);
return;
}
createAutoBundle();
Target->alignRegisterPow2(SP, Alignment);
Target->_bic(SP, SP, memOpBicMask(Target->Func));
}
InstARM32Call *TargetARM32::Sandboxer::bl(Variable *ReturnReg,
Operand *CallTarget) {
if (Target->NeedSandboxing) {
createAutoBundle();
if (auto *CallTargetR = llvm::dyn_cast<Variable>(CallTarget)) {
Target->_bic(CallTargetR, CallTargetR,
indirectBranchBicMask(Target->Func));
......@@ -6542,6 +6553,7 @@ void TargetARM32::Sandboxer::ldr(Variable *Dest, OperandARM32Mem *Mem,
CondARM32::Cond Pred) {
Variable *MemBase = Mem->getBase();
if (Target->NeedSandboxing && baseNeedsBic(MemBase)) {
createAutoBundle();
assert(!Mem->isRegReg());
Target->_bic(MemBase, MemBase, memOpBicMask(Target->Func), Pred);
}
......@@ -6552,6 +6564,7 @@ void TargetARM32::Sandboxer::ldrex(Variable *Dest, OperandARM32Mem *Mem,
CondARM32::Cond Pred) {
Variable *MemBase = Mem->getBase();
if (Target->NeedSandboxing && baseNeedsBic(MemBase)) {
createAutoBundle();
assert(!Mem->isRegReg());
Target->_bic(MemBase, MemBase, memOpBicMask(Target->Func), Pred);
}
......@@ -6560,14 +6573,18 @@ void TargetARM32::Sandboxer::ldrex(Variable *Dest, OperandARM32Mem *Mem,
void TargetARM32::Sandboxer::reset_sp(Variable *Src) {
Variable *SP = Target->getPhysicalRegister(RegARM32::Reg_sp);
Target->_mov_redefined(SP, Src);
if (Target->NeedSandboxing) {
Target->_bic(SP, SP, memOpBicMask(Target->Func));
if (!Target->NeedSandboxing) {
Target->_mov_redefined(SP, Src);
return;
}
createAutoBundle();
Target->_mov_redefined(SP, Src);
Target->_bic(SP, SP, memOpBicMask(Target->Func));
}
void TargetARM32::Sandboxer::ret(Variable *RetAddr, Variable *RetValue) {
if (Target->NeedSandboxing) {
createAutoBundle();
Target->_bic(RetAddr, RetAddr, indirectBranchBicMask(Target->Func));
}
Target->_ret(RetAddr, RetValue);
......@@ -6577,6 +6594,7 @@ void TargetARM32::Sandboxer::str(Variable *Src, OperandARM32Mem *Mem,
CondARM32::Cond Pred) {
Variable *MemBase = Mem->getBase();
if (Target->NeedSandboxing && baseNeedsBic(MemBase)) {
createAutoBundle();
assert(!Mem->isRegReg());
Target->_bic(MemBase, MemBase, memOpBicMask(Target->Func), Pred);
}
......@@ -6587,6 +6605,7 @@ void TargetARM32::Sandboxer::strex(Variable *Dest, Variable *Src,
OperandARM32Mem *Mem, CondARM32::Cond Pred) {
Variable *MemBase = Mem->getBase();
if (Target->NeedSandboxing && baseNeedsBic(MemBase)) {
createAutoBundle();
assert(!Mem->isRegReg());
Target->_bic(MemBase, MemBase, memOpBicMask(Target->Func), Pred);
}
......@@ -6595,10 +6614,13 @@ void TargetARM32::Sandboxer::strex(Variable *Dest, Variable *Src,
void TargetARM32::Sandboxer::sub_sp(Operand *SubAmount) {
Variable *SP = Target->getPhysicalRegister(RegARM32::Reg_sp);
Target->_sub(SP, SP, SubAmount);
if (Target->NeedSandboxing) {
Target->_bic(SP, SP, memOpBicMask(Target->Func));
if (!Target->NeedSandboxing) {
Target->_sub(SP, SP, SubAmount);
return;
}
createAutoBundle();
Target->_sub(SP, SP, SubAmount);
Target->_bic(SP, SP, memOpBicMask(Target->Func));
}
TargetDataARM32::TargetDataARM32(GlobalContext *Ctx)
......
......@@ -22,6 +22,8 @@
#include "IceRegistersARM32.h"
#include "IceTargetLowering.h"
#include <utility>
namespace Ice {
namespace ARM32 {
......@@ -802,10 +804,14 @@ protected:
}
void _umull(Variable *DestLo, Variable *DestHi, Variable *Src0,
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);
// Model the modification to the second dest as a fake def. Note that the
// def is not predicated.
Context.insert<InstFakeDef>(DestHi, DestLo);
Context.insert<InstFakeDef>(DestHi, DestLo)->setDestRedefined();
Context.insert<InstFakeUse>(DestHi);
}
void _uxt(Variable *Dest, Variable *Src0,
......@@ -1040,8 +1046,11 @@ protected:
void sub_sp(Operand *SubAmount);
private:
AutoBundle Bundler;
TargetARM32 *Target;
TargetARM32 *const Target;
const InstBundleLock::Option BundleOption;
std::unique_ptr<AutoBundle> Bundler;
void createAutoBundle();
};
class PostLoweringLegalizer {
......
......@@ -26,18 +26,12 @@ define internal i32 @MulTwoRegs(i32 %a, i32 %b) {
}
; ASM-LABEL:MulTwoRegs:
; ASM-NEXT:.LMulTwoRegs$__0:
; ASM-NEXT: mul r0, r0, r1
; DIS-LABEL:00000000 <MulTwoRegs>:
; DIS-NEXT: 0: e0000190
; DIS-LABEL:<MulTwoRegs>:
; IASM-LABEL:MulTwoRegs:
; IASM-NEXT:.LMulTwoRegs$__0:
; IASM-NEXT: .byte 0x90
; IASM-NEXT: .byte 0x1
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0xe0
; ASM: mul r0, r0, r1
; DIS: e0000190
; IASM-NOT: mul
define internal i64 @MulTwoI64Regs(i64 %a, i64 %b) {
%v = mul i64 %a, %b
......@@ -45,52 +39,22 @@ define internal i64 @MulTwoI64Regs(i64 %a, i64 %b) {
}
; ASM-LABEL:MulTwoI64Regs:
; ASM-NEXT:.LMulTwoI64Regs$__0:
; 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
; DIS-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
; IASM-NEXT: .byte 0x20
; IASM-NEXT: .byte 0x82
; IASM-NEXT: .byte 0xe0
; IASM-NEXT: .byte 0x2
; IASM-NEXT: .byte 0x10
; IASM-NEXT: .byte 0xa0
; IASM-NEXT: .byte 0xe1
; IASM-NEXT: .byte 0x1e
; IASM-NEXT: .byte 0xff
; IASM-NEXT: .byte 0x2f
; IASM-NEXT: .byte 0xe1
; ASM: mul r3, r0, r3
; ASM-NEXT: mla r1, r2, r1, r3
; ASM-NEXT: # r3 = def.pseudo
; ASM-NEXT: umull r0, r3, r0, r2
; ASM-NEXT: # r3 = def.pseudo r0
; ASM-NEXT: add r3, r3, r1
; DIS: e0030390
; DIS-NEXT: e0213192
; DIS-NEXT: e0830290
; DIS-NEXT: e0833001
; IASM-NOT: mul
; IASM-NOT: mla
; IASM-NOT: umull
; IASM-NOT: add
......@@ -149,31 +149,39 @@ entry:
; ARM110P2-NEXT: .bundle_unlock
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: add ip, sp, #32
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: bic ip, ip, #3221225472
; ARM110P2-NEXT: vst1.32 q0, [ip]
; ARM110P2-NEXT: .bundle_unlock
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: # [sp, #32] = def.pseudo
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: add ip, sp, #16
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: bic ip, ip, #3221225472
; ARM110P2-NEXT: vst1.32 q1, [ip]
; ARM110P2-NEXT: .bundle_unlock
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: # [sp, #16] = def.pseudo
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: add ip, sp, #32
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: bic ip, ip, #3221225472
; ARM110P2-NEXT: vld1.32 q0, [ip]
; ARM110P2-NEXT: .bundle_unlock
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: add ip, sp, #16
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: bic ip, ip, #3221225472
; ARM110P2-NEXT: vld1.32 q1, [ip]
; ARM110P2-NEXT: .bundle_unlock
......@@ -182,15 +190,11 @@ entry:
; ARM110P2-NEXT: vmul.i32 q0, q0, q1
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: vst1.32 q0, [sp]
; ARM110P2-NEXT: .bundle_unlock
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: # [sp] = def.pseudo
; ARM110P2-NEXT: .bundle_lock
; ARM110P2-NEXT: vld1.32 q0, [sp]
; ARM110P2-NEXT: .bundle_unlock
; ARM110P2-NEXT: nop
; ARM110P2-NEXT: nop
; 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