From: Devang Patel Date: Thu, 21 Feb 2008 01:54:02 +0000 (+0000) Subject: Let function call return aggregate. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=bb4f8d40458eb086cb901e19c4be0777e2a73dce;p=oota-llvm.git Let function call return aggregate. Now, we have very first multiple return value testcase! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47424 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp index 7b9d7f02b37..440e0a63fdb 100644 --- a/lib/VMCore/Value.cpp +++ b/lib/VMCore/Value.cpp @@ -14,6 +14,7 @@ #include "llvm/Constant.h" #include "llvm/DerivedTypes.h" #include "llvm/InstrTypes.h" +#include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/ValueSymbolTable.h" #include "llvm/Support/Debug.h" @@ -33,7 +34,11 @@ static inline const Type *checkType(const Type *Ty) { Value::Value(const Type *ty, unsigned scid) : SubclassID(scid), SubclassData(0), Ty(checkType(ty)), UseList(0), Name(0) { - if (!isa(this) && !isa(this)) + if (isa(this)) + assert((Ty->isFirstClassType() || Ty == Type::VoidTy || + isa(ty) || Ty->getTypeID() == Type::StructTyID) && + "invalid CallInst type!"); + else if (!isa(this) && !isa(this)) assert((Ty->isFirstClassType() || Ty == Type::VoidTy || isa(ty)) && "Cannot create non-first-class values except for constants!"); diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 4bd2ba6c624..27adc089c38 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -1071,7 +1071,8 @@ void Verifier::visitInstruction(Instruction &I) { // Check that the return value of the instruction is either void or a legal // value type. - Assert1(I.getType() == Type::VoidTy || I.getType()->isFirstClassType(), + Assert1(I.getType() == Type::VoidTy || I.getType()->isFirstClassType() + || (isa(I) && I.getType()->getTypeID() == Type::StructTyID), "Instruction returns a non-scalar type!", &I); // Check that all uses of the instruction, if they are instructions @@ -1091,11 +1092,24 @@ void Verifier::visitInstruction(Instruction &I) { // Check to make sure that only first-class-values are operands to // instructions. - Assert1(I.getOperand(i)->getType()->isFirstClassType() - || (isa(I) - && I.getOperand(i)->getType()->getTypeID() == Type::StructTyID), - "Instruction operands must be first-class values!", &I); - + if (!I.getOperand(i)->getType()->isFirstClassType()) { + if (isa(I) || isa(I)) + Assert1(I.getOperand(i)->getType()->getTypeID() == Type::StructTyID, + "Invalid ReturnInst operands!", &I); + else if (isa(I)) { + if (const PointerType *PT = dyn_cast + (I.getOperand(i)->getType())) { + const Type *ETy = PT->getElementType(); + Assert1(ETy->getTypeID() == Type::StructTyID, + "Invalid CallInst operands!", &I); + } + else + Assert1(0, "Invalid CallInst operands!", &I); + } + else + Assert1(0, "Instruction operands must be first-class values!", &I); + } + if (Function *F = dyn_cast(I.getOperand(i))) { // Check to make sure that the "address of" an intrinsic function is never // taken. diff --git a/test/Assembler/2005-01-31-CallingAggregateFunction.ll b/test/Assembler/2005-01-31-CallingAggregateFunction.ll index ebe2ee9e76e..e6baf34a6c7 100644 --- a/test/Assembler/2005-01-31-CallingAggregateFunction.ll +++ b/test/Assembler/2005-01-31-CallingAggregateFunction.ll @@ -1,5 +1,4 @@ ; RUN: llvm-as < %s -o /dev/null -f -; XFAIL: * define void @test() { call {} @foo() diff --git a/test/Assembler/2008-02-20-MultipleReturnValue.ll b/test/Assembler/2008-02-20-MultipleReturnValue.ll new file mode 100644 index 00000000000..a40fa3ebcfc --- /dev/null +++ b/test/Assembler/2008-02-20-MultipleReturnValue.ll @@ -0,0 +1,12 @@ +; RUN: llvm-as < %s -disable-output + +define {i32, i8} @foo(i32 %p) { + ret i32 1, i8 2 +} + +define i8 @f2(i32 %p) { + %c = call {i32, i8} @foo(i32 %p) + %d = getresult {i32, i8} %c, 1 + %e = add i8 %d, 1 + ret i8 %e +}