From: Chris Lattner Date: Sat, 16 Oct 2004 23:31:32 +0000 (+0000) Subject: Implement constant folding of undef values. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=71d3778c0b75a637c66704689bf624e9bd317521;p=oota-llvm.git Implement constant folding of undef values. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17070 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index a6ae0d5ac34..2e8ed54ec64 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -486,7 +486,8 @@ ConstRules &ConstRules::get(const Constant *V1, const Constant *V2) { static DirectFPRules DoubleR; if (isa(V1) || isa(V2) || - isa(V1) || isa(V2)) + isa(V1) || isa(V2) || + isa(V1) || isa(V2)) return EmptyR; switch (V1->getType()->getTypeID()) { @@ -525,15 +526,14 @@ Constant *llvm::ConstantFoldCastInstruction(const Constant *V, if (V->getType() == DestTy) return (Constant*)V; // Cast of a global address to boolean is always true. - if (const GlobalValue *GV = dyn_cast(V)) + if (const GlobalValue *GV = dyn_cast(V)) { if (DestTy == Type::BoolTy) // FIXME: When we support 'external weak' references, we have to prevent // this transformation from happening. In the meantime we avoid folding // any cast of an external symbol. if (!GV->isExternal()) return ConstantBool::True; - - if (const ConstantExpr *CE = dyn_cast(V)) + } else if (const ConstantExpr *CE = dyn_cast(V)) { if (CE->getOpcode() == Instruction::Cast) { Constant *Op = const_cast(CE->getOperand(0)); // Try to not produce a cast of a cast, which is almost always redundant. @@ -561,6 +561,9 @@ Constant *llvm::ConstantFoldCastInstruction(const Constant *V, if (isAllNull) return ConstantExpr::getCast(CE->getOperand(0), DestTy); } + } else if (isa(V)) { + return UndefValue::get(DestTy); + } // Check to see if we are casting an array of X to a pointer to X. If so, use // a GEP to get to the first element of the array instead of a cast! @@ -600,6 +603,10 @@ Constant *llvm::ConstantFoldSelectInstruction(const Constant *Cond, return const_cast(V1); else if (Cond == ConstantBool::False) return const_cast(V2); + + if (isa(V1)) return const_cast(V2); + if (isa(V2)) return const_cast(V1); + if (isa(Cond)) return const_cast(V1); return 0; } @@ -865,6 +872,49 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, break; } + if (isa(V1) || isa(V2)) { + switch (Opcode) { + case Instruction::Add: + case Instruction::Sub: + case Instruction::SetEQ: + case Instruction::SetNE: + case Instruction::SetLT: + case Instruction::SetLE: + case Instruction::SetGT: + case Instruction::SetGE: + case Instruction::Xor: + return UndefValue::get(V1->getType()); + + case Instruction::Mul: + case Instruction::And: + return Constant::getNullValue(V1->getType()); + case Instruction::Div: + case Instruction::Rem: + if (!isa(V2)) // undef/X -> 0 + return Constant::getNullValue(V1->getType()); + return const_cast(V2); // X/undef -> undef + case Instruction::Or: // X|undef -> -1 + return ConstantInt::getAllOnesValue(V1->getType()); + case Instruction::Shr: + if (!isa(V2)) { + if (V1->getType()->isSigned()) + return const_cast(V1); // undef >>s X -> undef + // undef >>u X -> 0 + } else if (isa(V1)) { + return const_cast(V1); // undef >> undef -> undef + } else { + if (V1->getType()->isSigned()) + return const_cast(V1); // X >>s undef -> X + // X >>u undef -> 0 + } + return Constant::getNullValue(V1->getType()); + + case Instruction::Shl: + // undef << X -> 0 X << undef -> 0 + return Constant::getNullValue(V1->getType()); + } + } + if (const ConstantExpr *CE1 = dyn_cast(V1)) { if (const ConstantExpr *CE2 = dyn_cast(V2)) { // There are many possible foldings we could do here. We should probably