mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-19 01:13:25 +00:00
div/rem by zero and div/rem overflow are both undefined according to
langref. Constant fold them to undef instead of trying to preserve the trap. This fixes PR3354. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62534 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
dbe664adcd
commit
c9a005807a
@ -655,11 +655,15 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
|
||||
case Instruction::SDiv:
|
||||
if (CI2->equalsInt(1))
|
||||
return const_cast<Constant*>(C1); // X / 1 == X
|
||||
if (CI2->equalsInt(0))
|
||||
return UndefValue::get(CI2->getType()); // X / 0 == undef
|
||||
break;
|
||||
case Instruction::URem:
|
||||
case Instruction::SRem:
|
||||
if (CI2->equalsInt(1))
|
||||
return Constant::getNullValue(CI2->getType()); // X % 1 == 0
|
||||
if (CI2->equalsInt(0))
|
||||
return UndefValue::get(CI2->getType()); // X % 0 == undef
|
||||
break;
|
||||
case Instruction::And:
|
||||
if (CI2->isZero()) return const_cast<Constant*>(C2); // X & 0 == 0
|
||||
@ -733,24 +737,20 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
|
||||
case Instruction::Mul:
|
||||
return ConstantInt::get(C1V * C2V);
|
||||
case Instruction::UDiv:
|
||||
if (CI2->isNullValue())
|
||||
return 0; // X / 0 -> can't fold
|
||||
assert(!CI2->isNullValue() && "Div by zero handled above");
|
||||
return ConstantInt::get(C1V.udiv(C2V));
|
||||
case Instruction::SDiv:
|
||||
if (CI2->isNullValue())
|
||||
return 0; // X / 0 -> can't fold
|
||||
assert(!CI2->isNullValue() && "Div by zero handled above");
|
||||
if (C2V.isAllOnesValue() && C1V.isMinSignedValue())
|
||||
return 0; // MIN_INT / -1 -> overflow
|
||||
return UndefValue::get(CI1->getType()); // MIN_INT / -1 -> undef
|
||||
return ConstantInt::get(C1V.sdiv(C2V));
|
||||
case Instruction::URem:
|
||||
if (C2->isNullValue())
|
||||
return 0; // X / 0 -> can't fold
|
||||
assert(!CI2->isNullValue() && "Div by zero handled above");
|
||||
return ConstantInt::get(C1V.urem(C2V));
|
||||
case Instruction::SRem:
|
||||
if (CI2->isNullValue())
|
||||
return 0; // X % 0 -> can't fold
|
||||
case Instruction::SRem:
|
||||
assert(!CI2->isNullValue() && "Div by zero handled above");
|
||||
if (C2V.isAllOnesValue() && C1V.isMinSignedValue())
|
||||
return 0; // MIN_INT % -1 -> overflow
|
||||
return UndefValue::get(CI1->getType()); // MIN_INT % -1 -> undef
|
||||
return ConstantInt::get(C1V.srem(C2V));
|
||||
case Instruction::And:
|
||||
return ConstantInt::get(C1V & C2V);
|
||||
|
Loading…
Reference in New Issue
Block a user