[llvm] r277883 - [InstCombine] refactor ctlz/cttz folds (NFCI)
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 5 15:42:47 PDT 2016
Author: spatel
Date: Fri Aug 5 17:42:46 2016
New Revision: 277883
URL: http://llvm.org/viewvc/llvm-project?rev=277883&view=rev
Log:
[InstCombine] refactor ctlz/cttz folds (NFCI)
Note that this fold really belongs in InstSimplify.
Refactoring here anyway as an intermediate step because
there's a planned addition to this function in D23134.
Differential Revision: https://reviews.llvm.org/D23223
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=277883&r1=277882&r2=277883&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Fri Aug 5 17:42:46 2016
@@ -1104,6 +1104,35 @@ static Instruction *simplifyMaskedScatte
return nullptr;
}
+static Value *foldCttzCtlz(IntrinsicInst &II, InstCombiner &IC) {
+ Value *Op0 = II.getArgOperand(0);
+ // FIXME: Try to simplify vectors of integers.
+ auto *IT = dyn_cast<IntegerType>(Op0->getType());
+ if (!IT)
+ return nullptr;
+
+ unsigned BitWidth = IT->getBitWidth();
+ APInt KnownZero(BitWidth, 0);
+ APInt KnownOne(BitWidth, 0);
+ IC.computeKnownBits(Op0, KnownZero, KnownOne, 0, &II);
+
+ // Create a mask for bits above (ctlz) or below (cttz) the first known one.
+ bool IsTZ = II.getIntrinsicID() == Intrinsic::cttz;
+ unsigned NumMaskBits = IsTZ ? KnownOne.countTrailingZeros()
+ : KnownOne.countLeadingZeros();
+ APInt Mask = IsTZ ? APInt::getLowBitsSet(BitWidth, NumMaskBits)
+ : APInt::getHighBitsSet(BitWidth, NumMaskBits);
+
+ // If all bits above (ctlz) or below (cttz) the first known one are known
+ // zero, this value is constant.
+ // FIXME: This should be in InstSimplify because we're replacing an
+ // instruction with a constant.
+ if ((Mask & KnownZero) == Mask)
+ return ConstantInt::get(IT, APInt(BitWidth, NumMaskBits));
+
+ return nullptr;
+}
+
// TODO: If the x86 backend knew how to convert a bool vector mask back to an
// XMM register mask efficiently, we could transform all x86 masked intrinsics
// to LLVM masked intrinsics and remove the x86 masked intrinsic defs.
@@ -1397,41 +1426,11 @@ Instruction *InstCombiner::visitCallInst
II->getArgOperand(0));
}
break;
- case Intrinsic::cttz: {
- // If all bits below the first known one are known zero,
- // this value is constant.
- IntegerType *IT = dyn_cast<IntegerType>(II->getArgOperand(0)->getType());
- // FIXME: Try to simplify vectors of integers.
- if (!IT) break;
- uint32_t BitWidth = IT->getBitWidth();
- APInt KnownZero(BitWidth, 0);
- APInt KnownOne(BitWidth, 0);
- computeKnownBits(II->getArgOperand(0), KnownZero, KnownOne, 0, II);
- unsigned TrailingZeros = KnownOne.countTrailingZeros();
- APInt Mask(APInt::getLowBitsSet(BitWidth, TrailingZeros));
- if ((Mask & KnownZero) == Mask)
- return replaceInstUsesWith(CI, ConstantInt::get(IT,
- APInt(BitWidth, TrailingZeros)));
- }
- break;
- case Intrinsic::ctlz: {
- // If all bits above the first known one are known zero,
- // this value is constant.
- IntegerType *IT = dyn_cast<IntegerType>(II->getArgOperand(0)->getType());
- // FIXME: Try to simplify vectors of integers.
- if (!IT) break;
- uint32_t BitWidth = IT->getBitWidth();
- APInt KnownZero(BitWidth, 0);
- APInt KnownOne(BitWidth, 0);
- computeKnownBits(II->getArgOperand(0), KnownZero, KnownOne, 0, II);
- unsigned LeadingZeros = KnownOne.countLeadingZeros();
- APInt Mask(APInt::getHighBitsSet(BitWidth, LeadingZeros));
- if ((Mask & KnownZero) == Mask)
- return replaceInstUsesWith(CI, ConstantInt::get(IT,
- APInt(BitWidth, LeadingZeros)));
-
- }
+ case Intrinsic::cttz:
+ case Intrinsic::ctlz:
+ if (Value *V = foldCttzCtlz(*II, *this))
+ return replaceInstUsesWith(*II, V);
break;
case Intrinsic::uadd_with_overflow:
More information about the llvm-commits
mailing list