diff options
Diffstat (limited to 'lib/Bitcode')
-rw-r--r-- | lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp | 2 | ||||
-rw-r--r-- | lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp | 11 | ||||
-rw-r--r-- | lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp | 45 |
3 files changed, 42 insertions, 16 deletions
diff --git a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp index 994bf712ae..aac03678d1 100644 --- a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp +++ b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp @@ -1429,7 +1429,7 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) { if (OpNum != Record.size()) return Error("Invalid RET record"); - I = ReturnInst::Create(Context, Op); + I = ReturnInst::Create(Context, ConvertOpToScalar(Op, CurBBNo)); break; } case naclbitc::FUNC_CODE_INST_BR: { // BR: [bb#, bb#, opval] or [bb#] diff --git a/lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp b/lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp index ea5e9cde54..4a6a454796 100644 --- a/lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp +++ b/lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp @@ -718,7 +718,16 @@ static bool WriteInstruction(const Instruction &I, unsigned InstID, AbbrevToUse = FUNCTION_INST_CAST_ABBREV; pushValue(I.getOperand(0), InstID, Vals, VE, Stream); Vals.push_back(VE.getTypeID(I.getType())); - Vals.push_back(GetEncodedCastOpcode(I.getOpcode(), I)); + unsigned Opcode = I.getOpcode(); + Vals.push_back(GetEncodedCastOpcode(Opcode, I)); + if (PNaClVersion >= 2 && + (Opcode == Instruction::PtrToInt || + Opcode == Instruction::IntToPtr || + (Opcode == Instruction::BitCast && + (I.getOperand(0)->getType()->isPointerTy() || + I.getType()->isPointerTy())))) { + ReportIllegalValue("(PNaCl ABI) pointer cast", I); + } } else if (isa<BinaryOperator>(I)) { // BINOP: [opval, opval, opcode[, flags]] Code = naclbitc::FUNC_CODE_INST_BINOP; diff --git a/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp b/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp index 8cfdf13240..5dbc525eec 100644 --- a/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp +++ b/lib/Bitcode/NaCl/Writer/NaClValueEnumerator.cpp @@ -18,6 +18,7 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Module.h" #include "llvm/IR/ValueSymbolTable.h" #include "llvm/Support/Debug.h" @@ -466,11 +467,13 @@ static bool AllUsesExpectsNormalizedPtr(const Instruction *I2P) { return true; } -// Given Value that uses scalar value Arg, returns true if the bitcode -// writer can assume that Value always expects Arg to be scalar. This -// function is used to infer cases where PtrToInt casts can be -// removed. -static bool ExpectsScalarValue(const Value *V, const Instruction *Arg) { +// Given Value V that uses argument Arg, returns true if the bitcode +// writer can assume that V always expects Arg to be scalar. +// Assumes that the type of Arg is the integer type used to model +// pointers. Hence, this function determines if the reader would +// have to convert pointers to integer. This function +// is used to infer cases where PtrToInt casts can be removed. +static bool ExpectsIntPtrType(const Value *V, const Instruction *Arg) { const Instruction *I = dyn_cast<Instruction>(V); if (I == 0) return false; @@ -487,6 +490,7 @@ static bool ExpectsScalarValue(const Value *V, const Instruction *Arg) { case Instruction::UIToFP: case Instruction::SIToFP: case Instruction::ICmp: + case Instruction::Ret: return true; case Instruction::Store: return Arg == I->getOperand(0); @@ -495,8 +499,12 @@ static bool ExpectsScalarValue(const Value *V, const Instruction *Arg) { return Arg == Op->getTrueValue() || Arg == Op->getFalseValue(); } case Instruction::Call: { - // All operands (except the first, which must be a function pointer), - // can be scalar values. + // All operands (except the first, which must be a function + // pointer), must be scalar values. Note: For non-intrinsic + // calls, this is a requirement of the PNaCl ABI. For intrinsic + // calls, the condition that Arg's type is an integer type, + // implies that the intrinsic (for that argument) requires a + // scalar value at that position. const CallInst *Call = cast<CallInst>(I); return Call->getCalledValue() != Arg; } @@ -504,13 +512,12 @@ static bool ExpectsScalarValue(const Value *V, const Instruction *Arg) { } } -// Returns true if the bitcode reader and writer can assume that the -// uses of the given PtrToInt expect scalar values (i.e. non-pointer), -// and hence, we can elide the PtrToInt cast. -static bool AllUsesExpectsScalarValue(const Instruction *I) { +// Returns true if all uses of I expect I to be scalar, given that +// the type of I is the integer type used to represent pointers. +static bool AllUsesExpectsIntPtrType(const Instruction *I) { for (Value::const_use_iterator Use = I->use_begin(), UseEnd = I->use_end(); Use != UseEnd; ++Use) { - if (!ExpectsScalarValue(*Use, I)) return false; + if (!ExpectsIntPtrType(*Use, I)) return false; } // If reached, all uses expect a scalar value (and hence we know how // to automatically add it back), or there were no uses (and hence @@ -518,10 +525,20 @@ static bool AllUsesExpectsScalarValue(const Instruction *I) { return true; } +// Returns true if the value is an intrinsic instruction returns +// a pointer value. +static inline bool IsIntrinsicReturningPtr(const Value *V) { + if (const IntrinsicInst *ICall = dyn_cast<IntrinsicInst>(V)) { + return V->getType()->isPointerTy(); + } + return false; +} + // Returns true if the value is an InherentPtr (as defined in // llvm/lib/Transforms/NaCl/ReplacePtrsWithInts.cpp). static inline bool IsInherentPtr(const Value *V) { - return isa<AllocaInst>(V) || isa<GlobalValue>(V); + return isa<AllocaInst>(V) || isa<GlobalValue>(V) || + IsIntrinsicReturningPtr(V); } // Note: This function is based on the comments in @@ -547,7 +564,7 @@ const Value *NaClValueEnumerator::ElideCasts(const Value *V) { case Instruction::PtrToInt: if (IsIntPtrType(I->getType()) && IsInherentPtr(I->getOperand(0)) && - AllUsesExpectsScalarValue(I)) { + AllUsesExpectsIntPtrType(I)) { V = I->getOperand(0); } break; |