Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(749)

Unified Diff: src/IceTargetLoweringMIPS32.cpp

Issue 2432373002: [SubZero] Fix f64 to/from i64 moves (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addressed review comments Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pydir/crosstest.py ('k') | tests_lit/llvm2ice_tests/bitcast.ll » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceTargetLoweringMIPS32.cpp
diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp
index 99c32cc19c85fb194063fd3bded43a75fe3eb6c6..ca8794419455a3e0c0c41a4c3cbd8773f4309a2d 100644
--- a/src/IceTargetLoweringMIPS32.cpp
+++ b/src/IceTargetLoweringMIPS32.cpp
@@ -115,7 +115,6 @@ void TargetMIPS32::assignVarStackSlots(VarList &SortedSpilledVariables,
size_t NextStackOffset = SpillAreaPaddingBytes;
CfgVector<size_t> LocalsSize(Func->getNumNodes());
const bool SimpleCoalescing = !callsReturnsTwice();
-
for (Variable *Var : SortedSpilledVariables) {
size_t Increment = typeWidthInBytesOnStack(Var->getType());
if (SimpleCoalescing && VMetadata->isTracked(Var)) {
@@ -1741,9 +1740,9 @@ void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) {
SrcGPRHi = Target->makeReg(IceType_i32, FirstReg);
SrcGPRLo = Target->makeReg(IceType_i32, SecondReg);
} else {
- SrcGPRHi = Target->makeReg(
- IceType_i32, RegMIPS32::get64PairFirstRegNum(SRegNum));
SrcGPRLo = Target->makeReg(
+ IceType_i32, RegMIPS32::get64PairFirstRegNum(SRegNum));
+ SrcGPRHi = Target->makeReg(
IceType_i32, RegMIPS32::get64PairSecondRegNum(SRegNum));
}
}
@@ -1775,19 +1774,19 @@ void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) {
auto *SrcR = llvm::cast<Variable>(Src);
assert(SrcR->hasReg());
assert(!SrcR->isRematerializable());
- int32_t Offset = 0;
-
- if (MovInstr->getDestHi() != nullptr)
- Offset = MovInstr->getDestHi()->getStackOffset();
- else
- Offset = Dest->getStackOffset();
+ int32_t Offset = Dest->getStackOffset();
// This is a _mov(Mem(), Variable), i.e., a store.
auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg());
- OperandMIPS32Mem *Addr = OperandMIPS32Mem::create(
+ OperandMIPS32Mem *TAddr = OperandMIPS32Mem::create(
Target->Func, DestTy, Base,
llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset)));
+ OperandMIPS32Mem *TAddrHi = OperandMIPS32Mem::create(
+ Target->Func, DestTy, Base,
+ llvm::cast<ConstantInteger32>(
+ Target->Ctx->getConstantInt32(Offset + 4)));
+ OperandMIPS32Mem *Addr = legalizeMemOperand(TAddr);
// FP arguments are passed in GP reg if first argument is in GP. In this
// case type of the SrcR is still FP thus we need to explicitly generate sw
@@ -1802,24 +1801,18 @@ void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) {
Target->makeReg(IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum));
Variable *SrcGPRLo = Target->makeReg(
IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum));
- OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create(
- Target->Func, DestTy, Base,
- llvm::cast<ConstantInteger32>(
- Target->Ctx->getConstantInt32(Offset + 4)));
- Target->_sw(SrcGPRLo, Addr);
- Target->_sw(SrcGPRHi, AddrHi);
+ Target->_sw(SrcGPRHi, Addr);
+ OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi);
+ Target->_sw(SrcGPRLo, AddrHi);
} else if (DestTy == IceType_f64 && IsSrcGPReg) {
const auto FirstReg =
(llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum();
const auto SecondReg =
(llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum();
- Variable *SrcGPRHi = Target->makeReg(IceType_i32, SecondReg);
- Variable *SrcGPRLo = Target->makeReg(IceType_i32, FirstReg);
- OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create(
- Target->Func, DestTy, Base,
- llvm::cast<ConstantInteger32>(
- Target->Ctx->getConstantInt32(Offset + 4)));
+ Variable *SrcGPRHi = Target->makeReg(IceType_i32, FirstReg);
+ Variable *SrcGPRLo = Target->makeReg(IceType_i32, SecondReg);
Target->_sw(SrcGPRLo, Addr);
+ OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi);
Target->_sw(SrcGPRHi, AddrHi);
} else {
Target->_sw(SrcR, Addr);
@@ -1847,12 +1840,68 @@ void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) {
// This is a _mov(Variable, Mem()), i.e., a load.
const int32_t Offset = Var->getStackOffset();
auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg());
- OperandMIPS32Mem *Addr;
- Addr = OperandMIPS32Mem::create(
- Target->Func, DestTy, Base,
- llvm::cast<ConstantInteger32>(
- Target->Ctx->getConstantInt32(Offset)));
- Target->_lw(Dest, Addr);
+ const RegNumT RegNum = Dest->getRegNum();
+ const bool IsDstGPReg = RegMIPS32::isGPRReg(Dest->getRegNum());
+ // If we are moving i64 to a double using stack then the address may
+ // not be aligned to 8-byte boundary as we split i64 into Hi-Lo parts
+ // and store them individually with 4-byte alignment. Load the Hi-Lo
+ // parts in TmpReg and move them to the dest using mtc1.
+ if (DestTy == IceType_f64 && !Utils::IsAligned(Offset, 8)
+ && !IsDstGPReg) {
+ auto *Reg = Target->makeReg(IceType_i32, Target->getReservedTmpReg());
+ const RegNumT RegNum = Dest->getRegNum();
+ Variable *DestLo = Target->makeReg(
+ IceType_f32, RegMIPS32::get64PairFirstRegNum(RegNum));
+ Variable *DestHi = Target->makeReg(
+ IceType_f32, RegMIPS32::get64PairSecondRegNum(RegNum));
+ OperandMIPS32Mem *AddrLo = OperandMIPS32Mem::create(
+ Target->Func, IceType_i32, Base,
+ llvm::cast<ConstantInteger32>(
+ Target->Ctx->getConstantInt32(Offset)));
+ OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create(
+ Target->Func, IceType_i32, Base,
+ llvm::cast<ConstantInteger32>(
+ Target->Ctx->getConstantInt32(Offset + 4)));
+ Target->_lw(Reg, AddrLo);
+ Target->_mov(DestLo, Reg);
+ Target->_lw(Reg, AddrHi);
+ Target->_mov(DestHi, Reg);
+ } else {
+ OperandMIPS32Mem *TAddr = OperandMIPS32Mem::create(
+ Target->Func, DestTy, Base, llvm::cast<ConstantInteger32>(
+ Target->Ctx->getConstantInt32(Offset)));
+ OperandMIPS32Mem *Addr = legalizeMemOperand(TAddr);
+ OperandMIPS32Mem *TAddrHi = OperandMIPS32Mem::create(
+ Target->Func, DestTy, Base, llvm::cast<ConstantInteger32>(
+ Target->Ctx->getConstantInt32(Offset + 4)));
+ // FP arguments are passed in GP reg if first argument is in GP.
+ // In this case type of the Dest is still FP thus we need to
+ // explicitly generate lw instead of lwc1.
+ if (DestTy == IceType_f32 && IsDstGPReg) {
+ Variable *DstGPR = Target->makeReg(IceType_i32, RegNum);
+ Target->_lw(DstGPR, Addr);
+ } else if (DestTy == IceType_f64 && IsDstGPReg) {
+ Variable *DstGPRHi = Target->makeReg(
+ IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum));
+ Variable *DstGPRLo = Target->makeReg(
+ IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum));
+ Target->_lw(DstGPRHi, Addr);
+ OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi);
+ Target->_lw(DstGPRLo, AddrHi);
+ } else if (DestTy == IceType_f64 && IsDstGPReg) {
+ const auto FirstReg =
+ (llvm::cast<Variable>(MovInstr->getSrc(0)))->getRegNum();
+ const auto SecondReg =
+ (llvm::cast<Variable>(MovInstr->getSrc(1)))->getRegNum();
+ Variable *DstGPRHi = Target->makeReg(IceType_i32, FirstReg);
+ Variable *DstGPRLo = Target->makeReg(IceType_i32, SecondReg);
+ Target->_lw(DstGPRLo, Addr);
+ OperandMIPS32Mem *AddrHi = legalizeMemOperand(TAddrHi);
+ Target->_lw(DstGPRHi, AddrHi);
+ } else {
+ Target->_lw(Dest, Addr);
+ }
+ }
Legalized = true;
}
}
@@ -2536,7 +2585,15 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) {
return;
}
case InstArithmetic::Lshr: {
- _srlv(T, Src0R, Src1R);
+ auto *T0R = Src0R;
+ auto *T1R = Src1R;
+ if (Dest->getType() != IceType_i32) {
+ T0R = makeReg(IceType_i32);
+ lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R));
+ T1R = makeReg(IceType_i32);
+ lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R));
+ }
+ _srlv(T, T0R, T1R);
_mov(Dest, T);
return;
}
@@ -2547,8 +2604,16 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) {
}
case InstArithmetic::Udiv: {
auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO);
- _divu(T_Zero, Src0R, Src1R);
- _teq(Src1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero
+ auto *T0R = Src0R;
+ auto *T1R = Src1R;
+ if (Dest->getType() != IceType_i32) {
+ T0R = makeReg(IceType_i32);
+ lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R));
+ T1R = makeReg(IceType_i32);
+ lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R));
+ }
+ _divu(T_Zero, T0R, T1R);
+ _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero
_mflo(T, T_Zero);
_mov(Dest, T);
return;
@@ -2563,8 +2628,16 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) {
}
case InstArithmetic::Urem: {
auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO);
- _divu(T_Zero, Src0R, Src1R);
- _teq(Src1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero
+ auto *T0R = Src0R;
+ auto *T1R = Src1R;
+ if (Dest->getType() != IceType_i32) {
+ T0R = makeReg(IceType_i32);
+ lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R));
+ T1R = makeReg(IceType_i32);
+ lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R));
+ }
+ _divu(T_Zero, T0R, T1R);
+ _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero
_mfhi(T, T_Zero);
_mov(Dest, T);
return;
@@ -3348,20 +3421,24 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) {
return;
}
if (Src0Ty != IceType_i64) {
+ Variable *Src0R = legalizeToReg(Src0);
+ auto *T0R = Src0R;
+ if (Src0Ty != IceType_i32 && CastKind == InstCast::Uitofp) {
+ T0R = makeReg(IceType_i32);
+ lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R));
+ }
if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f32) {
- Variable *Src0R = legalizeToReg(Src0);
Variable *FTmp1 = makeReg(IceType_f32);
Variable *FTmp2 = makeReg(IceType_f32);
- _mtc1(FTmp1, Src0R);
+ _mtc1(FTmp1, T0R);
_cvt_s_w(FTmp2, FTmp1);
_mov(Dest, FTmp2);
return;
}
if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f64) {
- Variable *Src0R = legalizeToReg(Src0);
Variable *FTmp1 = makeReg(IceType_f64);
Variable *FTmp2 = makeReg(IceType_f64);
- _mtc1(FTmp1, Src0R);
+ _mtc1(FTmp1, T0R);
_cvt_d_w(FTmp2, FTmp1);
_mov(Dest, FTmp2);
return;
@@ -3408,8 +3485,12 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) {
case IceType_i64: {
assert(Src0->getType() == IceType_f64);
Variable *Src0R = legalizeToReg(Src0);
- auto *Dest64 = llvm::cast<Variable64On32>(Dest);
- _mov(Dest64, Src0R);
+ auto *T = llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64));
+ T->initHiLo(Func);
+ T->getHi()->setMustHaveReg();
+ T->getLo()->setMustHaveReg();
+ _mov(T, Src0R);
+ lowerAssign(InstAssign::create(Func, Dest, T));
break;
}
case IceType_f64: {
@@ -5241,6 +5322,8 @@ void TargetHeaderMIPS32::lower() {
<< "nomicromips\n";
Str << "\t.set\t"
<< "nomips16\n";
+ Str << "\t.set\t"
+ << "noat\n";
}
SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM];
« no previous file with comments | « pydir/crosstest.py ('k') | tests_lit/llvm2ice_tests/bitcast.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698