[llvm] r259326 - add helper function for minnum/maxnum ; NFC
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 31 08:35:23 PST 2016
Author: spatel
Date: Sun Jan 31 10:35:23 2016
New Revision: 259326
URL: http://llvm.org/viewvc/llvm-project?rev=259326&view=rev
Log:
add helper function for minnum/maxnum ; NFC
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=259326&r1=259325&r2=259326&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Sun Jan 31 10:35:23 2016
@@ -677,6 +677,82 @@ static Value *simplifyX86vpcom(const Int
return nullptr;
}
+static Value *simplifyMinnumMaxnum(const IntrinsicInst &II) {
+ Value *Arg0 = II.getArgOperand(0);
+ Value *Arg1 = II.getArgOperand(1);
+
+ // fmin(x, x) -> x
+ if (Arg0 == Arg1)
+ return Arg0;
+
+ const auto *C1 = dyn_cast<ConstantFP>(Arg1);
+
+ // fmin(x, nan) -> x
+ if (C1 && C1->isNaN())
+ return Arg0;
+
+ // This is the value because if undef were NaN, we would return the other
+ // value and cannot return a NaN unless both operands are.
+ //
+ // fmin(undef, x) -> x
+ if (isa<UndefValue>(Arg0))
+ return Arg1;
+
+ // fmin(x, undef) -> x
+ if (isa<UndefValue>(Arg1))
+ return Arg0;
+
+ Value *X = nullptr;
+ Value *Y = nullptr;
+ if (II.getIntrinsicID() == Intrinsic::minnum) {
+ // fmin(x, fmin(x, y)) -> fmin(x, y)
+ // fmin(y, fmin(x, y)) -> fmin(x, y)
+ if (match(Arg1, m_FMin(m_Value(X), m_Value(Y)))) {
+ if (Arg0 == X || Arg0 == Y)
+ return Arg1;
+ }
+
+ // fmin(fmin(x, y), x) -> fmin(x, y)
+ // fmin(fmin(x, y), y) -> fmin(x, y)
+ if (match(Arg0, m_FMin(m_Value(X), m_Value(Y)))) {
+ if (Arg1 == X || Arg1 == Y)
+ return Arg0;
+ }
+
+ // TODO: fmin(nnan x, inf) -> x
+ // TODO: fmin(nnan ninf x, flt_max) -> x
+ if (C1 && C1->isInfinity()) {
+ // fmin(x, -inf) -> -inf
+ if (C1->isNegative())
+ return Arg1;
+ }
+ } else {
+ assert(II.getIntrinsicID() == Intrinsic::maxnum);
+ // fmax(x, fmax(x, y)) -> fmax(x, y)
+ // fmax(y, fmax(x, y)) -> fmax(x, y)
+ if (match(Arg1, m_FMax(m_Value(X), m_Value(Y)))) {
+ if (Arg0 == X || Arg0 == Y)
+ return Arg1;
+ }
+
+ // fmax(fmax(x, y), x) -> fmax(x, y)
+ // fmax(fmax(x, y), y) -> fmax(x, y)
+ if (match(Arg0, m_FMax(m_Value(X), m_Value(Y)))) {
+ if (Arg1 == X || Arg1 == Y)
+ return Arg0;
+ }
+
+ // TODO: fmax(nnan x, -inf) -> x
+ // TODO: fmax(nnan ninf x, -flt_max) -> x
+ if (C1 && C1->isInfinity()) {
+ // fmax(x, inf) -> inf
+ if (!C1->isNegative())
+ return Arg1;
+ }
+ }
+ return nullptr;
+}
+
/// CallInst simplification. This mostly only handles folding of intrinsic
/// instructions. For normal calls, it allows visitCallSite to do the heavy
/// lifting.
@@ -885,84 +961,14 @@ Instruction *InstCombiner::visitCallInst
case Intrinsic::maxnum: {
Value *Arg0 = II->getArgOperand(0);
Value *Arg1 = II->getArgOperand(1);
-
- // fmin(x, x) -> x
- if (Arg0 == Arg1)
- return ReplaceInstUsesWith(CI, Arg0);
-
- const ConstantFP *C0 = dyn_cast<ConstantFP>(Arg0);
- const ConstantFP *C1 = dyn_cast<ConstantFP>(Arg1);
-
- // Canonicalize constants into the RHS.
- if (C0 && !C1) {
+ // Canonicalize constants to the RHS.
+ if (isa<ConstantFP>(Arg0) && !isa<ConstantFP>(Arg1)) {
II->setArgOperand(0, Arg1);
II->setArgOperand(1, Arg0);
return II;
}
-
- // fmin(x, nan) -> x
- if (C1 && C1->isNaN())
- return ReplaceInstUsesWith(CI, Arg0);
-
- // This is the value because if undef were NaN, we would return the other
- // value and cannot return a NaN unless both operands are.
- //
- // fmin(undef, x) -> x
- if (isa<UndefValue>(Arg0))
- return ReplaceInstUsesWith(CI, Arg1);
-
- // fmin(x, undef) -> x
- if (isa<UndefValue>(Arg1))
- return ReplaceInstUsesWith(CI, Arg0);
-
- Value *X = nullptr;
- Value *Y = nullptr;
- if (II->getIntrinsicID() == Intrinsic::minnum) {
- // fmin(x, fmin(x, y)) -> fmin(x, y)
- // fmin(y, fmin(x, y)) -> fmin(x, y)
- if (match(Arg1, m_FMin(m_Value(X), m_Value(Y)))) {
- if (Arg0 == X || Arg0 == Y)
- return ReplaceInstUsesWith(CI, Arg1);
- }
-
- // fmin(fmin(x, y), x) -> fmin(x, y)
- // fmin(fmin(x, y), y) -> fmin(x, y)
- if (match(Arg0, m_FMin(m_Value(X), m_Value(Y)))) {
- if (Arg1 == X || Arg1 == Y)
- return ReplaceInstUsesWith(CI, Arg0);
- }
-
- // TODO: fmin(nnan x, inf) -> x
- // TODO: fmin(nnan ninf x, flt_max) -> x
- if (C1 && C1->isInfinity()) {
- // fmin(x, -inf) -> -inf
- if (C1->isNegative())
- return ReplaceInstUsesWith(CI, Arg1);
- }
- } else {
- assert(II->getIntrinsicID() == Intrinsic::maxnum);
- // fmax(x, fmax(x, y)) -> fmax(x, y)
- // fmax(y, fmax(x, y)) -> fmax(x, y)
- if (match(Arg1, m_FMax(m_Value(X), m_Value(Y)))) {
- if (Arg0 == X || Arg0 == Y)
- return ReplaceInstUsesWith(CI, Arg1);
- }
-
- // fmax(fmax(x, y), x) -> fmax(x, y)
- // fmax(fmax(x, y), y) -> fmax(x, y)
- if (match(Arg0, m_FMax(m_Value(X), m_Value(Y)))) {
- if (Arg1 == X || Arg1 == Y)
- return ReplaceInstUsesWith(CI, Arg0);
- }
-
- // TODO: fmax(nnan x, -inf) -> x
- // TODO: fmax(nnan ninf x, -flt_max) -> x
- if (C1 && C1->isInfinity()) {
- // fmax(x, inf) -> inf
- if (!C1->isNegative())
- return ReplaceInstUsesWith(CI, Arg1);
- }
- }
+ if (Value *V = simplifyMinnumMaxnum(*II))
+ return ReplaceInstUsesWith(*II, V);
break;
}
case Intrinsic::ppc_altivec_lvx:
More information about the llvm-commits
mailing list