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

Unified Diff: src/IceTargetLoweringMIPS32.cpp

Issue 2619943003: [SubZero] Fix code generation issues occurred in Cross-test and PNaCL smoke-tests (Closed)
Patch Set: Addressed review comments Created 3 years, 11 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 | « src/IceTargetLoweringMIPS32.h ('k') | tests_lit/assembler/mips32/encoding_intrinsics.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 36650bdad05066182e43e0509a8c48bd0557769d..acbe42240e28ed0b2bb335a75ad89f673eb52032 100644
--- a/src/IceTargetLoweringMIPS32.cpp
+++ b/src/IceTargetLoweringMIPS32.cpp
@@ -97,7 +97,7 @@ uint32_t applyStackAlignmentTy(uint32_t Value, Type Ty) {
size_t typeAlignInBytes = typeWidthInBytes(Ty);
// Vectors are stored on stack with the same alignment as that of int type
if (isVectorType(Ty))
- typeAlignInBytes = typeWidthInBytes(IceType_i32);
+ typeAlignInBytes = typeWidthInBytes(IceType_i64);
return Utils::applyAlignment(Value, typeAlignInBytes);
}
@@ -240,7 +240,7 @@ uint32_t TargetMIPS32::getCallStackArgumentsSizeBytes(const InstCall *Call) {
// If PartialOnStack is true and if this is a vector type then last two
// elements are on stack
if (PartialOnStack && isVectorType(Ty)) {
- OutArgsSizeBytes = applyStackAlignmentTy(OutArgsSizeBytes, IceType_i32);
+ OutArgsSizeBytes = applyStackAlignmentTy(OutArgsSizeBytes, IceType_i64);
OutArgsSizeBytes += typeWidthInBytesOnStack(IceType_i32) * 2;
}
continue;
@@ -987,7 +987,6 @@ Operand *TargetMIPS32::legalizeUndef(Operand *From, RegNumT RegNum) {
auto *Reg = llvm::cast<VariableVecOn32>(Var);
Reg->initVecElement(Func);
auto *Zero = getZero();
- Context.insert<InstFakeDef>(Zero);
for (Variable *Var : Reg->getContainers()) {
_mov(Var, Zero);
}
@@ -1475,7 +1474,7 @@ void TargetMIPS32::addProlog(CfgNode *Node) {
// prolog/epilog.
using RegClassType = std::tuple<uint32_t, uint32_t, VarList *>;
const RegClassType RegClass = RegClassType(
- RegMIPS32::Reg_GPR_First, RegMIPS32::Reg_GPR_Last, &PreservedGPRs);
+ RegMIPS32::Reg_GPR_First, RegMIPS32::Reg_FPR_Last, &PreservedGPRs);
const uint32_t FirstRegInClass = std::get<0>(RegClass);
const uint32_t LastRegInClass = std::get<1>(RegClass);
VarList *const PreservedRegsInClass = std::get<2>(RegClass);
@@ -1520,7 +1519,8 @@ void TargetMIPS32::addProlog(CfgNode *Node) {
// Combine fixed alloca with SpillAreaSize.
SpillAreaSizeBytes += FixedAllocaSizeBytes;
- TotalStackSizeBytes = PreservedRegsSizeBytes + SpillAreaSizeBytes;
+ TotalStackSizeBytes =
+ applyStackAlignment(PreservedRegsSizeBytes + SpillAreaSizeBytes);
// Generate "addiu sp, sp, -TotalStackSizeBytes"
if (TotalStackSizeBytes) {
@@ -1533,11 +1533,16 @@ void TargetMIPS32::addProlog(CfgNode *Node) {
if (!PreservedGPRs.empty()) {
uint32_t StackOffset = TotalStackSizeBytes;
for (Variable *Var : *PreservedRegsInClass) {
- Variable *PhysicalRegister = getPhysicalRegister(Var->getRegNum());
- StackOffset -= typeWidthInBytesOnStack(PhysicalRegister->getType());
+ Type RegType;
+ if (RegMIPS32::isFPRReg(Var->getRegNum()))
+ RegType = IceType_f32;
+ else
+ RegType = IceType_i32;
+ auto *PhysicalRegister = makeReg(RegType, Var->getRegNum());
+ StackOffset -= typeWidthInBytesOnStack(RegType);
Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP);
OperandMIPS32Mem *MemoryLocation = OperandMIPS32Mem::create(
- Func, IceType_i32, SP,
+ Func, RegType, SP,
llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackOffset)));
Sandboxer(this).sw(PhysicalRegister, MemoryLocation);
}
@@ -1652,10 +1657,15 @@ void TargetMIPS32::addEpilog(CfgNode *Node) {
uint32_t StackOffset = TotalStackSizeBytes - PreservedRegsSizeBytes;
for (RIter = PreservedGPRs.rbegin(), END = PreservedGPRs.rend();
RIter != END; ++RIter) {
- Variable *PhysicalRegister = getPhysicalRegister((*RIter)->getRegNum());
+ Type RegType;
+ if (RegMIPS32::isFPRReg((*RIter)->getRegNum()))
+ RegType = IceType_f32;
+ else
+ RegType = IceType_i32;
+ auto *PhysicalRegister = makeReg(RegType, (*RIter)->getRegNum());
Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP);
OperandMIPS32Mem *MemoryLocation = OperandMIPS32Mem::create(
- Func, IceType_i32, SP,
+ Func, RegType, SP,
llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackOffset)));
_lw(PhysicalRegister, MemoryLocation);
StackOffset += typeWidthInBytesOnStack(PhysicalRegister->getType());
@@ -1703,6 +1713,39 @@ Variable *TargetMIPS32::PostLoweringLegalizer::newBaseRegister(
return ScratchReg;
}
+void TargetMIPS32::PostLoweringLegalizer::legalizeMovFp(
+ InstMIPS32MovFP64ToI64 *MovInstr) {
+ Variable *Dest = MovInstr->getDest();
+ Operand *Src = MovInstr->getSrc(0);
+ const Type SrcTy = Src->getType();
+
+ if (Dest != nullptr && SrcTy == IceType_f64) {
+ int32_t Offset = Dest->getStackOffset();
+ auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg());
+ OperandMIPS32Mem *TAddr = OperandMIPS32Mem::create(
+ Target->Func, IceType_f32, Base,
+ llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset)));
+ OperandMIPS32Mem *Addr = legalizeMemOperand(TAddr);
+ auto *SrcV = llvm::cast<Variable>(Src);
+ Variable *SrcR;
+ if (MovInstr->getInt64Part() == Int64_Lo) {
+ SrcR = Target->makeReg(
+ IceType_f32, RegMIPS32::get64PairFirstRegNum(SrcV->getRegNum()));
+ } else {
+ SrcR = Target->makeReg(
+ IceType_f32, RegMIPS32::get64PairSecondRegNum(SrcV->getRegNum()));
+ }
+ Sandboxer(Target).sw(SrcR, Addr);
+ if (MovInstr->isDestRedefined()) {
+ Target->_set_dest_redefined();
+ }
+ MovInstr->setDeleted();
+ return;
+ }
+
+ llvm::report_fatal_error("legalizeMovFp: Invalid operands");
+}
+
void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) {
Variable *Dest = MovInstr->getDest();
assert(Dest != nullptr);
@@ -1747,8 +1790,8 @@ void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) {
DstFPRLo = Target->makeReg(
IceType_i32, RegMIPS32::get64PairSecondRegNum(DRegNum));
}
- Target->_mov(DstFPRHi, SrcGPRLo);
- Target->_mov(DstFPRLo, SrcGPRHi);
+ Target->_mov(DstFPRHi, SrcGPRHi);
+ Target->_mov(DstFPRLo, SrcGPRLo);
Legalized = true;
} else {
Variable *SrcGPR = Target->makeReg(IceType_f32, SRegNum);
@@ -1860,9 +1903,10 @@ void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) {
// ExtraOffset is only needed for stack-pointer based frames as we have
// to account for spill storage.
- const int32_t ExtraOffset = (Var->getRegNum() == Target->getStackReg())
- ? Target->getFrameFixedAllocaOffset()
- : 0;
+ const int32_t ExtraOffset =
+ (Var->getRegNum() == Target->getFrameOrStackReg())
+ ? Target->getFrameFixedAllocaOffset()
+ : 0;
const int32_t Offset = Var->getStackOffset() + ExtraOffset;
Variable *Base = Target->getPhysicalRegister(Var->getRegNum());
@@ -2018,6 +2062,10 @@ void TargetMIPS32::postLowerLegalization() {
Legalizer.legalizeMov(MovInstr);
continue;
}
+ if (auto *MovInstr = llvm::dyn_cast<InstMIPS32MovFP64ToI64>(CurInstr)) {
+ Legalizer.legalizeMovFp(MovInstr);
+ continue;
+ }
if (llvm::isa<InstMIPS32Sw>(CurInstr)) {
if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) {
Sandboxer(this).sw(Src0V, LegalMem);
@@ -2608,15 +2656,24 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) {
switch (Instr->getOp()) {
case InstArithmetic::Add:
+ case InstArithmetic::Sub: {
+ auto *Const32 = llvm::dyn_cast<ConstantInteger32>(Src1);
+ if (Const32 != nullptr && isInt<16>(int32_t(Const32->getValue()))) {
+ IsSrc1Imm16 = true;
+ Value = Const32->getValue();
+ } else {
+ Src1R = legalizeToReg(Src1);
+ }
+ break;
+ }
case InstArithmetic::And:
case InstArithmetic::Or:
case InstArithmetic::Xor:
- case InstArithmetic::Sub:
case InstArithmetic::Shl:
case InstArithmetic::Lshr:
case InstArithmetic::Ashr: {
auto *Const32 = llvm::dyn_cast<ConstantInteger32>(Src1);
- if (Const32 != nullptr && isInt<16>(int32_t(Const32->getValue()))) {
+ if (Const32 != nullptr && llvm::isUInt<16>(uint32_t(Const32->getValue()))) {
IsSrc1Imm16 = true;
Value = Const32->getValue();
} else {
@@ -2633,14 +2690,25 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) {
switch (Instr->getOp()) {
case InstArithmetic::_num:
break;
- case InstArithmetic::Add:
+ case InstArithmetic::Add: {
+ auto *T0R = Src0R;
+ auto *T1R = Src1R;
+ if (Dest->getType() != IceType_i32) {
+ T0R = makeReg(IceType_i32);
+ lowerCast(InstCast::create(Func, InstCast::Sext, T0R, Src0R));
+ if (!IsSrc1Imm16) {
+ T1R = makeReg(IceType_i32);
+ lowerCast(InstCast::create(Func, InstCast::Sext, T1R, Src1R));
+ }
+ }
if (IsSrc1Imm16) {
- _addiu(T, Src0R, Value);
+ _addiu(T, T0R, Value);
} else {
- _addu(T, Src0R, Src1R);
+ _addu(T, T0R, T1R);
}
_mov(Dest, T);
return;
+ }
case InstArithmetic::And:
if (IsSrc1Imm16) {
_andi(T, Src0R, Value);
@@ -2665,14 +2733,25 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) {
}
_mov(Dest, T);
return;
- case InstArithmetic::Sub:
+ case InstArithmetic::Sub: {
+ auto *T0R = Src0R;
+ auto *T1R = Src1R;
+ if (Dest->getType() != IceType_i32) {
+ T0R = makeReg(IceType_i32);
+ lowerCast(InstCast::create(Func, InstCast::Sext, T0R, Src0R));
+ if (!IsSrc1Imm16) {
+ T1R = makeReg(IceType_i32);
+ lowerCast(InstCast::create(Func, InstCast::Sext, T1R, Src1R));
+ }
+ }
if (IsSrc1Imm16) {
- _addiu(T, Src0R, -Value);
+ _addiu(T, T0R, -Value);
} else {
- _subu(T, Src0R, Src1R);
+ _subu(T, T0R, T1R);
}
_mov(Dest, T);
return;
+ }
case InstArithmetic::Mul: {
_mul(T, Src0R, Src1R);
_mov(Dest, T);
@@ -2707,10 +2786,20 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) {
return;
}
case InstArithmetic::Ashr: {
+ auto *T0R = Src0R;
+ auto *T1R = Src1R;
+ if (Dest->getType() != IceType_i32) {
+ T0R = makeReg(IceType_i32);
+ lowerCast(InstCast::create(Func, InstCast::Sext, T0R, Src0R));
+ if (!IsSrc1Imm16) {
+ T1R = makeReg(IceType_i32);
+ lowerCast(InstCast::create(Func, InstCast::Sext, T1R, Src1R));
+ }
+ }
if (IsSrc1Imm16) {
- _sra(T, Src0R, Value);
+ _sra(T, T0R, Value);
} else {
- _srav(T, Src0R, Src1R);
+ _srav(T, T0R, T1R);
}
_mov(Dest, T);
return;
@@ -2733,8 +2822,16 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) {
}
case InstArithmetic::Sdiv: {
auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO);
- _div(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::Sext, T0R, Src0R));
+ T1R = makeReg(IceType_i32);
+ lowerCast(InstCast::create(Func, InstCast::Sext, T1R, Src1R));
+ }
+ _div(T_Zero, T0R, T1R);
+ _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero
_mflo(T, T_Zero);
_mov(Dest, T);
return;
@@ -2757,8 +2854,16 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) {
}
case InstArithmetic::Srem: {
auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO);
- _div(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::Sext, T0R, Src0R));
+ T1R = makeReg(IceType_i32);
+ lowerCast(InstCast::create(Func, InstCast::Sext, T1R, Src1R));
+ }
+ _div(T_Zero, T0R, T1R);
+ _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero
_mfhi(T, T_Zero);
_mov(Dest, T);
return;
@@ -2905,8 +3010,32 @@ void TargetMIPS32::lowerBr(const InstBr *Instr) {
Src0HiR = legalizeToReg(hiOperand(Src0));
Src1HiR = legalizeToReg(hiOperand(Src1));
} else {
- Src0R = legalizeToReg(Src0);
- Src1R = legalizeToReg(Src1);
+ auto *Src0RT = legalizeToReg(Src0);
+ auto *Src1RT = legalizeToReg(Src1);
+ // Sign/Zero extend the source operands
+ if (Src0Ty != IceType_i32) {
+ InstCast::OpKind CastKind;
+ switch (CompareInst->getCondition()) {
+ case InstIcmp::Eq:
+ case InstIcmp::Ne:
+ case InstIcmp::Sgt:
+ case InstIcmp::Sge:
+ case InstIcmp::Slt:
+ case InstIcmp::Sle:
+ CastKind = InstCast::Sext;
+ break;
+ default:
+ CastKind = InstCast::Zext;
+ break;
+ }
+ Src0R = makeReg(IceType_i32);
+ Src1R = makeReg(IceType_i32);
+ lowerCast(InstCast::create(Func, CastKind, Src0R, Src0RT));
+ lowerCast(InstCast::create(Func, CastKind, Src1R, Src1RT));
+ } else {
+ Src0R = Src0RT;
+ Src1R = Src1RT;
+ }
}
auto *DestT = makeReg(IceType_i32);
@@ -3144,9 +3273,9 @@ void TargetMIPS32::lowerCall(const InstCall *Instr) {
if (!InReg) {
if (isVectorType(Ty)) {
auto *ArgVec = llvm::cast<VariableVecOn32>(Arg);
+ ParameterAreaSizeBytes =
+ applyStackAlignmentTy(ParameterAreaSizeBytes, IceType_i64);
for (Variable *Elem : ArgVec->getContainers()) {
- ParameterAreaSizeBytes =
- applyStackAlignmentTy(ParameterAreaSizeBytes, IceType_i32);
StackArgs.push_back(std::make_pair(Elem, ParameterAreaSizeBytes));
ParameterAreaSizeBytes += typeWidthInBytesOnStack(IceType_i32);
}
@@ -3179,11 +3308,9 @@ void TargetMIPS32::lowerCall(const InstCall *Instr) {
std::make_pair(Elem3, RegNumT::fixme((unsigned)Reg + 3)));
} else {
ParameterAreaSizeBytes =
- applyStackAlignmentTy(ParameterAreaSizeBytes, IceType_i32);
+ applyStackAlignmentTy(ParameterAreaSizeBytes, IceType_i64);
StackArgs.push_back(std::make_pair(Elem2, ParameterAreaSizeBytes));
ParameterAreaSizeBytes += typeWidthInBytesOnStack(IceType_i32);
- ParameterAreaSizeBytes =
- applyStackAlignmentTy(ParameterAreaSizeBytes, IceType_i32);
StackArgs.push_back(std::make_pair(Elem3, ParameterAreaSizeBytes));
ParameterAreaSizeBytes += typeWidthInBytesOnStack(IceType_i32);
}
@@ -3484,7 +3611,20 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) {
Src0 = loOperand(Src0);
Variable *Src0R = legalizeToReg(Src0);
Variable *T = makeReg(DestTy);
- _mov(T, Src0R);
+ switch (DestTy) {
+ case IceType_i1:
+ _andi(T, Src0R, 0x1);
+ break;
+ case IceType_i8:
+ _andi(T, Src0R, 0xff);
+ break;
+ case IceType_i16:
+ _andi(T, Src0R, 0xffff);
+ break;
+ default:
+ _mov(T, Src0R);
+ break;
+ }
_mov(Dest, T);
break;
}
@@ -3540,9 +3680,12 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) {
if (Src0Ty != IceType_i64) {
Variable *Src0R = legalizeToReg(Src0);
auto *T0R = Src0R;
- if (Src0Ty != IceType_i32 && CastKind == InstCast::Uitofp) {
+ if (Src0Ty != IceType_i32) {
T0R = makeReg(IceType_i32);
- lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R));
+ if (CastKind == InstCast::Uitofp)
+ lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R));
+ else
+ lowerCast(InstCast::create(Func, InstCast::Sext, T0R, Src0R));
}
if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f32) {
Variable *FTmp1 = makeReg(IceType_f32);
@@ -3604,9 +3747,12 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) {
Variable *Src0R = legalizeToReg(Src0);
auto *T = llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64));
T->initHiLo(Func);
- T->getHi()->setMustHaveReg();
- T->getLo()->setMustHaveReg();
- _mov(T, Src0R);
+ T->getHi()->setMustNotHaveReg();
+ T->getLo()->setMustNotHaveReg();
+ Context.insert<InstFakeDef>(T->getHi());
+ Context.insert<InstFakeDef>(T->getLo());
+ _mov_fp64_to_i64(T->getHi(), Src0R, Int64_Hi);
+ _mov_fp64_to_i64(T->getLo(), Src0R, Int64_Lo);
lowerAssign(InstAssign::create(Func, Dest, T));
break;
}
@@ -4178,12 +4324,12 @@ void TargetMIPS32::lowerInsertElement(const InstInsertElement *Instr) {
auto *DstE = TVDest->getContainers()[Index / ElemPerCont];
// Element to insert
auto *Src1R = legalizeToReg(Instr->getSrc(1));
- auto *TReg1 = makeReg(Src1R->getType());
- auto *TReg2 = makeReg(Src1R->getType());
- auto *TReg3 = makeReg(Src1R->getType());
- auto *TReg4 = makeReg(Src1R->getType());
- auto *TReg5 = makeReg(Src1R->getType());
- auto *TDReg = makeReg(Src1R->getType());
+ auto *TReg1 = makeReg(IceType_i32);
+ auto *TReg2 = makeReg(IceType_i32);
+ auto *TReg3 = makeReg(IceType_i32);
+ auto *TReg4 = makeReg(IceType_i32);
+ auto *TReg5 = makeReg(IceType_i32);
+ auto *TDReg = makeReg(IceType_i32);
// Position of the element in the container
uint32_t PosInCont = Index % ElemPerCont;
// Load source vector in a temporary vector
@@ -4248,7 +4394,7 @@ void TargetMIPS32::lowerInsertElement(const InstInsertElement *Instr) {
_mov(DstE, TDReg);
break;
case 3:
- _srl(TReg1, Src1R, 24); // Position in the destination
+ _sll(TReg1, Src1R, 24); // Position in the destination
_sll(TReg2, SrcE, 8);
_srl(TReg3, TReg2, 8); // Clear bits[31:24] of element
_or(TDReg, TReg1, TReg3);
@@ -5729,8 +5875,8 @@ Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed,
} else {
uint32_t UpperBits = (Value >> 16) & 0xFFFF;
uint32_t LowerBits = Value & 0xFFFF;
- Variable *TReg = makeReg(Ty, RegNum);
if (LowerBits) {
+ Variable *TReg = makeReg(Ty, RegNum);
_lui(TReg, Ctx->getConstantInt32(UpperBits));
_ori(Reg, TReg, LowerBits);
} else {
« no previous file with comments | « src/IceTargetLoweringMIPS32.h ('k') | tests_lit/assembler/mips32/encoding_intrinsics.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698