[llvm] r338215 - [InstSimplify] refactor intrinsic simplifications; NFCI
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Sun Jul 29 07:42:08 PDT 2018
Author: spatel
Date: Sun Jul 29 07:42:08 2018
New Revision: 338215
URL: http://llvm.org/viewvc/llvm-project?rev=338215&view=rev
Log:
[InstSimplify] refactor intrinsic simplifications; NFCI
Modified:
llvm/trunk/lib/Analysis/InstructionSimplify.cpp
Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=338215&r1=338214&r2=338215&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Sun Jul 29 07:42:08 2018
@@ -4641,149 +4641,131 @@ static bool maskIsAllZeroOrUndef(Value *
return true;
}
-template <typename IterTy>
-static Value *SimplifyIntrinsic(Function *F, IterTy ArgBegin, IterTy ArgEnd,
- const SimplifyQuery &Q, unsigned MaxRecurse) {
+static Value *simplifyUnaryIntrinsic(Function *F, Value *Op0,
+ const SimplifyQuery &Q) {
+ // Idempotent functions return the same result when called repeatedly.
Intrinsic::ID IID = F->getIntrinsicID();
- unsigned NumOperands = std::distance(ArgBegin, ArgEnd);
+ if (IsIdempotent(IID))
+ if (auto *II = dyn_cast<IntrinsicInst>(Op0))
+ if (II->getIntrinsicID() == IID)
+ return II;
- // Unary Ops
- if (NumOperands == 1) {
- // Perform idempotent optimizations
- if (IsIdempotent(IID)) {
- if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(*ArgBegin)) {
- if (II->getIntrinsicID() == IID)
- return II;
- }
- }
+ Value *X;
+ switch (IID) {
+ case Intrinsic::fabs:
+ if (SignBitMustBeZero(Op0, Q.TLI)) return Op0;
+ break;
+ case Intrinsic::bswap:
+ // bswap(bswap(x)) -> x
+ if (match(Op0, m_BSwap(m_Value(X)))) return X;
+ break;
+ case Intrinsic::bitreverse:
+ // bitreverse(bitreverse(x)) -> x
+ if (match(Op0, m_BitReverse(m_Value(X)))) return X;
+ break;
+ case Intrinsic::exp:
+ // exp(log(x)) -> x
+ if (Q.CxtI->hasAllowReassoc() &&
+ match(Op0, m_Intrinsic<Intrinsic::log>(m_Value(X)))) return X;
+ break;
+ case Intrinsic::exp2:
+ // exp2(log2(x)) -> x
+ if (Q.CxtI->hasAllowReassoc() &&
+ match(Op0, m_Intrinsic<Intrinsic::log2>(m_Value(X)))) return X;
+ break;
+ case Intrinsic::log:
+ // log(exp(x)) -> x
+ if (Q.CxtI->hasAllowReassoc() &&
+ match(Op0, m_Intrinsic<Intrinsic::exp>(m_Value(X)))) return X;
+ break;
+ case Intrinsic::log2:
+ // log2(exp2(x)) -> x
+ if (Q.CxtI->hasAllowReassoc() &&
+ match(Op0, m_Intrinsic<Intrinsic::exp2>(m_Value(X)))) return X;
+ break;
+ default:
+ break;
+ }
- Value *IIOperand = *ArgBegin;
- Value *X;
- switch (IID) {
- case Intrinsic::fabs: {
- if (SignBitMustBeZero(IIOperand, Q.TLI))
- return IIOperand;
- return nullptr;
- }
- case Intrinsic::bswap: {
- // bswap(bswap(x)) -> x
- if (match(IIOperand, m_BSwap(m_Value(X))))
- return X;
- return nullptr;
- }
- case Intrinsic::bitreverse: {
- // bitreverse(bitreverse(x)) -> x
- if (match(IIOperand, m_BitReverse(m_Value(X))))
- return X;
- return nullptr;
- }
- case Intrinsic::exp: {
- // exp(log(x)) -> x
- if (Q.CxtI->hasAllowReassoc() &&
- match(IIOperand, m_Intrinsic<Intrinsic::log>(m_Value(X))))
- return X;
- return nullptr;
- }
- case Intrinsic::exp2: {
- // exp2(log2(x)) -> x
- if (Q.CxtI->hasAllowReassoc() &&
- match(IIOperand, m_Intrinsic<Intrinsic::log2>(m_Value(X))))
- return X;
- return nullptr;
- }
- case Intrinsic::log: {
- // log(exp(x)) -> x
- if (Q.CxtI->hasAllowReassoc() &&
- match(IIOperand, m_Intrinsic<Intrinsic::exp>(m_Value(X))))
- return X;
- return nullptr;
- }
- case Intrinsic::log2: {
- // log2(exp2(x)) -> x
- if (Q.CxtI->hasAllowReassoc() &&
- match(IIOperand, m_Intrinsic<Intrinsic::exp2>(m_Value(X)))) {
- return X;
- }
- return nullptr;
- }
- default:
- return nullptr;
- }
+ return nullptr;
+}
+
+static Value *simplifyBinaryIntrinsic(Function *F, Value *Op0, Value *Op1,
+ const SimplifyQuery &Q) {
+ Intrinsic::ID IID = F->getIntrinsicID();
+ Type *ReturnType = F->getReturnType();
+ switch (IID) {
+ case Intrinsic::usub_with_overflow:
+ case Intrinsic::ssub_with_overflow:
+ // X - X -> { 0, false }
+ if (Op0 == Op1)
+ return Constant::getNullValue(ReturnType);
+ // X - undef -> undef
+ // undef - X -> undef
+ if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
+ return UndefValue::get(ReturnType);
+ break;
+ case Intrinsic::uadd_with_overflow:
+ case Intrinsic::sadd_with_overflow:
+ // X + undef -> undef
+ if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
+ return UndefValue::get(ReturnType);
+ break;
+ case Intrinsic::umul_with_overflow:
+ case Intrinsic::smul_with_overflow:
+ // 0 * X -> { 0, false }
+ // X * 0 -> { 0, false }
+ if (match(Op0, m_Zero()) || match(Op1, m_Zero()))
+ return Constant::getNullValue(ReturnType);
+ // undef * X -> { 0, false }
+ // X * undef -> { 0, false }
+ if (match(Op0, m_Undef()) || match(Op1, m_Undef()))
+ return Constant::getNullValue(ReturnType);
+ break;
+ case Intrinsic::load_relative:
+ if (auto *C0 = dyn_cast<Constant>(Op0))
+ if (auto *C1 = dyn_cast<Constant>(Op1))
+ return SimplifyRelativeLoad(C0, C1, Q.DL);
+ break;
+ case Intrinsic::powi:
+ if (auto *Power = dyn_cast<ConstantInt>(Op1)) {
+ // powi(x, 0) -> 1.0
+ if (Power->isZero())
+ return ConstantFP::get(Op0->getType(), 1.0);
+ // powi(x, 1) -> x
+ if (Power->isOne())
+ return Op0;
+ }
+ break;
+ case Intrinsic::maxnum:
+ case Intrinsic::minnum:
+ // If one argument is NaN, return the other argument.
+ if (match(Op0, m_NaN())) return Op1;
+ if (match(Op1, m_NaN())) return Op0;
+ break;
+ default:
+ break;
}
- // Binary Ops
- if (NumOperands == 2) {
- Value *LHS = *ArgBegin;
- Value *RHS = *(ArgBegin + 1);
- Type *ReturnType = F->getReturnType();
-
- switch (IID) {
- case Intrinsic::usub_with_overflow:
- case Intrinsic::ssub_with_overflow: {
- // X - X -> { 0, false }
- if (LHS == RHS)
- return Constant::getNullValue(ReturnType);
-
- // X - undef -> undef
- // undef - X -> undef
- if (isa<UndefValue>(LHS) || isa<UndefValue>(RHS))
- return UndefValue::get(ReturnType);
+ return nullptr;
+}
- return nullptr;
- }
- case Intrinsic::uadd_with_overflow:
- case Intrinsic::sadd_with_overflow: {
- // X + undef -> undef
- if (isa<UndefValue>(LHS) || isa<UndefValue>(RHS))
- return UndefValue::get(ReturnType);
+template <typename IterTy>
+static Value *simplifyIntrinsic(Function *F, IterTy ArgBegin, IterTy ArgEnd,
+ const SimplifyQuery &Q) {
+ // Intrinsics with no operands have some kind of side effect. Don't simplify.
+ unsigned NumOperands = std::distance(ArgBegin, ArgEnd);
+ if (NumOperands == 0)
+ return nullptr;
- return nullptr;
- }
- case Intrinsic::umul_with_overflow:
- case Intrinsic::smul_with_overflow: {
- // 0 * X -> { 0, false }
- // X * 0 -> { 0, false }
- if (match(LHS, m_Zero()) || match(RHS, m_Zero()))
- return Constant::getNullValue(ReturnType);
-
- // undef * X -> { 0, false }
- // X * undef -> { 0, false }
- if (match(LHS, m_Undef()) || match(RHS, m_Undef()))
- return Constant::getNullValue(ReturnType);
+ Intrinsic::ID IID = F->getIntrinsicID();
+ if (NumOperands == 1)
+ return simplifyUnaryIntrinsic(F, ArgBegin[0], Q);
- return nullptr;
- }
- case Intrinsic::load_relative: {
- Constant *C0 = dyn_cast<Constant>(LHS);
- Constant *C1 = dyn_cast<Constant>(RHS);
- if (C0 && C1)
- return SimplifyRelativeLoad(C0, C1, Q.DL);
- return nullptr;
- }
- case Intrinsic::powi:
- if (ConstantInt *Power = dyn_cast<ConstantInt>(RHS)) {
- // powi(x, 0) -> 1.0
- if (Power->isZero())
- return ConstantFP::get(LHS->getType(), 1.0);
- // powi(x, 1) -> x
- if (Power->isOne())
- return LHS;
- }
- return nullptr;
- case Intrinsic::maxnum:
- case Intrinsic::minnum:
- // If one argument is NaN, return the other argument.
- if (match(LHS, m_NaN()))
- return RHS;
- if (match(RHS, m_NaN()))
- return LHS;
- return nullptr;
- default:
- return nullptr;
- }
- }
+ if (NumOperands == 2)
+ return simplifyBinaryIntrinsic(F, ArgBegin[0], ArgBegin[1], Q);
- // Simplify calls to llvm.masked.load.*
+ // Handle intrinsics with 3 or more arguments.
switch (IID) {
case Intrinsic::masked_load: {
Value *MaskArg = ArgBegin[2];
@@ -4817,7 +4799,7 @@ static Value *SimplifyCall(ImmutableCall
return nullptr;
if (F->isIntrinsic())
- if (Value *Ret = SimplifyIntrinsic(F, ArgBegin, ArgEnd, Q, MaxRecurse))
+ if (Value *Ret = simplifyIntrinsic(F, ArgBegin, ArgEnd, Q))
return Ret;
if (!canConstantFoldCallTo(CS, F))
More information about the llvm-commits
mailing list