The eh_selector, eh_filter and eh_typeid_for intrinsics take
arguments that should be a global variable or a bitcast of a
global variable.  A bitcast of a global variable can be constant
folded to a GEP in some cases, causing the current code to assert.
The attached patch fixes this.

Best wishes,

Duncan.
Index: llvm.master/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
===================================================================
--- llvm.master.orig/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	2007-05-03 18:55:35.000000000 +0200
+++ llvm.master/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	2007-05-03 18:57:17.000000000 +0200
@@ -2457,6 +2457,24 @@
   }
 }
 
+/// ExtractGlobalVariable - If C is a global variable, or a bitcast of one
+/// (possibly constant folded), return it.  Otherwise return NULL.
+static GlobalVariable *ExtractGlobalVariable (Constant *C) {
+  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C))
+    return GV;
+  else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+    if (CE->getOpcode() == Instruction::BitCast)
+      return dyn_cast<GlobalVariable>(CE->getOperand(0));
+    else if (CE->getOpcode() == Instruction::GetElementPtr) {
+      for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i)
+        if (!CE->getOperand(i)->isNullValue())
+          return NULL;
+      return dyn_cast<GlobalVariable>(CE->getOperand(0));
+    }
+  }
+  return NULL;
+}
+
 /// visitIntrinsicCall - Lower the call to the specified intrinsic function.  If
 /// we want to emit this as a call to a named external function, return the name
 /// otherwise lower it and return null.
@@ -2610,20 +2628,12 @@
       // MachineModuleInfo.
       std::vector<GlobalVariable *> TyInfo;
       for (unsigned i = 3, N = I.getNumOperands(); i < N; ++i) {
-        Constant *C = cast<Constant>(I.getOperand(i));
-        if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
-          TyInfo.push_back(GV);
-        } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
-          assert(CE->getOpcode() == Instruction::BitCast &&
-                 isa<GlobalVariable>(CE->getOperand(0))
-                 && "TypeInfo must be a global variable or NULL");
-          TyInfo.push_back(cast<GlobalVariable>(CE->getOperand(0)));
-        } else {
-          ConstantInt *CI = dyn_cast<ConstantInt>(C);
-          assert(CI && CI->isNullValue() &&
-                 "TypeInfo must be a global variable or NULL");
-          TyInfo.push_back(NULL);
-        }
+	Constant *C = cast<Constant>(I.getOperand(i));
+        GlobalVariable *GV = ExtractGlobalVariable(C);
+        assert (GV || (isa<ConstantInt>(C) &&
+                       cast<ConstantInt>(C)->isNullValue()) &&
+                "TypeInfo must be a global variable or NULL");
+        TyInfo.push_back(GV);
       }
       MMI->addCatchTypeInfo(CurMBB, TyInfo);
       
@@ -2651,18 +2661,12 @@
     
     if (MMI) {
       // Find the type id for the given typeinfo.
-      GlobalVariable *GV = NULL;
-      ConstantExpr *CE = dyn_cast<ConstantExpr>(I.getOperand(1));
-      if (CE && CE->getOpcode() == Instruction::BitCast &&
-          isa<GlobalVariable>(CE->getOperand(0))) {
-        GV = cast<GlobalVariable>(CE->getOperand(0));
-      } else {
-        ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1));
-        assert(CI && CI->getZExtValue() == 0 &&
-          "TypeInfo must be a global variable typeinfo or NULL");
-        GV = NULL;
-      }
-      
+      Constant *C = cast<Constant>(I.getOperand(1));
+      GlobalVariable *GV = ExtractGlobalVariable(C);
+      assert (GV || (isa<ConstantInt>(C) &&
+                     cast<ConstantInt>(C)->isNullValue()) &&
+              "TypeInfo must be a global variable or NULL");
+
       unsigned TypeID = MMI->getTypeIDFor(GV);
       setValue(&I, DAG.getConstant(TypeID, MVT::i32));
     } else {
Index: llvm.master/test/CodeGen/Generic/2007-05-03-EHTypeInfo.ll
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ llvm.master/test/CodeGen/Generic/2007-05-03-EHTypeInfo.ll	2007-05-03 20:28:54.000000000 +0200
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | llc -enable-eh
+
+	%struct.exception = type { i8, i8, i32, i8*, i8*, i32, i8* }
[EMAIL PROTECTED] = external global %struct.exception		; <%struct.exception*> [#uses=1]
+
+define void @typeinfo() {
+entry:
+	%eh_typeid = tail call i32 @llvm.eh.typeid.for( i8* getelementptr (%struct.exception* @program_error, i32 0, i32 0) )		; <i32> [#uses=0]
+	ret void
+}
+
+declare i32 @llvm.eh.typeid.for(i8*)
_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to