Fix constant fold of div by zero and rem by zero to match IEEE 754

requirements. We must return NaN in some cases and correctly signed
infinity in other cases. Passes CFP2006 (not that that says much).

llvm-svn: 35277
This commit is contained in:
Reid Spencer 2007-03-23 05:33:23 +00:00
parent 0900993ebc
commit d96dc9020a
1 changed files with 18 additions and 8 deletions

View File

@ -651,17 +651,27 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
case Instruction::Mul:
return ConstantFP::get(CFP1->getType(), C1Val * C2Val);
case Instruction::FDiv:
if (CFP2->isExactlyValue(0.0))
return ConstantFP::get(CFP1->getType(),
std::numeric_limits<double>::infinity());
if (CFP2->isExactlyValue(-0.0))
return ConstantFP::get(CFP1->getType(),
-std::numeric_limits<double>::infinity());
if (CFP2->isExactlyValue(0.0) || CFP2->isExactlyValue(-0.0))
if (CFP1->isExactlyValue(0.0) || CFP1->isExactlyValue(-0.0))
// IEEE 754, Section 7.1, #4
return ConstantFP::get(CFP1->getType(),
std::numeric_limits<double>::quiet_NaN());
else if (CFP2->isExactlyValue(-0.0) || C1Val < 0.0)
// IEEE 754, Section 7.2, negative infinity case
return ConstantFP::get(CFP1->getType(),
-std::numeric_limits<double>::infinity());
else
// IEEE 754, Section 7.2, positive infinity case
return ConstantFP::get(CFP1->getType(),
std::numeric_limits<double>::infinity());
return ConstantFP::get(CFP1->getType(), C1Val / C2Val);
case Instruction::FRem:
if (CFP2->isNullValue())
return 0;
if (CFP2->isExactlyValue(0.0) || CFP2->isExactlyValue(-0.0))
// IEEE 754, Section 7.1, #5
return ConstantFP::get(CFP1->getType(),
std::numeric_limits<double>::quiet_NaN());
return ConstantFP::get(CFP1->getType(), std::fmod(C1Val, C2Val));
}
}
} else if (const ConstantVector *CP1 = dyn_cast<ConstantVector>(C1)) {