From 3b346368deddbe3cb853b29472de46bc9b58d6b8 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 4 May 2007 17:12:26 +0000 Subject: [PATCH] A bitcast of a global variable may have been constant folded to a GEP - handle this case too. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36745 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 56 ++++++++++--------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 2546314f91b..93384fe8337 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2457,6 +2457,24 @@ void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I, } } +/// 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(C)) + return GV; + else if (ConstantExpr *CE = dyn_cast(C)) { + if (CE->getOpcode() == Instruction::BitCast) + return dyn_cast(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(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 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { // MachineModuleInfo. std::vector TyInfo; for (unsigned i = 3, N = I.getNumOperands(); i < N; ++i) { - Constant *C = cast(I.getOperand(i)); - if (GlobalVariable *GV = dyn_cast(C)) { - TyInfo.push_back(GV); - } else if (ConstantExpr *CE = dyn_cast(C)) { - assert(CE->getOpcode() == Instruction::BitCast && - isa(CE->getOperand(0)) - && "TypeInfo must be a global variable or NULL"); - TyInfo.push_back(cast(CE->getOperand(0))); - } else { - ConstantInt *CI = dyn_cast(C); - assert(CI && CI->isNullValue() && - "TypeInfo must be a global variable or NULL"); - TyInfo.push_back(NULL); - } + Constant *C = cast(I.getOperand(i)); + GlobalVariable *GV = ExtractGlobalVariable(C); + assert (GV || (isa(C) && + cast(C)->isNullValue()) && + "TypeInfo must be a global variable or NULL"); + TyInfo.push_back(GV); } MMI->addCatchTypeInfo(CurMBB, TyInfo); @@ -2651,18 +2661,12 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { if (MMI) { // Find the type id for the given typeinfo. - GlobalVariable *GV = NULL; - ConstantExpr *CE = dyn_cast(I.getOperand(1)); - if (CE && CE->getOpcode() == Instruction::BitCast && - isa(CE->getOperand(0))) { - GV = cast(CE->getOperand(0)); - } else { - ConstantInt *CI = dyn_cast(I.getOperand(1)); - assert(CI && CI->getZExtValue() == 0 && - "TypeInfo must be a global variable typeinfo or NULL"); - GV = NULL; - } - + Constant *C = cast(I.getOperand(1)); + GlobalVariable *GV = ExtractGlobalVariable(C); + assert (GV || (isa(C) && + cast(C)->isNullValue()) && + "TypeInfo must be a global variable or NULL"); + unsigned TypeID = MMI->getTypeIDFor(GV); setValue(&I, DAG.getConstant(TypeID, MVT::i32)); } else {