mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-04 17:56:53 +00:00
Implement constant folding of undef values.
llvm-svn: 17070
This commit is contained in:
parent
68f14bc09c
commit
8c86882a99
@ -486,7 +486,8 @@ ConstRules &ConstRules::get(const Constant *V1, const Constant *V2) {
|
||||
static DirectFPRules <ConstantFP , double , &Type::DoubleTy> DoubleR;
|
||||
|
||||
if (isa<ConstantExpr>(V1) || isa<ConstantExpr>(V2) ||
|
||||
isa<GlobalValue>(V1) || isa<GlobalValue>(V2))
|
||||
isa<GlobalValue>(V1) || isa<GlobalValue>(V2) ||
|
||||
isa<UndefValue>(V1) || isa<UndefValue>(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<GlobalValue>(V))
|
||||
if (const GlobalValue *GV = dyn_cast<GlobalValue>(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<ConstantExpr>(V))
|
||||
} else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
|
||||
if (CE->getOpcode() == Instruction::Cast) {
|
||||
Constant *Op = const_cast<Constant*>(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<UndefValue>(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<Constant*>(V1);
|
||||
else if (Cond == ConstantBool::False)
|
||||
return const_cast<Constant*>(V2);
|
||||
|
||||
if (isa<UndefValue>(V1)) return const_cast<Constant*>(V2);
|
||||
if (isa<UndefValue>(V2)) return const_cast<Constant*>(V1);
|
||||
if (isa<UndefValue>(Cond)) return const_cast<Constant*>(V1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -865,6 +872,49 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
|
||||
break;
|
||||
}
|
||||
|
||||
if (isa<UndefValue>(V1) || isa<UndefValue>(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<UndefValue>(V2)) // undef/X -> 0
|
||||
return Constant::getNullValue(V1->getType());
|
||||
return const_cast<Constant*>(V2); // X/undef -> undef
|
||||
case Instruction::Or: // X|undef -> -1
|
||||
return ConstantInt::getAllOnesValue(V1->getType());
|
||||
case Instruction::Shr:
|
||||
if (!isa<UndefValue>(V2)) {
|
||||
if (V1->getType()->isSigned())
|
||||
return const_cast<Constant*>(V1); // undef >>s X -> undef
|
||||
// undef >>u X -> 0
|
||||
} else if (isa<UndefValue>(V1)) {
|
||||
return const_cast<Constant*>(V1); // undef >> undef -> undef
|
||||
} else {
|
||||
if (V1->getType()->isSigned())
|
||||
return const_cast<Constant*>(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<ConstantExpr>(V1)) {
|
||||
if (const ConstantExpr *CE2 = dyn_cast<ConstantExpr>(V2)) {
|
||||
// There are many possible foldings we could do here. We should probably
|
||||
|
Loading…
Reference in New Issue
Block a user