[llvm] r336444 - [Constants] extend getBinOpIdentity(); NFC
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 6 08:18:58 PDT 2018
Author: spatel
Date: Fri Jul 6 08:18:58 2018
New Revision: 336444
URL: http://llvm.org/viewvc/llvm-project?rev=336444&view=rev
Log:
[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.
Modified:
llvm/trunk/include/llvm/IR/Constants.h
llvm/trunk/lib/IR/Constants.cpp
Modified: llvm/trunk/include/llvm/IR/Constants.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Constants.h?rev=336444&r1=336443&r2=336444&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Constants.h (original)
+++ llvm/trunk/include/llvm/IR/Constants.h Fri Jul 6 08:18:58 2018
@@ -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
Modified: llvm/trunk/lib/IR/Constants.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Constants.cpp?rev=336444&r1=336443&r2=336444&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Constants.cpp (original)
+++ llvm/trunk/lib/IR/Constants.cpp Fri Jul 6 08:18:58 2018
@@ -2271,32 +2271,49 @@ Constant *ConstantExpr::getAShr(Constant
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.
- 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);
+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");
+ }
+ }
- // TODO: If the fadd has 'nsz', should we return +0.0?
- case Instruction::FAdd:
- return ConstantFP::getNegativeZero(Ty);
+ // Non-commutative opcodes: AllowRHSConstant must be set.
+ if (!AllowRHSConstant)
+ return nullptr;
- 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;
}
}
More information about the llvm-commits
mailing list