mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-03-02 09:16:40 +00: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:
parent
8e3ee5bc36
commit
75f2c3060c
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user