зеркало из https://github.com/dotnet/llilc.git
Merge pull request #360 from JosephTremoulet/DivideByZero
Insert divide-by-zero checks
This commit is contained in:
Коммит
922cfd76fc
|
@ -520,16 +520,16 @@ Once correct EH support is enabled and pushed back up to the master branch,
|
|||
EH-centric optimizations and support for other targets will follow.
|
||||
|
||||
The current status is that the stub EH support is implemented with support
|
||||
for explicit throws and some but not all implicit exceptions.
|
||||
for both explicit throws and implicit exceptions.
|
||||
|
||||
In summary, the plan/status is:
|
||||
1. [ ] Stub EH support
|
||||
1. [x] Stub EH support
|
||||
- [x] Reader discards catch/filter/fault handlers
|
||||
- [x] Explicit throw becomes helper call
|
||||
- [x] Continuation passing for finally handlers invoked by `leave`
|
||||
- [ ] Implicit exceptions expanded to explicit test/throw sequences
|
||||
- [x] Implicit exceptions expanded to explicit test/throw sequences
|
||||
- [x] Null dereference
|
||||
- [ ] Divide by zero
|
||||
- [x] Divide by zero
|
||||
- [x] Arithmetic overflow
|
||||
- [x] Convert with overflow
|
||||
- [x] Array bounds checks
|
||||
|
|
|
@ -1137,6 +1137,14 @@ protected:
|
|||
// could look like with null checks folded onto loads/stores.
|
||||
static const bool UseExplicitNullChecks = true;
|
||||
|
||||
// \brief Indicates that divide-by-zero checks use explicit compare+branch IR
|
||||
//
|
||||
// Compiling with this set to false isn't really supported (the generated IR
|
||||
// would not have sufficient EH annotations), but it is provided as a mock
|
||||
// configuration flag to facilitate experimenting with what the IR/codegen
|
||||
// could look like with divide-by-zero checks folded onto divides.
|
||||
static const bool UseExplicitZeroDivideChecks = true;
|
||||
|
||||
// Verification Info
|
||||
public:
|
||||
bool VerificationNeeded;
|
||||
|
|
|
@ -2321,6 +2321,21 @@ IRNode *GenIR::binaryOp(ReaderBaseNS::BinaryOpcode Opcode, IRNode *Arg1,
|
|||
} else {
|
||||
// Create a simple binary operation.
|
||||
Instruction::BinaryOps Op = Triple[Opcode].Op.Opcode;
|
||||
|
||||
if ((Op == Instruction::BinaryOps::SDiv) ||
|
||||
(Op == Instruction::BinaryOps::UDiv)) {
|
||||
// Integer divide throws a DivideByZeroException on 0 denominator
|
||||
if (UseExplicitZeroDivideChecks) {
|
||||
Value *IsZero = LLVMBuilder->CreateIsNull(Arg2);
|
||||
genConditionalThrow(IsZero, CORINFO_HELP_THROWDIVZERO,
|
||||
"ThrowDivideByZero");
|
||||
} else {
|
||||
// This configuration isn't really supported. To support it we'd
|
||||
// need to annotate the divide we're about to generate as possibly
|
||||
// throwing an exception (that would be raised from a machine trap).
|
||||
}
|
||||
}
|
||||
|
||||
Result = (IRNode *)LLVMBuilder->CreateBinOp(Op, Arg1, Arg2);
|
||||
}
|
||||
return Result;
|
||||
|
|
Загрузка…
Ссылка в новой задаче