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