Let function call return aggregate.
authorDevang Patel <dpatel@apple.com>
Thu, 21 Feb 2008 01:54:02 +0000 (01:54 +0000)
committerDevang Patel <dpatel@apple.com>
Thu, 21 Feb 2008 01:54:02 +0000 (01:54 +0000)
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

lib/VMCore/Value.cpp
lib/VMCore/Verifier.cpp
test/Assembler/2005-01-31-CallingAggregateFunction.ll
test/Assembler/2008-02-20-MultipleReturnValue.ll [new file with mode: 0644]

index 7b9d7f02b37b963f6208e533505f31f46729773d..440e0a63fdbce50ebef987fedd43d95305097e9f 100644 (file)
@@ -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<Constant>(this) && !isa<BasicBlock>(this))
+  if (isa<CallInst>(this))
+    assert((Ty->isFirstClassType() || Ty == Type::VoidTy ||
+            isa<OpaqueType>(ty) || Ty->getTypeID() == Type::StructTyID) &&
+           "invalid CallInst  type!");
+  else if (!isa<Constant>(this) && !isa<BasicBlock>(this))
     assert((Ty->isFirstClassType() || Ty == Type::VoidTy ||
            isa<OpaqueType>(ty)) &&
            "Cannot create non-first-class values except for constants!");
index 4bd2ba6c624e97ce78a56ec2050dc07697804741..27adc089c381f3d002758f1477c7e0b7edb2ebe0 100644 (file)
@@ -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<CallInst>(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<ReturnInst>(I) 
-                && I.getOperand(i)->getType()->getTypeID() == Type::StructTyID),
-            "Instruction operands must be first-class values!", &I);
-  
+    if (!I.getOperand(i)->getType()->isFirstClassType()) {
+      if (isa<ReturnInst>(I) || isa<GetResultInst>(I))
+        Assert1(I.getOperand(i)->getType()->getTypeID() == Type::StructTyID,
+                "Invalid ReturnInst operands!", &I);
+      else if (isa<CallInst>(I)) {
+        if (const PointerType *PT = dyn_cast<PointerType>
+            (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<Function>(I.getOperand(i))) {
       // Check to make sure that the "address of" an intrinsic function is never
       // taken.
index ebe2ee9e76ef16bd8c801e168212e9642d12a498..e6baf34a6c74b8f95eb0e4a854020fdacea341f6 100644 (file)
@@ -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 (file)
index 0000000..a40fa3e
--- /dev/null
@@ -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
+}