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

Unified Diff: src/PNaClTranslator.cpp

Issue 794823002: Remove using LLVM tools to check correctness of cast operation. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix issues in patch set 4. Created 6 years 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/IceInst.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/PNaClTranslator.cpp
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
index 639c0625a6bf02a9c16c3d87a15261fe588094aa..2940ca2318597d6e5dc67a18bb8a7a4972766f0f 100644
--- a/src/PNaClTranslator.cpp
+++ b/src/PNaClTranslator.cpp
@@ -1602,46 +1602,159 @@ private:
}
}
- /// Converts an LLVM cast opcode LLVMCastOp to the corresponding Ice
- /// cast opcode and assigns to CastKind. Returns true if successful,
- /// false otherwise.
- bool convertLLVMCastOpToIceOp(Instruction::CastOps LLVMCastOp,
- Ice::InstCast::OpKind &CastKind) const {
- switch (LLVMCastOp) {
- case Instruction::ZExt:
+ /// Simplifies out vector types from Type1 and Type2, if both are vectors
+ /// of the same size. Returns true iff both are vectors of the same size,
+ /// or are both scalar types.
+ static bool simplifyOutCommonVectorType(Ice::Type &Type1, Ice::Type &Type2) {
+ bool IsType1Vector = isVectorType(Type1);
+ bool IsType2Vector = isVectorType(Type2);
+ if (IsType1Vector != IsType2Vector)
+ return false;
+ if (!IsType1Vector)
+ return true;
+ if (typeNumElements(Type1) != typeNumElements(Type2))
+ return false;
+ Type1 = typeElementType(Type1);
+ Type2 = typeElementType(Type2);
+ return true;
+ }
+
+ /// Returns true iff an integer truncation from SourceType to TargetType is
+ /// valid.
+ static bool isIntTruncCastValid(Ice::Type SourceType, Ice::Type TargetType) {
+ return Ice::isIntegerType(SourceType)
+ && Ice::isIntegerType(TargetType)
+ && simplifyOutCommonVectorType(SourceType, TargetType)
+ && getScalarIntBitWidth(SourceType) > getScalarIntBitWidth(TargetType);
+ }
+
+ /// Returns true iff a floating type truncation from SourceType to TargetType
+ /// is valid.
+ static bool isFloatTruncCastValid(Ice::Type SourceType,
+ Ice::Type TargetType) {
+ return simplifyOutCommonVectorType(SourceType, TargetType)
+ && SourceType == Ice::IceType_f64
+ && TargetType == Ice::IceType_f32;
+ }
+
+ /// Returns true iff an integer extension from SourceType to TargetType is
+ /// valid.
+ static bool isIntExtCastValid(Ice::Type SourceType, Ice::Type TargetType) {
+ return isIntTruncCastValid(TargetType, SourceType);
+ }
+
+ /// Returns true iff a floating type extension from SourceType to TargetType
+ /// is valid.
+ static bool isFloatExtCastValid(Ice::Type SourceType, Ice::Type TargetType) {
+ return isFloatTruncCastValid(TargetType, SourceType);
+ }
+
+ /// Returns true iff a cast from floating type SourceType to integer
+ /// type TargetType is valid.
+ static bool isFloatToIntCastValid(Ice::Type SourceType,
+ Ice::Type TargetType) {
+ if (!(Ice::isFloatingType(SourceType) && Ice::isIntegerType(TargetType)))
+ return false;
+ bool IsSourceVector = isVectorType(SourceType);
+ bool IsTargetVector = isVectorType(TargetType);
+ if (IsSourceVector != IsTargetVector)
+ return false;
+ if (IsSourceVector) {
+ return typeNumElements(SourceType) == typeNumElements(TargetType);
+ }
+ return true;
+ }
+
+ /// Returns true iff a cast from integer type SourceType to floating
+ /// type TargetType is valid.
+ static bool isIntToFloatCastValid(Ice::Type SourceType,
+ Ice::Type TargetType) {
+ return isFloatToIntCastValid(TargetType, SourceType);
+ }
+
+ /// Returns the number of bits used to model type Ty when defining the
+ /// bitcast instruction.
+ static Ice::SizeT bitcastSizeInBits(Ice::Type Ty) {
+ if (Ice::isVectorType(Ty))
+ return Ice::typeNumElements(Ty) *
+ bitcastSizeInBits(Ice::typeElementType(Ty));
+ if (Ty == Ice::IceType_i1)
+ return 1;
+ return Ice::typeWidthInBytes(Ty) * CHAR_BIT;
+ }
+
+ /// Returns true iff a bitcast from SourceType to TargetType is allowed.
+ static bool isBitcastValid(Ice::Type SourceType, Ice::Type TargetType) {
+ return bitcastSizeInBits(SourceType) == bitcastSizeInBits(TargetType);
+ }
+
+ /// Returns true iff the NaCl bitcode Opcode is a valid cast opcode
+ /// for converting SourceType to TargetType. Updates CastKind to the
+ /// corresponding instruction cast opcode. Also generates an error
+ /// message when this function returns false.
+ bool convertCastOpToIceOp(uint64_t Opcode, Ice::Type SourceType,
+ Ice::Type TargetType,
+ Ice::InstCast::OpKind &CastKind) {
+ bool Result;
+ switch (Opcode) {
+ default: {
+ std::string Buffer;
+ raw_string_ostream StrBuf(Buffer);
+ StrBuf << "Cast opcode " << Opcode << " not understood.\n";
+ Error(StrBuf.str());
+ // TODO(kschimpf) Remove error recovery once implementation complete.
+ CastKind = Ice::InstCast::Bitcast;
+ return false;
+ }
+ case naclbitc::CAST_TRUNC:
+ CastKind = Ice::InstCast::Trunc;
+ Result = isIntTruncCastValid(SourceType, TargetType);
+ break;
+ case naclbitc::CAST_ZEXT:
CastKind = Ice::InstCast::Zext;
+ Result = isIntExtCastValid(SourceType, TargetType);
break;
- case Instruction::SExt:
+ case naclbitc::CAST_SEXT:
CastKind = Ice::InstCast::Sext;
+ Result = isIntExtCastValid(SourceType, TargetType);
break;
- case Instruction::Trunc:
- CastKind = Ice::InstCast::Trunc;
- break;
- case Instruction::FPTrunc:
- CastKind = Ice::InstCast::Fptrunc;
- break;
- case Instruction::FPExt:
- CastKind = Ice::InstCast::Fpext;
+ case naclbitc::CAST_FPTOUI:
+ CastKind = Ice::InstCast::Fptoui;
+ Result = isFloatToIntCastValid(SourceType, TargetType);
break;
- case Instruction::FPToSI:
+ case naclbitc::CAST_FPTOSI:
CastKind = Ice::InstCast::Fptosi;
+ Result = isFloatToIntCastValid(SourceType, TargetType);
break;
- case Instruction::FPToUI:
- CastKind = Ice::InstCast::Fptoui;
+ case naclbitc::CAST_UITOFP:
+ CastKind = Ice::InstCast::Uitofp;
+ Result = isIntToFloatCastValid(SourceType, TargetType);
break;
- case Instruction::SIToFP:
+ case naclbitc::CAST_SITOFP:
CastKind = Ice::InstCast::Sitofp;
+ Result = isIntToFloatCastValid(SourceType, TargetType);
break;
- case Instruction::UIToFP:
- CastKind = Ice::InstCast::Uitofp;
+ case naclbitc::CAST_FPTRUNC:
+ CastKind = Ice::InstCast::Fptrunc;
+ Result = isFloatTruncCastValid(SourceType, TargetType);
+ break;
+ case naclbitc::CAST_FPEXT:
+ CastKind = Ice::InstCast::Fpext;
+ Result = isFloatExtCastValid(SourceType, TargetType);
break;
- case Instruction::BitCast:
+ case naclbitc::CAST_BITCAST:
CastKind = Ice::InstCast::Bitcast;
+ Result = isBitcastValid(SourceType, TargetType);
break;
- default:
- return false;
}
- return true;
+ if (!Result) {
+ std::string Buffer;
+ raw_string_ostream StrBuf(Buffer);
+ StrBuf << "Illegal cast: " << Ice::InstCast::getCastName(CastKind) << " "
+ << SourceType << " to " << TargetType;
+ Error(StrBuf.str());
+ }
+ return Result;
}
// Converts PNaCl bitcode Icmp operator to corresponding ICE op.
@@ -1874,30 +1987,13 @@ void FunctionParser::ProcessRecord() {
return;
Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex);
Ice::Type CastType = Context->getSimpleTypeByID(Values[1]);
- Instruction::CastOps LLVMCastOp;
Ice::InstCast::OpKind CastKind;
- if (!naclbitc::DecodeCastOpcode(Values[2], LLVMCastOp) ||
- !convertLLVMCastOpToIceOp(LLVMCastOp, CastKind)) {
- std::string Buffer;
- raw_string_ostream StrBuf(Buffer);
- StrBuf << "Cast opcode not understood: " << Values[2];
- Error(StrBuf.str());
- appendErrorInstruction(CastType);
- return;
- }
if (isIRGenerationDisabled()) {
assert(Src == nullptr);
setNextLocalInstIndex(nullptr);
return;
}
- Ice::Type SrcType = Src->getType();
- if (!CastInst::castIsValid(LLVMCastOp, Context->convertToLLVMType(SrcType),
- Context->convertToLLVMType(CastType))) {
- std::string Buffer;
- raw_string_ostream StrBuf(Buffer);
- StrBuf << "Illegal cast: " << Instruction::getOpcodeName(LLVMCastOp)
- << " " << SrcType << " to " << CastType;
- Error(StrBuf.str());
+ if (!convertCastOpToIceOp(Values[2], Src->getType(), CastType, CastKind)) {
appendErrorInstruction(CastType);
return;
}
« no previous file with comments | « src/IceInst.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698