From e9391fd9b52e93717b365bdd05c471101323a4df Mon Sep 17 00:00:00 2001 From: Reid Spencer Date: Sun, 1 Apr 2007 07:35:23 +0000 Subject: [PATCH] For PR1297: Support overloaded intrinsics bswap, ctpop, cttz, ctlz. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35547 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ConstantFolding.cpp | 40 ++++++++----------- lib/CodeGen/IntrinsicLowering.cpp | 21 ++-------- .../Scalar/InstructionCombining.cpp | 32 ++++----------- 3 files changed, 28 insertions(+), 65 deletions(-) diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 1288674139c..f0bd1dd0ad4 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -317,24 +317,12 @@ llvm::canConstantFoldCallTo(Function *F) { switch (F->getIntrinsicID()) { case Intrinsic::sqrt_f32: case Intrinsic::sqrt_f64: - case Intrinsic::bswap_i16: - case Intrinsic::bswap_i32: - case Intrinsic::bswap_i64: case Intrinsic::powi_f32: case Intrinsic::powi_f64: - // FIXME: these should be constant folded as well - //case Intrinsic::ctpop_i8: - //case Intrinsic::ctpop_i16: - //case Intrinsic::ctpop_i32: - //case Intrinsic::ctpop_i64: - //case Intrinsic::ctlz_i8: - //case Intrinsic::ctlz_i16: - //case Intrinsic::ctlz_i32: - //case Intrinsic::ctlz_i64: - //case Intrinsic::cttz_i8: - //case Intrinsic::cttz_i16: - //case Intrinsic::cttz_i32: - //case Intrinsic::cttz_i64: + case Intrinsic::bswap: + case Intrinsic::ctpop: + case Intrinsic::ctlz: + case Intrinsic::cttz: return true; default: break; } @@ -445,13 +433,19 @@ llvm::ConstantFoldCall(Function *F, Constant** Operands, unsigned NumOperands) { break; } } else if (ConstantInt *Op = dyn_cast(Operands[0])) { - uint64_t V = Op->getZExtValue(); - if (Name == "llvm.bswap.i16") - return ConstantInt::get(Ty, ByteSwap_16(V)); - else if (Name == "llvm.bswap.i32") - return ConstantInt::get(Ty, ByteSwap_32(V)); - else if (Name == "llvm.bswap.i64") - return ConstantInt::get(Ty, ByteSwap_64(V)); + const IntegerType *OpTy = cast(Op->getType()); + if (Name.size() > 11 && !memcmp(&Name[0], "llvm.bswap", 10)) { + return ConstantInt::get(Op->getValue().byteSwap()); + } else if (Name.size() > 11 && !memcmp(&Name[0],"llvm.ctpop",10)) { + uint64_t ctpop = Op->getValue().countPopulation(); + return ConstantInt::get(OpTy, ctpop); + } else if (Name.size() > 10 && !memcmp(&Name[0], "llvm.cttz", 9)) { + uint64_t cttz = Op->getValue().countTrailingZeros(); + return ConstantInt::get(OpTy, cttz); + } else if (Name.size() > 10 && !memcmp(&Name[0], "llvm.ctlz", 9)) { + uint64_t ctlz = Op->getValue().countLeadingZeros(); + return ConstantInt::get(OpTy, ctlz); + } } } else if (NumOperands == 2) { if (ConstantFP *Op1 = dyn_cast(Operands[0])) { diff --git a/lib/CodeGen/IntrinsicLowering.cpp b/lib/CodeGen/IntrinsicLowering.cpp index 3cfa436935f..21b0e514ef6 100644 --- a/lib/CodeGen/IntrinsicLowering.cpp +++ b/lib/CodeGen/IntrinsicLowering.cpp @@ -236,8 +236,6 @@ static Value *LowerCTLZ(Value *V, Instruction *IP) { return LowerCTPOP(V, IP); } - - void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { Function *Callee = CI->getCalledFunction(); assert(Callee && "Cannot lower an indirect call!"); @@ -283,30 +281,19 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { Type::VoidTy, AbortFCache); break; } - case Intrinsic::ctpop_i8: - case Intrinsic::ctpop_i16: - case Intrinsic::ctpop_i32: - case Intrinsic::ctpop_i64: + case Intrinsic::ctpop: CI->replaceAllUsesWith(LowerCTPOP(CI->getOperand(1), CI)); break; - case Intrinsic::bswap_i16: - case Intrinsic::bswap_i32: - case Intrinsic::bswap_i64: + case Intrinsic::bswap: CI->replaceAllUsesWith(LowerBSWAP(CI->getOperand(1), CI)); break; - case Intrinsic::ctlz_i8: - case Intrinsic::ctlz_i16: - case Intrinsic::ctlz_i32: - case Intrinsic::ctlz_i64: + case Intrinsic::ctlz: CI->replaceAllUsesWith(LowerCTLZ(CI->getOperand(1), CI)); break; - case Intrinsic::cttz_i8: - case Intrinsic::cttz_i16: - case Intrinsic::cttz_i32: - case Intrinsic::cttz_i64: { + case Intrinsic::cttz: { // cttz(x) -> ctpop(~X & (X-1)) Value *Src = CI->getOperand(1); Value *NotSrc = BinaryOperator::createNot(Src, Src->getName()+".not", CI); diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 2735dff48f4..81379c0222f 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -3624,11 +3624,11 @@ Instruction *InstCombiner::MatchBSwap(BinaryOperator &I) { Module *M = I.getParent()->getParent()->getParent(); const char *FnName = 0; if (I.getType() == Type::Int16Ty) - FnName = "llvm.bswap.i16"; + FnName = "llvm.bswap.i16.i16"; else if (I.getType() == Type::Int32Ty) - FnName = "llvm.bswap.i32"; + FnName = "llvm.bswap.i32.i32"; else if (I.getType() == Type::Int64Ty) - FnName = "llvm.bswap.i64"; + FnName = "llvm.bswap.i64.i64"; else assert(0 && "Unknown integer type!"); Constant *F = M->getOrInsertFunction(FnName, I.getType(), I.getType(), NULL); @@ -5173,29 +5173,11 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { default: break; } } else if (IntrinsicInst *II = dyn_cast(Op0)) { - // Handle set{eq|ne} , intcst. - switch (II->getIntrinsicID()) { - default: break; - case Intrinsic::bswap_i16: - // icmp eq (bswap(x)), c -> icmp eq (x,bswap(c)) - AddToWorkList(II); // Dead? + // Handle icmp {eq|ne} , intcst. + if (II->getIntrinsicID() == Intrinsic::bswap) { + AddToWorkList(II); I.setOperand(0, II->getOperand(1)); - I.setOperand(1, ConstantInt::get(Type::Int16Ty, - ByteSwap_16(CI->getZExtValue()))); - return &I; - case Intrinsic::bswap_i32: - // icmp eq (bswap(x)), c -> icmp eq (x,bswap(c)) - AddToWorkList(II); // Dead? - I.setOperand(0, II->getOperand(1)); - I.setOperand(1, ConstantInt::get(Type::Int32Ty, - ByteSwap_32(CI->getZExtValue()))); - return &I; - case Intrinsic::bswap_i64: - // icmp eq (bswap(x)), c -> icmp eq (x,bswap(c)) - AddToWorkList(II); // Dead? - I.setOperand(0, II->getOperand(1)); - I.setOperand(1, ConstantInt::get(Type::Int64Ty, - ByteSwap_64(CI->getZExtValue()))); + I.setOperand(1, ConstantInt::get(CI->getValue().byteSwap())); return &I; } }