1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[Constants] extend getBinOpIdentity(); NFC

The enhanced version will be used in D48893 and related patches
and an almost identical (fadd is different) version is proposed 
in D28907, so adding this as a preliminary step.

llvm-svn: 336444
This commit is contained in:
Sanjay Patel 2018-07-06 15:18:58 +00:00
parent 8e3ee5bc36
commit 75f2c3060c
2 changed files with 50 additions and 28 deletions

View File

@ -1018,10 +1018,15 @@ public:
return getLShr(C1, C2, true);
}
/// Return the identity for the given binary operation,
/// i.e. a constant C such that X op C = X and C op X = X for every X. It
/// returns null if the operator doesn't have an identity.
static Constant *getBinOpIdentity(unsigned Opcode, Type *Ty);
/// Return the identity constant for a binary opcode.
/// The identity constant C is defined as X op C = X and C op X = X for every
/// X when the binary operation is commutative. If the binop is not
/// commutative, callers can acquire the operand 1 identity constant by
/// setting AllowRHSConstant to true. For example, any shift has a zero
/// identity constant for operand 1: X shift 0 = X.
/// Return nullptr if the operator does not have an identity constant.
static Constant *getBinOpIdentity(unsigned Opcode, Type *Ty,
bool AllowRHSConstant = false);
/// Return the absorbing element for the given binary
/// operation, i.e. a constant C such that X op C = C and C op X = C for

View File

@ -2271,32 +2271,49 @@ Constant *ConstantExpr::getAShr(Constant *C1, Constant *C2, bool isExact) {
isExact ? PossiblyExactOperator::IsExact : 0);
}
// FIXME: Add a parameter to specify the operand number for non-commutative ops.
// For example, the operand 1 identity constant for any shift is the null value
// because shift-by-0 always returns operand 0.
Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty) {
switch (Opcode) {
default:
// Doesn't have an identity.
Constant *ConstantExpr::getBinOpIdentity(unsigned Opcode, Type *Ty,
bool AllowRHSConstant) {
assert(Instruction::isBinaryOp(Opcode) && "Only binops allowed");
// Commutative opcodes: it does not matter if AllowRHSConstant is set.
if (Instruction::isCommutative(Opcode)) {
switch (Opcode) {
case Instruction::Add: // X + 0 = X
case Instruction::Or: // X | 0 = X
case Instruction::Xor: // X ^ 0 = X
return Constant::getNullValue(Ty);
case Instruction::Mul: // X * 1 = X
return ConstantInt::get(Ty, 1);
case Instruction::And: // X & -1 = X
return Constant::getAllOnesValue(Ty);
case Instruction::FAdd: // X + -0.0 = X
// TODO: If the fadd has 'nsz', should we return +0.0?
return ConstantFP::getNegativeZero(Ty);
case Instruction::FMul: // X * 1.0 = X
return ConstantFP::get(Ty, 1.0);
default:
llvm_unreachable("Every commutative binop has an identity constant");
}
}
// Non-commutative opcodes: AllowRHSConstant must be set.
if (!AllowRHSConstant)
return nullptr;
case Instruction::Add:
case Instruction::Or:
case Instruction::Xor:
return Constant::getNullValue(Ty);
case Instruction::Mul:
return ConstantInt::get(Ty, 1);
case Instruction::And:
return Constant::getAllOnesValue(Ty);
// TODO: If the fadd has 'nsz', should we return +0.0?
case Instruction::FAdd:
return ConstantFP::getNegativeZero(Ty);
case Instruction::FMul:
return ConstantFP::get(Ty, 1.0);
switch (Opcode) {
case Instruction::Sub: // X - 0 = X
case Instruction::Shl: // X << 0 = X
case Instruction::LShr: // X >>u 0 = X
case Instruction::AShr: // X >> 0 = X
case Instruction::FSub: // X - 0.0 = X
return Constant::getNullValue(Ty);
case Instruction::SDiv: // X / 1 = X
case Instruction::UDiv: // X /u 1 = X
return ConstantInt::get(Ty, 1);
case Instruction::FDiv: // X / 1.0 = X
return ConstantFP::get(Ty, 1.0);
default:
return nullptr;
}
}