Commit bf170370 by Karl Schimpf

Remove using LLVM tools to check correctness of cast operation.

Removes cast instruction checks (in PNaClTranslator.cpp) that used LLVM utilities to use locally defined methods instead. Remove the need to call naclbitc::DecodeCastOpcode and CastInst::castIsValid. Also removes two more calls to convertToLLVMType. BUG= None R=jvoung@chromium.org, stichnot@chromium.org Review URL: https://codereview.chromium.org/794823002
parent e5b73e6e
...@@ -619,13 +619,21 @@ void InstCall::dump(const Cfg *Func) const { ...@@ -619,13 +619,21 @@ void InstCall::dump(const Cfg *Func) const {
Str << ")"; Str << ")";
} }
const char *InstCast::getCastName(InstCast::OpKind Kind) {
size_t Index = static_cast<size_t>(Kind);
if (Index < InstCast::OpKind::_num)
return InstCastAttributes[Index].DisplayString;
llvm_unreachable("Invalid InstCast::OpKind");
return "???";
}
void InstCast::dump(const Cfg *Func) const { void InstCast::dump(const Cfg *Func) const {
if (!ALLOW_DUMP) if (!ALLOW_DUMP)
return; return;
Ostream &Str = Func->getContext()->getStrDump(); Ostream &Str = Func->getContext()->getStrDump();
dumpDest(Func); dumpDest(Func);
Str << " = " << InstCastAttributes[getCastKind()].DisplayString << " " Str << " = " << getCastName(getCastKind()) << " " << getSrc(0)->getType()
<< getSrc(0)->getType() << " "; << " ";
dumpSources(Func); dumpSources(Func);
Str << " to " << getDest()->getType(); Str << " to " << getDest()->getType();
} }
......
...@@ -402,6 +402,8 @@ public: ...@@ -402,6 +402,8 @@ public:
_num _num
}; };
static const char *getCastName(OpKind Kind);
static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest, static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest,
Operand *Source) { Operand *Source) {
return new (Func->allocateInst<InstCast>()) return new (Func->allocateInst<InstCast>())
......
...@@ -1603,46 +1603,159 @@ private: ...@@ -1603,46 +1603,159 @@ private:
} }
} }
/// Converts an LLVM cast opcode LLVMCastOp to the corresponding Ice /// Simplifies out vector types from Type1 and Type2, if both are vectors
/// cast opcode and assigns to CastKind. Returns true if successful, /// of the same size. Returns true iff both are vectors of the same size,
/// false otherwise. /// or are both scalar types.
bool convertLLVMCastOpToIceOp(Instruction::CastOps LLVMCastOp, static bool simplifyOutCommonVectorType(Ice::Type &Type1, Ice::Type &Type2) {
Ice::InstCast::OpKind &CastKind) const { bool IsType1Vector = isVectorType(Type1);
switch (LLVMCastOp) { bool IsType2Vector = isVectorType(Type2);
case Instruction::ZExt: 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; CastKind = Ice::InstCast::Zext;
Result = isIntExtCastValid(SourceType, TargetType);
break; break;
case Instruction::SExt: case naclbitc::CAST_SEXT:
CastKind = Ice::InstCast::Sext; CastKind = Ice::InstCast::Sext;
Result = isIntExtCastValid(SourceType, TargetType);
break; break;
case Instruction::Trunc: case naclbitc::CAST_FPTOUI:
CastKind = Ice::InstCast::Trunc; CastKind = Ice::InstCast::Fptoui;
break; Result = isFloatToIntCastValid(SourceType, TargetType);
case Instruction::FPTrunc:
CastKind = Ice::InstCast::Fptrunc;
break;
case Instruction::FPExt:
CastKind = Ice::InstCast::Fpext;
break; break;
case Instruction::FPToSI: case naclbitc::CAST_FPTOSI:
CastKind = Ice::InstCast::Fptosi; CastKind = Ice::InstCast::Fptosi;
Result = isFloatToIntCastValid(SourceType, TargetType);
break; break;
case Instruction::FPToUI: case naclbitc::CAST_UITOFP:
CastKind = Ice::InstCast::Fptoui; CastKind = Ice::InstCast::Uitofp;
Result = isIntToFloatCastValid(SourceType, TargetType);
break; break;
case Instruction::SIToFP: case naclbitc::CAST_SITOFP:
CastKind = Ice::InstCast::Sitofp; CastKind = Ice::InstCast::Sitofp;
Result = isIntToFloatCastValid(SourceType, TargetType);
break; break;
case Instruction::UIToFP: case naclbitc::CAST_FPTRUNC:
CastKind = Ice::InstCast::Uitofp; CastKind = Ice::InstCast::Fptrunc;
Result = isFloatTruncCastValid(SourceType, TargetType);
break;
case naclbitc::CAST_FPEXT:
CastKind = Ice::InstCast::Fpext;
Result = isFloatExtCastValid(SourceType, TargetType);
break; break;
case Instruction::BitCast: case naclbitc::CAST_BITCAST:
CastKind = Ice::InstCast::Bitcast; CastKind = Ice::InstCast::Bitcast;
Result = isBitcastValid(SourceType, TargetType);
break; 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. // Converts PNaCl bitcode Icmp operator to corresponding ICE op.
...@@ -1875,30 +1988,13 @@ void FunctionParser::ProcessRecord() { ...@@ -1875,30 +1988,13 @@ void FunctionParser::ProcessRecord() {
return; return;
Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex); Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex);
Ice::Type CastType = Context->getSimpleTypeByID(Values[1]); Ice::Type CastType = Context->getSimpleTypeByID(Values[1]);
Instruction::CastOps LLVMCastOp;
Ice::InstCast::OpKind CastKind; 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()) { if (isIRGenerationDisabled()) {
assert(Src == nullptr); assert(Src == nullptr);
setNextLocalInstIndex(nullptr); setNextLocalInstIndex(nullptr);
return; return;
} }
Ice::Type SrcType = Src->getType(); if (!convertCastOpToIceOp(Values[2], Src->getType(), CastType, CastKind)) {
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());
appendErrorInstruction(CastType); appendErrorInstruction(CastType);
return; return;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment