diff options
-rw-r--r-- | include/llvm/Bitcode/NaCl/NaClLLVMBitCodes.h | 2 | ||||
-rw-r--r-- | lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp | 31 | ||||
-rw-r--r-- | lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp | 6 | ||||
-rw-r--r-- | test/NaCl/Bitcode/call-elide.ll | 18 |
4 files changed, 30 insertions, 27 deletions
diff --git a/include/llvm/Bitcode/NaCl/NaClLLVMBitCodes.h b/include/llvm/Bitcode/NaCl/NaClLLVMBitCodes.h index 384b03661e..2e3cd21652 100644 --- a/include/llvm/Bitcode/NaCl/NaClLLVMBitCodes.h +++ b/include/llvm/Bitcode/NaCl/NaClLLVMBitCodes.h @@ -331,7 +331,7 @@ namespace naclbitc { FUNC_CODE_INST_LOADATOMIC = 41, // Not used in PNaCl. FUNC_CODE_INST_STOREATOMIC = 42, // Not used in PNaCl. FUNC_CODE_INST_FORWARDTYPEREF = 43, // TYPE: [opval, ty] - // PNaCl version 2+: CALL_INDIRECT: [cc, fnid, fnty, args...] + // PNaCl version 2+: CALL_INDIRECT: [cc, fnid, returnty, args...] FUNC_CODE_INST_CALL_INDIRECT = 44 }; } // End naclbitc namespace diff --git a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp index eaaa85a164..29a842c948 100644 --- a/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp +++ b/lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp @@ -1626,16 +1626,11 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) { // Build function type for call. FunctionType *FTy = 0; + Type *ReturnType = 0; if (BitCode == naclbitc::FUNC_CODE_INST_CALL_INDIRECT) { // Callee type has been elided, add back in. - Type *Type = getTypeByID(Record[2]); + ReturnType = getTypeByID(Record[2]); ++OpNum; - if (FunctionType *FcnType = dyn_cast<FunctionType>(Type)) { - FTy = FcnType; - Callee = ConvertOpToType(Callee, FcnType->getPointerTo(), CurBBNo); - } else { - return Error("Invalid type for CALL_INDIRECT record"); - } } else { // Get type signature from callee. if (PointerType *OpTy = dyn_cast<PointerType>(Callee->getType())) { @@ -1646,7 +1641,7 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) { } unsigned NumParams = Record.size() - OpNum; - if (NumParams != FTy->getNumParams()) + if (FTy && NumParams != FTy->getNumParams()) return Error("Invalid CALL record"); // Process call arguments. @@ -1655,14 +1650,26 @@ bool NaClBitcodeReader::ParseFunctionBody(Function *F) { Value *Arg; if (popValue(Record, &OpNum, NextValueNo, &Arg)) Error("Invalid argument in CALL record"); - if (BitCode == naclbitc::FUNC_CODE_INST_CALL_INDIRECT && - FTy->getParamType(Index)->isPointerTy()) { - return Error("Pointer arguments not allowed for indirect calls"); + if (FTy) { + // Add a cast, to a pointer type if necessary, in case this + // is an intrinsic call that takes a pointer argument. + Arg = ConvertOpToType(Arg, FTy->getParamType(Index), CurBBNo); + } else { + Arg = ConvertOpToScalar(Arg, CurBBNo); } - Arg = ConvertOpToType(Arg, FTy->getParamType(Index), CurBBNo); Args.push_back(Arg); } + if (FTy == 0) { + // Reconstruct the function type and cast the function pointer + // to it. + SmallVector<Type*, 6> ArgTypes; + for (unsigned Index = 0; Index < NumParams; ++Index) + ArgTypes.push_back(Args[Index]->getType()); + FTy = FunctionType::get(ReturnType, ArgTypes, false); + Callee = ConvertOpToType(Callee, FTy->getPointerTo(), CurBBNo); + } + // Construct call. I = CallInst::Create(Callee, Args); cast<CallInst>(I)->setCallingConv(GetDecodedCallingConv(CCInfo>>1)); diff --git a/lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp b/lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp index 166a95bb23..4288aceb06 100644 --- a/lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp +++ b/lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp @@ -893,11 +893,7 @@ static bool WriteInstruction(const Instruction &I, unsigned InstID, // not known. Hence, we must send the type signature to the // reader. Code = naclbitc::FUNC_CODE_INST_CALL_INDIRECT; - PointerType *FcnPtrType = - cast<PointerType>(Callee->getType()); - FunctionType *FcnType = - cast<FunctionType>(FcnPtrType->getElementType()); - Vals.push_back(VE.getTypeID(FcnType)); + Vals.push_back(VE.getTypeID(I.getType())); } } diff --git a/test/NaCl/Bitcode/call-elide.ll b/test/NaCl/Bitcode/call-elide.ll index adcd32a904..d7b93516cd 100644 --- a/test/NaCl/Bitcode/call-elide.ll +++ b/test/NaCl/Bitcode/call-elide.ll @@ -226,7 +226,7 @@ define void @IndirectCall(i32 %i) { ; PF2: <FUNCTION_BLOCK> ; PF2-NEXT: <DECLAREBLOCKS op0=1/> -; PF2-NEXT: <INST_CALL_INDIRECT op0=0 op1=1 op2=2 op3=1/> +; PF2-NEXT: <INST_CALL_INDIRECT op0=0 op1=1 op2=1 op3=1/> ; PF2-NEXT: <INST_RET/> ; PF2: </FUNCTION_BLOCK> @@ -260,16 +260,16 @@ define void @IndirectCallPtrToIntArg(i32 %i) { ; TD2: define void @IndirectCallPtrToIntArg(i32 %i) { ; TD2-NEXT: %1 = alloca i8, i32 4, align 8 -; TD2-NEXT: %2 = inttoptr i32 %i to void (i32)* -; TD2-NEXT: %3 = ptrtoint i8* %1 to i32 -; TD2-NEXT: call void %2(i32 %3) +; TD2-NEXT: %2 = ptrtoint i8* %1 to i32 +; TD2-NEXT: %3 = inttoptr i32 %i to void (i32)* +; TD2-NEXT: call void %3(i32 %2) ; TD2-NEXT: ret void ; TD2-NEXT: } ; PF2: <FUNCTION_BLOCK> ; PF2: </CONSTANTS_BLOCK> ; PF2-NEXT: <INST_ALLOCA op0=1 op1=4/> -; PF2-NEXT: <INST_CALL_INDIRECT op0=0 op1=3 op2=2 op3=1/> +; PF2-NEXT: <INST_CALL_INDIRECT op0=0 op1=3 op2=1 op3=1/> ; PF2-NEXT: <INST_RET/> ; PF2: </FUNCTION_BLOCK> @@ -299,15 +299,15 @@ define void @IndirectCallScalarArg(i32 %i, i32* %ptr) { ; PF1: </FUNCTION_BLOCK> ; TD2: define void @IndirectCallScalarArg(i32 %i, i32* %ptr) { -; TD2-NEXT: %1 = inttoptr i32 %i to void (i32)* -; TD2-NEXT: %2 = ptrtoint [4 x i8]* @bytes to i32 -; TD2-NEXT: call void %1(i32 %2) +; TD2-NEXT: %1 = ptrtoint [4 x i8]* @bytes to i32 +; TD2-NEXT: %2 = inttoptr i32 %i to void (i32)* +; TD2-NEXT: call void %2(i32 %1) ; TD2-NEXT: ret void ; TD2-NEXT: } ; PF2: <FUNCTION_BLOCK> ; PF2-NEXT: <DECLAREBLOCKS op0=1/> -; PF2-NEXT: <INST_CALL_INDIRECT op0=0 op1=2 op2=2 op3=3/> +; PF2-NEXT: <INST_CALL_INDIRECT op0=0 op1=2 op2=1 op3=3/> ; PF2-NEXT: <INST_RET/> ; PF2: </FUNCTION_BLOCK> |