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

Unified Diff: src/IceTargetLoweringMIPS32.cpp

Issue 2412053002: [SubZero] Implement Fcmp, ICmp, Cast and Select for vector type (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: 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
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));

Powered by Google App Engine
This is Rietveld 408576698