Fix a minor bug in the dag combiner that broke pcompress2 and some other
[oota-llvm.git] / lib / CodeGen / IntrinsicLowering.cpp
index 634f959f3c4781684989879d73a896770fb6c3f7..b2dd57b50c2c33b963b3db11d0d4808a58b42b1a 100644 (file)
@@ -131,7 +131,6 @@ void DefaultIntrinsicLowering::AddPrototypes(Module &M) {
 /// instruction.
 static Value *LowerCTPOP(Value *V, Instruction *IP) {
   assert(V->getType()->isInteger() && "Can't ctpop a non-integer type!");
-  unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
 
   static const uint64_t MaskValues[6] = {
     0x5555555555555555ULL, 0x3333333333333333ULL,
@@ -145,12 +144,13 @@ static Value *LowerCTPOP(Value *V, Instruction *IP) {
   if (DestTy->isSigned())
     V = new CastInst(V, DestTy->getUnsignedVersion(), V->getName(), IP);
 
+  unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
   for (unsigned i = 1, ct = 0; i != BitSize; i <<= 1, ++ct) {
     Value *MaskCst =
       ConstantExpr::getCast(ConstantUInt::get(Type::ULongTy,
                                               MaskValues[ct]), V->getType());
     Value *LHS = BinaryOperator::createAnd(V, MaskCst, "cppop.and1", IP);
-    Value *VShift = new ShiftInst(Instruction::Shr, V, 
+    Value *VShift = new ShiftInst(Instruction::Shr, V,
                       ConstantInt::get(Type::UByteTy, i), "ctpop.sh", IP);
     Value *RHS = BinaryOperator::createAnd(VShift, MaskCst, "cppop.and2", IP);
     V = BinaryOperator::createAdd(LHS, RHS, "ctpop.step", IP);
@@ -161,6 +161,29 @@ static Value *LowerCTPOP(Value *V, Instruction *IP) {
   return V;
 }
 
+/// LowerCTLZ - Emit the code to lower ctlz of V before the specified
+/// instruction.
+static Value *LowerCTLZ(Value *V, Instruction *IP) {
+  const Type *DestTy = V->getType();
+
+  // Force to unsigned so that the shift rights are logical.
+  if (DestTy->isSigned())
+    V = new CastInst(V, DestTy->getUnsignedVersion(), V->getName(), IP);
+
+  unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
+  for (unsigned i = 1; i != BitSize; i <<= 1) {
+    Value *ShVal = ConstantInt::get(Type::UByteTy, i);
+    ShVal = new ShiftInst(Instruction::Shr, V, ShVal, "ctlz.sh", IP);
+    V = BinaryOperator::createOr(V, ShVal, "ctlz.step", IP);
+  }
+
+  if (V->getType() != DestTy)
+    V = new CastInst(V, DestTy, V->getName(), IP);
+
+  V = BinaryOperator::createNot(V, "", IP);
+  return LowerCTPOP(V, IP);
+}
+
 void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
   Function *Callee = CI->getCalledFunction();
   assert(Callee && "Cannot lower an indirect call!");
@@ -210,46 +233,9 @@ void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
     CI->replaceAllUsesWith(LowerCTPOP(CI->getOperand(1), CI));
     break;
 
-  case Intrinsic::ctlz: {
-    Value *Src = CI->getOperand(1);
-    Value* SA;
-    switch (CI->getOperand(0)->getType()->getTypeID())
-    {
-    case Type::LongTyID:
-    case Type::ULongTyID:
-      SA = ConstantUInt::get(Type::UByteTy, 32);
-      Src = BinaryOperator::createOr(Src, new ShiftInst(Instruction::Shr, Src,
-                                                        SA, "", CI), "", CI);
-    case Type::IntTyID:
-    case Type::UIntTyID:
-      SA = ConstantUInt::get(Type::UByteTy, 16);
-      Src = BinaryOperator::createOr(Src, new ShiftInst(Instruction::Shr,
-                                                        Src, SA, "", CI),
-                                     "", CI);
-    case Type::ShortTyID:
-    case Type::UShortTyID:
-      SA = ConstantUInt::get(Type::UByteTy, 8);
-      Src = BinaryOperator::createOr(Src, new ShiftInst(Instruction::Shr,
-                                                        Src, SA, "", CI),
-                                     "", CI);
-    default:
-      SA = ConstantUInt::get(Type::UByteTy, 1);
-      Src = BinaryOperator::createOr(Src, new ShiftInst(Instruction::Shr, Src,
-                                                        SA, "", CI), "", CI);
-      SA = ConstantUInt::get(Type::UByteTy, 2);
-      Src = BinaryOperator::createOr(Src, new ShiftInst(Instruction::Shr, Src,
-                                                        SA, "", CI), "", CI);
-      SA = ConstantUInt::get(Type::UByteTy, 4);
-      Src = BinaryOperator::createOr(Src, new ShiftInst(Instruction::Shr, Src,
-                                                        SA, "", CI), "", CI);
-    };
-    Src = BinaryOperator::createNot(Src, "", CI);
-
-
-    Src = LowerCTPOP(Src, CI);
-    CI->replaceAllUsesWith(Src);
+  case Intrinsic::ctlz:
+    CI->replaceAllUsesWith(LowerCTLZ(CI->getOperand(1), CI));
     break;
-  }
   case Intrinsic::cttz: {
     // cttz(x) -> ctpop(~X & (X-1))
     Value *Src = CI->getOperand(1);