diff options
author | Duncan Sands <baldrick@free.fr> | 2007-05-04 17:12:26 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2007-05-04 17:12:26 +0000 |
commit | 3b346368deddbe3cb853b29472de46bc9b58d6b8 (patch) | |
tree | 05451f33d0cdf239db897ed8adffe6b20775e921 | |
parent | e5b01bea7b9b7dce7c24484d2d915b0c118d4d07 (diff) |
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
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 56 |
1 files changed, 30 insertions, 26 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 2546314f91..93384fe833 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<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 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { // 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 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { 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 { |