aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Bitcode/NaCl/NaClLLVMBitCodes.h2
-rw-r--r--lib/Bitcode/NaCl/Reader/NaClBitcodeReader.cpp31
-rw-r--r--lib/Bitcode/NaCl/Writer/NaClBitcodeWriter.cpp6
-rw-r--r--test/NaCl/Bitcode/call-elide.ll18
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>