aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/IntrinsicLowering.cpp
diff options
context:
space:
mode:
authorZhou Sheng <zhousheng00@gmail.com>2007-06-02 04:10:33 +0000
committerZhou Sheng <zhousheng00@gmail.com>2007-06-02 04:10:33 +0000
commit02031c0ff8ad48acdb8c4a4058c4fafe600423e1 (patch)
tree6deba65e84e468c1c1169ef079268de3fe709cbf /lib/CodeGen/IntrinsicLowering.cpp
parent8e63bf375d18118f46f43910c6a093c824eb4a7d (diff)
Make LowerCTPOP() support arbitrary bitwidth integer type.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37397 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/IntrinsicLowering.cpp')
-rw-r--r--lib/CodeGen/IntrinsicLowering.cpp33
1 files changed, 23 insertions, 10 deletions
diff --git a/lib/CodeGen/IntrinsicLowering.cpp b/lib/CodeGen/IntrinsicLowering.cpp
index c2e4024d11..e6ba069ac7 100644
--- a/lib/CodeGen/IntrinsicLowering.cpp
+++ b/lib/CodeGen/IntrinsicLowering.cpp
@@ -208,17 +208,30 @@ static Value *LowerCTPOP(Value *V, Instruction *IP) {
};
unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
-
- for (unsigned i = 1, ct = 0; i != BitSize; i <<= 1, ++ct) {
- Value *MaskCst = ConstantInt::get(V->getType(), MaskValues[ct]);
- Value *LHS = BinaryOperator::createAnd(V, MaskCst, "cppop.and1", IP);
- Value *VShift = BinaryOperator::createLShr(V,
- ConstantInt::get(V->getType(), i), "ctpop.sh", IP);
- Value *RHS = BinaryOperator::createAnd(VShift, MaskCst, "cppop.and2", IP);
- V = BinaryOperator::createAdd(LHS, RHS, "ctpop.step", IP);
+ unsigned WordSize = (BitSize + 63) / 64;
+ Value *Count = ConstantInt::get(V->getType(), 0);
+
+ for (unsigned n = 0; n < WordSize; ++n) {
+ Value *PartValue = V;
+ for (unsigned i = 1, ct = 0; i < (BitSize>64 ? 64 : BitSize);
+ i <<= 1, ++ct) {
+ Value *MaskCst = ConstantInt::get(V->getType(), MaskValues[ct]);
+ Value *LHS = BinaryOperator::createAnd(
+ PartValue, MaskCst, "cppop.and1", IP);
+ Value *VShift = BinaryOperator::createLShr(PartValue,
+ ConstantInt::get(V->getType(), i), "ctpop.sh", IP);
+ Value *RHS = BinaryOperator::createAnd(VShift, MaskCst, "cppop.and2", IP);
+ PartValue = BinaryOperator::createAdd(LHS, RHS, "ctpop.step", IP);
+ }
+ Count = BinaryOperator::createAdd(PartValue, Count, "ctpop.part", IP);
+ if (BitSize > 64) {
+ V = BinaryOperator::createLShr(V, ConstantInt::get(V->getType(), 64),
+ "ctpop.part.sh", IP);
+ BitSize -= 64;
+ }
}
- return CastInst::createIntegerCast(V, Type::Int32Ty, false, "ctpop", IP);
+ return CastInst::createIntegerCast(Count, Type::Int32Ty, false, "ctpop", IP);
}
/// LowerCTLZ - Emit the code to lower ctlz of V before the specified
@@ -226,7 +239,7 @@ static Value *LowerCTPOP(Value *V, Instruction *IP) {
static Value *LowerCTLZ(Value *V, Instruction *IP) {
unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
- for (unsigned i = 1; i != BitSize; i <<= 1) {
+ for (unsigned i = 1; i < BitSize; i <<= 1) {
Value *ShVal = ConstantInt::get(V->getType(), i);
ShVal = BinaryOperator::createLShr(V, ShVal, "ctlz.sh", IP);
V = BinaryOperator::createOr(V, ShVal, "ctlz.step", IP);