Chromium Code Reviews| Index: src/IceTargetLoweringMIPS32.cpp |
| diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp |
| index 9b71d46616e7be5c48902491d7ee10972b878220..dd8856d5926544fa850bf52c52202a160c82c10f 100644 |
| --- a/src/IceTargetLoweringMIPS32.cpp |
| +++ b/src/IceTargetLoweringMIPS32.cpp |
| @@ -223,6 +223,94 @@ void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) { |
| switch (Instr->getKind()) { |
| default: |
| return; |
| + case Inst::Select: { |
| + Variable *Dest = Instr->getDest(); |
| + if (isVectorType(Dest->getType())) { |
| + Operand *SrcT = llvm::cast<InstSelect>(Instr)->getTrueOperand(); |
| + Operand *SrcF = llvm::cast<InstSelect>(Instr)->getFalseOperand(); |
| + Operand *Cond = llvm::cast<InstSelect>(Instr)->getCondition(); |
| + Variable *T = Func->makeVariable(Dest->getType()); |
| + auto *Undef = ConstantUndef::create(Ctx, Dest->getType()); |
| + Context.insert<InstAssign>(T, Undef); |
| + auto *VarVecOn32 = llvm::dyn_cast<VariableVecOn32>(T); |
|
Jim Stichnoth
2016/10/14 13:43:37
Use llvm::cast<> since the next statement assumes
jaydeep.patil
2016/10/15 03:47:57
Done.
|
| + VarVecOn32->initVecElement(Func); |
| + for (SizeT I = 0; I < typeNumElements(Dest->getType()); ++I) { |
| + auto *Index = Ctx->getConstantInt32(I); |
| + auto *OpC = Func->makeVariable(typeElementType(Cond->getType())); |
| + Context.insert<InstExtractElement>(OpC, Cond, Index); |
| + auto *OpT = Func->makeVariable(typeElementType(T->getType())); |
|
Jim Stichnoth
2016/10/14 13:43:37
I would use DestTy instead of T->getType() just to
jaydeep.patil
2016/10/15 03:47:56
Done.
|
| + Context.insert<InstExtractElement>(OpT, SrcT, Index); |
| + auto *OpF = Func->makeVariable(typeElementType(T->getType())); |
| + Context.insert<InstExtractElement>(OpF, SrcF, Index); |
| + auto *Dst = Func->makeVariable(typeElementType(Dest->getType())); |
| + Variable *DestT = Func->makeVariable(Dest->getType()); |
| + Context.insert<InstSelect>(Dst, OpC, OpT, OpF); |
| + Context.insert<InstInsertElement>(DestT, T, Dst, Index); |
| + T = DestT; |
| + } |
| + Context.insert<InstAssign>(Dest, T); |
| + Instr->setDeleted(); |
| + } |
| + return; |
| + } |
| + case Inst::Fcmp: { |
| + Variable *Dest = Instr->getDest(); |
| + if (isVectorType(Dest->getType())) { |
| + InstFcmp::FCond Cond = llvm::cast<InstFcmp>(Instr)->getCondition(); |
| + Operand *Src0 = Instr->getSrc(0); |
| + Operand *Src1 = Instr->getSrc(1); |
| + Variable *T = Func->makeVariable(IceType_v4f32); |
| + auto *Undef = ConstantUndef::create(Ctx, IceType_v4f32); |
| + Context.insert<InstAssign>(T, Undef); |
| + auto *VarVecOn32 = llvm::dyn_cast<VariableVecOn32>(T); |
| + VarVecOn32->initVecElement(Func); |
| + for (SizeT I = 0; I < typeNumElements(IceType_v4f32); ++I) { |
| + auto *Index = Ctx->getConstantInt32(I); |
| + auto *Op0 = Func->makeVariable(IceType_f32); |
| + Context.insert<InstExtractElement>(Op0, Src0, Index); |
| + auto *Op1 = Func->makeVariable(IceType_f32); |
| + Context.insert<InstExtractElement>(Op1, Src1, Index); |
| + auto *Dst = Func->makeVariable(IceType_f32); |
| + Variable *DestT = Func->makeVariable(IceType_v4f32); |
| + Context.insert<InstFcmp>(Cond, Dst, Op0, Op1); |
| + Context.insert<InstInsertElement>(DestT, T, Dst, Index); |
| + T = DestT; |
| + } |
| + Context.insert<InstAssign>(Dest, T); |
| + Instr->setDeleted(); |
| + } |
| + return; |
| + } |
| + case Inst::Icmp: { |
| + Variable *Dest = Instr->getDest(); |
| + const Type DetType = Dest->getType(); |
| + if (isVectorType(DetType)) { |
| + InstIcmp::ICond Cond = llvm::cast<InstIcmp>(Instr)->getCondition(); |
| + Operand *Src0 = Instr->getSrc(0); |
| + Operand *Src1 = Instr->getSrc(1); |
| + const Type SrcType = Src0->getType(); |
| + Variable *T = Func->makeVariable(DetType); |
| + auto *Undef = ConstantUndef::create(Ctx, DetType); |
| + Context.insert<InstAssign>(T, Undef); |
| + auto *VarVecOn32 = llvm::dyn_cast<VariableVecOn32>(T); |
| + VarVecOn32->initVecElement(Func); |
| + for (SizeT I = 0; I < typeNumElements(SrcType); ++I) { |
| + auto *Index = Ctx->getConstantInt32(I); |
| + auto *Op0 = Func->makeVariable(typeElementType(SrcType)); |
| + Context.insert<InstExtractElement>(Op0, Src0, Index); |
| + auto *Op1 = Func->makeVariable(typeElementType(SrcType)); |
| + Context.insert<InstExtractElement>(Op1, Src1, Index); |
| + auto *Dst = Func->makeVariable(typeElementType(DetType)); |
| + Variable *DestT = Func->makeVariable(DetType); |
| + Context.insert<InstIcmp>(Cond, Dst, Op0, Op1); |
| + Context.insert<InstInsertElement>(DestT, T, Dst, Index); |
| + T = DestT; |
| + } |
| + Context.insert<InstAssign>(Dest, T); |
| + Instr->setDeleted(); |
| + } |
| + return; |
| + } |
| case Inst::Arithmetic: { |
| Variable *Dest = Instr->getDest(); |
| const Type DestTy = Dest->getType(); |
| @@ -294,6 +382,28 @@ void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) { |
| const Type SrcTy = Src0->getType(); |
| auto *CastInstr = llvm::cast<InstCast>(Instr); |
| const InstCast::OpKind CastKind = CastInstr->getCastKind(); |
| + |
| + if (isVectorType(Dest->getType())) { |
| + Variable *T = Func->makeVariable(DestTy); |
| + auto *VarVecOn32 = llvm::dyn_cast<VariableVecOn32>(T); |
| + VarVecOn32->initVecElement(Func); |
| + auto *Undef = ConstantUndef::create(Ctx, DestTy); |
| + Context.insert<InstAssign>(T, Undef); |
| + for (SizeT I = 0; I < typeNumElements(DestTy); ++I) { |
| + auto *Index = Ctx->getConstantInt32(I); |
| + auto *Op = Func->makeVariable(typeElementType(SrcTy)); |
| + Context.insert<InstExtractElement>(Op, Src0, Index); |
| + auto *Dst = Func->makeVariable(typeElementType(DestTy)); |
| + Variable *DestT = Func->makeVariable(DestTy); |
| + Context.insert<InstCast>(CastKind, Dst, Op); |
| + Context.insert<InstInsertElement>(DestT, T, Dst, Index); |
| + T = DestT; |
| + } |
| + Context.insert<InstAssign>(Dest, T); |
| + Instr->setDeleted(); |
| + return; |
| + } |
| + |
| switch (CastKind) { |
| default: |
| return; |
| @@ -445,11 +555,12 @@ void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) { |
| Intrinsics::IntrinsicInfo Info = FullInfo->Info; |
| Variable *T = Func->makeVariable(IceType_v4f32); |
| + auto *Undef = ConstantUndef::create(Ctx, IceType_v4f32); |
| + Context.insert<InstAssign>(T, Undef); |
| auto *VarVecOn32 = llvm::dyn_cast<VariableVecOn32>(T); |
| VarVecOn32->initVecElement(Func); |
| - Context.insert<InstFakeDef>(T); |
| - for (SizeT i = 0; i < VarVecOn32->ElementsPerContainer; ++i) { |
| + for (SizeT i = 0; i < typeNumElements(IceType_v4f32); ++i) { |
| auto *Index = Ctx->getConstantInt32(i); |
| auto *Op = Func->makeVariable(IceType_f32); |
| Context.insert<InstExtractElement>(Op, Src0, Index); |
| @@ -1079,23 +1190,13 @@ void TargetMIPS32::lowerArguments() { |
| // v4f32 is returned through stack. $4 is setup by the caller and passed as |
| // first argument implicitly. Callee then copies the return vector at $4. |
| + Variable *ImplicitRetVec = nullptr; |
| if (isVectorFloatingType(Func->getReturnType())) { |
| - Variable *ImplicitRetVec = Func->makeVariable(IceType_i32); |
| + ImplicitRetVec = Func->makeVariable(IceType_i32); |
| ImplicitRetVec->setName(Func, "ImplicitRet_v4f32"); |
| ImplicitRetVec->setIsArg(); |
| Args.insert(Args.begin(), ImplicitRetVec); |
| setImplicitRet(ImplicitRetVec); |
| - Context.insert<InstFakeDef>(ImplicitRetVec); |
| - for (CfgNode *Node : Func->getNodes()) { |
| - for (Inst &Instr : Node->getInsts()) { |
| - if (llvm::isa<InstRet>(&Instr)) { |
| - Context.setInsertPoint(Instr); |
| - Context.insert<InstFakeUse>(ImplicitRetVec); |
| - break; |
| - } |
| - } |
| - } |
| - Context.setInsertPoint(Context.getCur()); |
| } |
| for (SizeT i = 0, E = Args.size(); i < E; ++i) { |
| @@ -1149,6 +1250,19 @@ void TargetMIPS32::lowerArguments() { |
| } |
| Context.insert<InstAssign>(Arg, RegisterArg); |
| } |
| + |
| + // Insert fake use of ImplicitRet_v4f32 to keep it live |
| + if (ImplicitRetVec) { |
| + for (CfgNode *Node : Func->getNodes()) { |
| + for (Inst &Instr : Node->getInsts()) { |
| + if (llvm::isa<InstRet>(&Instr)) { |
| + Context.setInsertPoint(Instr); |
| + Context.insert<InstFakeUse>(ImplicitRetVec); |
| + break; |
| + } |
| + } |
| + } |
| + } |
| } |
| Type TargetMIPS32::stackSlotType() { return IceType_i32; } |
| @@ -2213,7 +2327,7 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) { |
| return; |
| } |
| if (isVectorType(Dest->getType())) { |
| - UnimplementedLoweringError(this, Instr); |
| + llvm::report_fatal_error("Arithmetic: Destination type is vector"); |
| return; |
| } |
| @@ -2361,6 +2475,20 @@ void TargetMIPS32::lowerAssign(const InstAssign *Instr) { |
| return; |
| } |
| + // Source type may not be same as destination |
| + if (isVectorType(Dest->getType())) { |
| + Operand *Src0 = legalizeUndef(Instr->getSrc(0)); |
| + auto *DstVec = llvm::dyn_cast<VariableVecOn32>(Dest); |
| + for (SizeT i = 0; i < DstVec->ContainersPerVector; ++i) { |
| + auto *DCont = DstVec->getContainers()[i]; |
| + auto *SCont = |
| + legalize(getOperandAtIndex(Src0, IceType_i32, i), Legal_Reg); |
| + auto *TReg = makeReg(IceType_i32); |
| + _mov(TReg, SCont); |
| + _mov(DCont, TReg); |
| + } |
| + return; |
| + } |
| Operand *Src0 = Instr->getSrc(0); |
| assert(Dest->getType() == Src0->getType()); |
| if (Dest->getType() == IceType_i64) { |
| @@ -2376,18 +2504,6 @@ void TargetMIPS32::lowerAssign(const InstAssign *Instr) { |
| _mov(DestHi, T_Hi); |
| return; |
| } |
| - if (isVectorType(Dest->getType())) { |
| - auto *DstVec = llvm::dyn_cast<VariableVecOn32>(Dest); |
| - for (SizeT i = 0; i < DstVec->ElementsPerContainer; ++i) { |
| - auto *DCont = DstVec->getContainers()[i]; |
| - auto *SCont = |
| - legalize(getOperandAtIndex(Src0, IceType_i32, i), Legal_Reg); |
| - auto *TReg = makeReg(IceType_i32); |
| - _mov(TReg, SCont); |
| - _mov(DCont, TReg); |
| - } |
| - return; |
| - } |
| Operand *SrcR; |
| if (Dest->hasReg()) { |
| // If Dest already has a physical register, then legalize the Src operand |
| @@ -2796,7 +2912,7 @@ void TargetMIPS32::lowerCall(const InstCall *Instr) { |
| ReturnReg = makeReg(Dest->getType(), RegMIPS32::Reg_V0); |
| auto *RetVec = llvm::dyn_cast<VariableVecOn32>(ReturnReg); |
| RetVec->initVecElement(Func); |
| - for (SizeT i = 0; i < RetVec->ElementsPerContainer; ++i) { |
| + for (SizeT i = 0; i < RetVec->ContainersPerVector; ++i) { |
| auto *Var = RetVec->getContainers()[i]; |
| Var->setRegNum(RegNumT::fixme(RegMIPS32::Reg_V0 + i)); |
| } |
| @@ -2887,7 +3003,7 @@ void TargetMIPS32::lowerCall(const InstCall *Instr) { |
| if (ReturnReg) { |
| if (RetVecFloat) { |
| auto *DestVecOn32 = llvm::cast<VariableVecOn32>(Dest); |
| - for (SizeT i = 0; i < DestVecOn32->ElementsPerContainer; ++i) { |
| + for (SizeT i = 0; i < DestVecOn32->ContainersPerVector; ++i) { |
| auto *Var = DestVecOn32->getContainers()[i]; |
| OperandMIPS32Mem *Mem = OperandMIPS32Mem::create( |
| Func, IceType_i32, RetVecFloat, |
| @@ -2896,7 +3012,7 @@ void TargetMIPS32::lowerCall(const InstCall *Instr) { |
| } |
| } else if (auto *RetVec = llvm::dyn_cast<VariableVecOn32>(ReturnReg)) { |
| auto *DestVecOn32 = llvm::cast<VariableVecOn32>(Dest); |
| - for (SizeT i = 0; i < DestVecOn32->ElementsPerContainer; ++i) { |
| + for (SizeT i = 0; i < DestVecOn32->ContainersPerVector; ++i) { |
| _mov(DestVecOn32->getContainers()[i], RetVec->getContainers()[i]); |
| } |
| } else if (ReturnRegHi) { |
| @@ -2932,7 +3048,7 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) { |
| : (1 << (CHAR_BITS * typeWidthInBytes(Src0Ty))) - 1); |
| if (isVectorType(DestTy)) { |
| - UnimplementedLoweringError(this, Instr); |
| + llvm::report_fatal_error("Cast: Destination type is vector"); |
| return; |
| } |
| switch (CastKind) { |
| @@ -3095,6 +3211,11 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) { |
| lowerAssign(Assign); |
| return; |
| } |
| + if (isVectorType(DestTy) || isVectorType(Src0->getType())) { |
| + llvm::report_fatal_error( |
| + "Bitcast: vector type should have been prelowered."); |
| + return; |
| + } |
| switch (DestTy) { |
| case IceType_NUM: |
| case IceType_void: |
| @@ -3103,24 +3224,10 @@ void TargetMIPS32::lowerCast(const InstCast *Instr) { |
| UnimplementedLoweringError(this, Instr); |
| break; |
| case IceType_i8: |
| - assert(Src0->getType() == IceType_v8i1); |
| - llvm::report_fatal_error( |
| - "i8 to v8i1 conversion should have been prelowered."); |
| + UnimplementedLoweringError(this, Instr); |
| break; |
| case IceType_i16: |
| - assert(Src0->getType() == IceType_v16i1); |
| - llvm::report_fatal_error( |
| - "i16 to v16i1 conversion should have been prelowered."); |
| - break; |
| - case IceType_v8i1: |
| - assert(Src0->getType() == IceType_i8); |
| - llvm::report_fatal_error( |
| - "v8i1 to i8 conversion should have been prelowered."); |
| - break; |
| - case IceType_v16i1: |
| - assert(Src0->getType() == IceType_i16); |
| - llvm::report_fatal_error( |
| - "v16i1 to i16 conversion should have been prelowered."); |
| + UnimplementedLoweringError(this, Instr); |
| break; |
| default: |
| UnimplementedLoweringError(this, Instr); |
| @@ -3142,7 +3249,7 @@ void TargetMIPS32::lowerExtractElement(const InstExtractElement *Instr) { |
| auto *Src0R = llvm::dyn_cast<VariableVecOn32>(Src0); |
| // Number of elements in each container |
| uint32_t ElemPerCont = |
| - typeNumElements(Src0->getType()) / Src0R->ElementsPerContainer; |
| + typeNumElements(Src0->getType()) / Src0R->ContainersPerVector; |
| auto *SrcE = Src0R->getContainers()[Index / ElemPerCont]; |
| // Position of the element in the container |
| uint32_t PosInCont = Index % ElemPerCont; |
| @@ -3182,8 +3289,9 @@ void TargetMIPS32::lowerExtractElement(const InstExtractElement *Instr) { |
| } |
| } |
| if (typeElementType(Src0R->getType()) == IceType_i1) { |
| - _andi(TReg, TDest, 0x1); |
| - _mov(Dest, TReg); |
| + Variable *TReg1 = makeReg(DestTy); |
| + _andi(TReg1, TDest, 0x1); |
| + _mov(Dest, TReg1); |
| } else { |
| _mov(Dest, TDest); |
| } |
| @@ -3195,7 +3303,7 @@ void TargetMIPS32::lowerExtractElement(const InstExtractElement *Instr) { |
| void TargetMIPS32::lowerFcmp(const InstFcmp *Instr) { |
| Variable *Dest = Instr->getDest(); |
| if (isVectorType(Dest->getType())) { |
| - UnimplementedLoweringError(this, Instr); |
| + llvm::report_fatal_error("Fcmp: Destination type is vector"); |
| return; |
| } |
| @@ -3204,7 +3312,7 @@ void TargetMIPS32::lowerFcmp(const InstFcmp *Instr) { |
| auto *Zero = getZero(); |
| InstFcmp::FCond Cond = Instr->getCondition(); |
| - auto *DestR = makeReg(Dest->getType()); |
| + auto *DestR = makeReg(IceType_i32); |
| auto *Src0R = legalizeToReg(Src0); |
| auto *Src1R = legalizeToReg(Src1); |
| const Type Src0Ty = Src0->getType(); |
| @@ -3542,7 +3650,7 @@ void TargetMIPS32::lowerIcmp(const InstIcmp *Instr) { |
| } |
| Variable *Dest = Instr->getDest(); |
| if (isVectorType(Dest->getType())) { |
| - UnimplementedLoweringError(this, Instr); |
| + llvm::report_fatal_error("Icmp: Destination type is vector"); |
| return; |
| } |
| InstIcmp::ICond Cond = Instr->getCondition(); |
| @@ -3648,14 +3756,13 @@ void TargetMIPS32::lowerInsertElement(const InstInsertElement *Instr) { |
| if (const auto *Imm = llvm::dyn_cast<ConstantInteger32>(Src2)) { |
| const uint32_t Index = Imm->getValue(); |
| // Vector to insert in |
| - auto *Src0 = Instr->getSrc(0); |
| + auto *Src0 = legalizeUndef(Instr->getSrc(0)); |
| auto *Src0R = llvm::dyn_cast<VariableVecOn32>(Src0); |
| // Number of elements in each container |
| uint32_t ElemPerCont = |
| - typeNumElements(Src0->getType()) / Src0R->ElementsPerContainer; |
| + typeNumElements(Src0->getType()) / Src0R->ContainersPerVector; |
| // Source Element |
| auto *SrcE = Src0R->getContainers()[Index / ElemPerCont]; |
| - Context.insert<InstFakeDef>(SrcE); |
| // Dest is a vector |
| auto *VDest = llvm::dyn_cast<VariableVecOn32>(Dest); |
| VDest->initVecElement(Func); |
| @@ -3675,7 +3782,7 @@ void TargetMIPS32::lowerInsertElement(const InstInsertElement *Instr) { |
| // Position of the element in the container |
| uint32_t PosInCont = Index % ElemPerCont; |
| // Load source vector in a temporary vector |
| - for (SizeT i = 0; i < TVDest->ElementsPerContainer; ++i) { |
| + for (SizeT i = 0; i < TVDest->ContainersPerVector; ++i) { |
| auto *DCont = TVDest->getContainers()[i]; |
| // Do not define DstE as we are going to redefine it |
| if (DCont == DstE) |
| @@ -4218,7 +4325,6 @@ OperandMIPS32Mem *TargetMIPS32::formAddressingMode(Type Ty, Cfg *Func, |
| } |
| if (isVectorType(Ty)) { |
| - UnimplementedError(getFlags()); |
| return nullptr; |
| } |
| @@ -4361,7 +4467,7 @@ void TargetMIPS32::lowerRet(const InstRet *Instr) { |
| Reg = getImplicitRet(); |
| auto *RegT = legalizeToReg(Reg); |
| // Return the vector through buffer in implicit argument a0 |
| - for (SizeT i = 0; i < SrcVec->ElementsPerContainer; ++i) { |
| + for (SizeT i = 0; i < SrcVec->ContainersPerVector; ++i) { |
| OperandMIPS32Mem *Mem = OperandMIPS32Mem::create( |
| Func, IceType_f32, RegT, |
| llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(i * 4))); |
| @@ -4387,7 +4493,7 @@ void TargetMIPS32::lowerSelect(const InstSelect *Instr) { |
| const Type DestTy = Dest->getType(); |
| if (isVectorType(DestTy)) { |
| - UnimplementedLoweringError(this, Instr); |
| + llvm::report_fatal_error("Select: Destination type is vector"); |
| return; |
| } |
| @@ -4459,7 +4565,7 @@ void TargetMIPS32::lowerStore(const InstStore *Instr) { |
| _sw(ValueLo, llvm::cast<OperandMIPS32Mem>(loOperand(NewAddr))); |
| } else if (isVectorType(Value->getType())) { |
| auto *DataVec = llvm::dyn_cast<VariableVecOn32>(Value); |
| - for (SizeT i = 0; i < DataVec->ElementsPerContainer; ++i) { |
| + for (SizeT i = 0; i < DataVec->ContainersPerVector; ++i) { |
| auto *DCont = legalizeToReg(DataVec->getContainers()[i]); |
| auto *MCont = llvm::cast<OperandMIPS32Mem>( |
| getOperandAtIndex(NewAddr, IceType_i32, i)); |