From eaff5246707cc620736e895c239ff78298b3d95e Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 12 Jul 2009 21:08:53 +0000 Subject: remove llvm.part.set.* and llvm.part.select.*. They have never been implemented in codegen, have no frontend to generate them, and are better implemented with pattern matching (like the ppc backend does to generate rlwimi/rlwinm etc). PR4543 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75430 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/LangRef.html | 106 -------- include/llvm/Intrinsics.td | 5 - lib/CodeGen/IntrinsicLowering.cpp | 340 ------------------------- lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp | 8 - 4 files changed, 459 deletions(-) diff --git a/docs/LangRef.html b/docs/LangRef.html index 416b105..15f95e2 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -208,8 +208,6 @@
  • 'llvm.ctpop.*' Intrinsic
  • 'llvm.ctlz.*' Intrinsic
  • 'llvm.cttz.*' Intrinsic
  • -
  • 'llvm.part.select.*' Intrinsic
  • -
  • 'llvm.part.set.*' Intrinsic
  • Arithmetic with Overflow Intrinsics @@ -5942,110 +5940,6 @@ of src. For example, llvm.cttz(2) = 1.

    - - - -
    - -
    Syntax:
    -

    This is an overloaded intrinsic. You can use llvm.part.select -on any integer bit width.

    -
    -  declare i17 @llvm.part.select.i17 (i17 %val, i32 %loBit, i32 %hiBit)
    -  declare i29 @llvm.part.select.i29 (i29 %val, i32 %loBit, i32 %hiBit)
    -
    - -
    Overview:
    -

    The 'llvm.part.select' family of intrinsic functions selects a -range of bits from an integer value and returns them in the same bit width as -the original value.

    - -
    Arguments:
    -

    The first argument, %val and the result may be integer types of -any bit width but they must have the same bit width. The second and third -arguments must be i32 type since they specify only a bit index.

    - -
    Semantics:
    -

    The operation of the 'llvm.part.select' intrinsic has two modes -of operation: forwards and reverse. If %loBit is greater than -%hiBits then the intrinsic operates in reverse mode. Otherwise it -operates in forward mode.

    -

    In forward mode, this intrinsic is the equivalent of shifting %val -right by %loBit bits and then ANDing it with a mask with -only the %hiBit - %loBit bits set, as follows:

    -
      -
    1. The %val is shifted right (LSHR) by the number of bits specified - by %loBits. This normalizes the value to the low order bits.
    2. -
    3. The %loBits value is subtracted from the %hiBits value - to determine the number of bits to retain.
    4. -
    5. A mask of the retained bits is created by shifting a -1 value.
    6. -
    7. The mask is ANDed with %val to produce the result.
    8. -
    -

    In reverse mode, a similar computation is made except that the bits are -returned in the reverse order. So, for example, if X has the value -i16 0x0ACF (101011001111) and we apply -part.select(i16 X, 8, 3) to it, we get back the value -i16 0x0026 (000000100110).

    -
    - - - -
    - -
    Syntax:
    -

    This is an overloaded intrinsic. You can use llvm.part.set -on any integer bit width.

    -
    -  declare i17 @llvm.part.set.i17.i9 (i17 %val, i9 %repl, i32 %lo, i32 %hi)
    -  declare i29 @llvm.part.set.i29.i9 (i29 %val, i9 %repl, i32 %lo, i32 %hi)
    -
    - -
    Overview:
    -

    The 'llvm.part.set' family of intrinsic functions replaces a range -of bits in an integer value with another integer value. It returns the integer -with the replaced bits.

    - -
    Arguments:
    -

    The first argument, %val, and the result may be integer types of -any bit width, but they must have the same bit width. %val is the value -whose bits will be replaced. The second argument, %repl may be an -integer of any bit width. The third and fourth arguments must be i32 -type since they specify only a bit index.

    - -
    Semantics:
    -

    The operation of the 'llvm.part.set' intrinsic has two modes -of operation: forwards and reverse. If %lo is greater than -%hi then the intrinsic operates in reverse mode. Otherwise it -operates in forward mode.

    - -

    For both modes, the %repl value is prepared for use by either -truncating it down to the size of the replacement area or zero extending it -up to that size.

    - -

    In forward mode, the bits between %lo and %hi (inclusive) -are replaced with corresponding bits from %repl. That is the 0th bit -in %repl replaces the %loth bit in %val and etc. up -to the %hith bit.

    - -

    In reverse mode, a similar computation is made except that the bits are -reversed. That is, the 0th bit in %repl replaces the -%hi bit in %val and etc. down to the %loth bit.

    - -
    Examples:
    - -
    -  llvm.part.set(0xFFFF, 0, 4, 7) -> 0xFF0F
    -  llvm.part.set(0xFFFF, 0, 7, 4) -> 0xFF0F
    -  llvm.part.set(0xFFFF, 1, 7, 4) -> 0xFF8F
    -  llvm.part.set(0xFFFF, F, 8, 3) -> 0xFFE7
    -  llvm.part.set(0xFFFF, 0, 3, 8) -> 0xFE07
    -
    - -
    diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td index c036151..9febb40 100644 --- a/include/llvm/Intrinsics.td +++ b/include/llvm/Intrinsics.td @@ -267,11 +267,6 @@ let Properties = [IntrNoMem] in { def int_ctpop: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>; def int_ctlz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>; def int_cttz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>; - def int_part_select : Intrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty]>; - def int_part_set : Intrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, llvm_anyint_ty, - llvm_i32_ty, llvm_i32_ty]>; } //===------------------------ Debugger Intrinsics -------------------------===// diff --git a/lib/CodeGen/IntrinsicLowering.cpp b/lib/CodeGen/IntrinsicLowering.cpp index 2c28660..914d703 100644 --- a/lib/CodeGen/IntrinsicLowering.cpp +++ b/lib/CodeGen/IntrinsicLowering.cpp @@ -291,338 +291,6 @@ static Value *LowerCTLZ(Value *V, Instruction *IP) { return LowerCTPOP(V, IP); } -/// Convert the llvm.part.select.iX.iY intrinsic. This intrinsic takes -/// three integer arguments. The first argument is the Value from which the -/// bits will be selected. It may be of any bit width. The second and third -/// arguments specify a range of bits to select with the second argument -/// specifying the low bit and the third argument specifying the high bit. Both -/// must be type i32. The result is the corresponding selected bits from the -/// Value in the same width as the Value (first argument). If the low bit index -/// is higher than the high bit index then the inverse selection is done and -/// the bits are returned in inverse order. -/// @brief Lowering of llvm.part.select intrinsic. -static Instruction *LowerPartSelect(CallInst *CI) { - IRBuilder<> Builder(*CI->getParent()->getContext()); - - // Make sure we're dealing with a part select intrinsic here - Function *F = CI->getCalledFunction(); - const FunctionType *FT = F->getFunctionType(); - if (!F->isDeclaration() || !FT->getReturnType()->isInteger() || - FT->getNumParams() != 3 || !FT->getParamType(0)->isInteger() || - !FT->getParamType(1)->isInteger() || !FT->getParamType(2)->isInteger()) - return CI; - - // Get the intrinsic implementation function by converting all the . to _ - // in the intrinsic's function name and then reconstructing the function - // declaration. - std::string Name(F->getName()); - for (unsigned i = 4; i < Name.length(); ++i) - if (Name[i] == '.') - Name[i] = '_'; - Module* M = F->getParent(); - F = cast(M->getOrInsertFunction(Name, FT)); - F->setLinkage(GlobalValue::WeakAnyLinkage); - - // If we haven't defined the impl function yet, do so now - if (F->isDeclaration()) { - - // Get the arguments to the function - Function::arg_iterator args = F->arg_begin(); - Value* Val = args++; Val->setName("Val"); - Value* Lo = args++; Lo->setName("Lo"); - Value* Hi = args++; Hi->setName("High"); - - // We want to select a range of bits here such that [Hi, Lo] is shifted - // down to the low bits. However, it is quite possible that Hi is smaller - // than Lo in which case the bits have to be reversed. - - // Create the blocks we will need for the two cases (forward, reverse) - BasicBlock* CurBB = BasicBlock::Create("entry", F); - BasicBlock *RevSize = BasicBlock::Create("revsize", CurBB->getParent()); - BasicBlock *FwdSize = BasicBlock::Create("fwdsize", CurBB->getParent()); - BasicBlock *Compute = BasicBlock::Create("compute", CurBB->getParent()); - BasicBlock *Reverse = BasicBlock::Create("reverse", CurBB->getParent()); - BasicBlock *RsltBlk = BasicBlock::Create("result", CurBB->getParent()); - - Builder.SetInsertPoint(CurBB); - - // Cast Hi and Lo to the size of Val so the widths are all the same - if (Hi->getType() != Val->getType()) - Hi = Builder.CreateIntCast(Hi, Val->getType(), /* isSigned */ false, - "tmp"); - if (Lo->getType() != Val->getType()) - Lo = Builder.CreateIntCast(Lo, Val->getType(), /* isSigned */ false, - "tmp"); - - // Compute a few things that both cases will need, up front. - Constant* Zero = ConstantInt::get(Val->getType(), 0); - Constant* One = ConstantInt::get(Val->getType(), 1); - Constant* AllOnes = ConstantInt::getAllOnesValue(Val->getType()); - - // Compare the Hi and Lo bit positions. This is used to determine - // which case we have (forward or reverse) - Value *Cmp = Builder.CreateICmpULT(Hi, Lo, "less"); - Builder.CreateCondBr(Cmp, RevSize, FwdSize); - - // First, compute the number of bits in the forward case. - Builder.SetInsertPoint(FwdSize); - Value* FBitSize = Builder.CreateSub(Hi, Lo, "fbits"); - Builder.CreateBr(Compute); - - // Second, compute the number of bits in the reverse case. - Builder.SetInsertPoint(RevSize); - Value* RBitSize = Builder.CreateSub(Lo, Hi, "rbits"); - Builder.CreateBr(Compute); - - // Now, compute the bit range. Start by getting the bitsize and the shift - // amount (either Hi or Lo) from PHI nodes. Then we compute a mask for - // the number of bits we want in the range. We shift the bits down to the - // least significant bits, apply the mask to zero out unwanted high bits, - // and we have computed the "forward" result. It may still need to be - // reversed. - Builder.SetInsertPoint(Compute); - - // Get the BitSize from one of the two subtractions - PHINode *BitSize = Builder.CreatePHI(Val->getType(), "bits"); - BitSize->reserveOperandSpace(2); - BitSize->addIncoming(FBitSize, FwdSize); - BitSize->addIncoming(RBitSize, RevSize); - - // Get the ShiftAmount as the smaller of Hi/Lo - PHINode *ShiftAmt = Builder.CreatePHI(Val->getType(), "shiftamt"); - ShiftAmt->reserveOperandSpace(2); - ShiftAmt->addIncoming(Lo, FwdSize); - ShiftAmt->addIncoming(Hi, RevSize); - - // Increment the bit size - Value *BitSizePlusOne = Builder.CreateAdd(BitSize, One, "bits"); - - // Create a Mask to zero out the high order bits. - Value* Mask = Builder.CreateShl(AllOnes, BitSizePlusOne, "mask"); - Mask = Builder.CreateNot(Mask, "mask"); - - // Shift the bits down and apply the mask - Value* FRes = Builder.CreateLShr(Val, ShiftAmt, "fres"); - FRes = Builder.CreateAnd(FRes, Mask, "fres"); - Builder.CreateCondBr(Cmp, Reverse, RsltBlk); - - // In the Reverse block we have the mask already in FRes but we must reverse - // it by shifting FRes bits right and putting them in RRes by shifting them - // in from left. - Builder.SetInsertPoint(Reverse); - - // First set up our loop counters - PHINode *Count = Builder.CreatePHI(Val->getType(), "count"); - Count->reserveOperandSpace(2); - Count->addIncoming(BitSizePlusOne, Compute); - - // Next, get the value that we are shifting. - PHINode *BitsToShift = Builder.CreatePHI(Val->getType(), "val"); - BitsToShift->reserveOperandSpace(2); - BitsToShift->addIncoming(FRes, Compute); - - // Finally, get the result of the last computation - PHINode *RRes = Builder.CreatePHI(Val->getType(), "rres"); - RRes->reserveOperandSpace(2); - RRes->addIncoming(Zero, Compute); - - // Decrement the counter - Value *Decr = Builder.CreateSub(Count, One, "decr"); - Count->addIncoming(Decr, Reverse); - - // Compute the Bit that we want to move - Value *Bit = Builder.CreateAnd(BitsToShift, One, "bit"); - - // Compute the new value for next iteration. - Value *NewVal = Builder.CreateLShr(BitsToShift, One, "rshift"); - BitsToShift->addIncoming(NewVal, Reverse); - - // Shift the bit into the low bits of the result. - Value *NewRes = Builder.CreateShl(RRes, One, "lshift"); - NewRes = Builder.CreateOr(NewRes, Bit, "addbit"); - RRes->addIncoming(NewRes, Reverse); - - // Terminate loop if we've moved all the bits. - Value *Cond = Builder.CreateICmpEQ(Decr, Zero, "cond"); - Builder.CreateCondBr(Cond, RsltBlk, Reverse); - - // Finally, in the result block, select one of the two results with a PHI - // node and return the result; - Builder.SetInsertPoint(RsltBlk); - PHINode *BitSelect = Builder.CreatePHI(Val->getType(), "part_select"); - BitSelect->reserveOperandSpace(2); - BitSelect->addIncoming(FRes, Compute); - BitSelect->addIncoming(NewRes, Reverse); - Builder.CreateRet(BitSelect); - } - - // Return a call to the implementation function - Builder.SetInsertPoint(CI->getParent(), CI); - CallInst *NewCI = Builder.CreateCall3(F, CI->getOperand(1), - CI->getOperand(2), CI->getOperand(3)); - NewCI->setName(CI->getName()); - return NewCI; -} - -/// Convert the llvm.part.set.iX.iY.iZ intrinsic. This intrinsic takes -/// four integer arguments (iAny %Value, iAny %Replacement, i32 %Low, i32 %High) -/// The first two arguments can be any bit width. The result is the same width -/// as %Value. The operation replaces bits between %Low and %High with the value -/// in %Replacement. If %Replacement is not the same width, it is truncated or -/// zero extended as appropriate to fit the bits being replaced. If %Low is -/// greater than %High then the inverse set of bits are replaced. -/// @brief Lowering of llvm.bit.part.set intrinsic. -static Instruction *LowerPartSet(CallInst *CI) { - IRBuilder<> Builder(*CI->getParent()->getContext()); - - // Make sure we're dealing with a part select intrinsic here - Function *F = CI->getCalledFunction(); - const FunctionType *FT = F->getFunctionType(); - if (!F->isDeclaration() || !FT->getReturnType()->isInteger() || - FT->getNumParams() != 4 || !FT->getParamType(0)->isInteger() || - !FT->getParamType(1)->isInteger() || !FT->getParamType(2)->isInteger() || - !FT->getParamType(3)->isInteger()) - return CI; - - // Get the intrinsic implementation function by converting all the . to _ - // in the intrinsic's function name and then reconstructing the function - // declaration. - std::string Name(F->getName()); - for (unsigned i = 4; i < Name.length(); ++i) - if (Name[i] == '.') - Name[i] = '_'; - Module* M = F->getParent(); - F = cast(M->getOrInsertFunction(Name, FT)); - F->setLinkage(GlobalValue::WeakAnyLinkage); - - // If we haven't defined the impl function yet, do so now - if (F->isDeclaration()) { - // Get the arguments for the function. - Function::arg_iterator args = F->arg_begin(); - Value* Val = args++; Val->setName("Val"); - Value* Rep = args++; Rep->setName("Rep"); - Value* Lo = args++; Lo->setName("Lo"); - Value* Hi = args++; Hi->setName("Hi"); - - // Get some types we need - const IntegerType* ValTy = cast(Val->getType()); - const IntegerType* RepTy = cast(Rep->getType()); - uint32_t RepBits = RepTy->getBitWidth(); - - // Constant Definitions - ConstantInt* RepBitWidth = ConstantInt::get(Type::Int32Ty, RepBits); - ConstantInt* RepMask = ConstantInt::getAllOnesValue(RepTy); - ConstantInt* ValMask = ConstantInt::getAllOnesValue(ValTy); - ConstantInt* One = ConstantInt::get(Type::Int32Ty, 1); - ConstantInt* ValOne = ConstantInt::get(ValTy, 1); - ConstantInt* Zero = ConstantInt::get(Type::Int32Ty, 0); - ConstantInt* ValZero = ConstantInt::get(ValTy, 0); - - // Basic blocks we fill in below. - BasicBlock* entry = BasicBlock::Create("entry", F, 0); - BasicBlock* large = BasicBlock::Create("large", F, 0); - BasicBlock* small = BasicBlock::Create("small", F, 0); - BasicBlock* reverse = BasicBlock::Create("reverse", F, 0); - BasicBlock* result = BasicBlock::Create("result", F, 0); - - // BASIC BLOCK: entry - Builder.SetInsertPoint(entry); - // First, get the number of bits that we're placing as an i32 - Value* is_forward = Builder.CreateICmpULT(Lo, Hi); - Value* Hi_pn = Builder.CreateSelect(is_forward, Hi, Lo); - Value* Lo_pn = Builder.CreateSelect(is_forward, Lo, Hi); - Value* NumBits = Builder.CreateSub(Hi_pn, Lo_pn); - NumBits = Builder.CreateAdd(NumBits, One); - // Now, convert Lo and Hi to ValTy bit width - Lo = Builder.CreateIntCast(Lo_pn, ValTy, /* isSigned */ false); - // Determine if the replacement bits are larger than the number of bits we - // are replacing and deal with it. - Value* is_large = Builder.CreateICmpULT(NumBits, RepBitWidth); - Builder.CreateCondBr(is_large, large, small); - - // BASIC BLOCK: large - Builder.SetInsertPoint(large); - Value* MaskBits = Builder.CreateSub(RepBitWidth, NumBits); - MaskBits = Builder.CreateIntCast(MaskBits, RepMask->getType(), - /* isSigned */ false); - Value* Mask1 = Builder.CreateLShr(RepMask, MaskBits); - Value* Rep2 = Builder.CreateAnd(Mask1, Rep); - Builder.CreateBr(small); - - // BASIC BLOCK: small - Builder.SetInsertPoint(small); - PHINode* Rep3 = Builder.CreatePHI(RepTy); - Rep3->reserveOperandSpace(2); - Rep3->addIncoming(Rep2, large); - Rep3->addIncoming(Rep, entry); - Value* Rep4 = Builder.CreateIntCast(Rep3, ValTy, /* isSigned */ false); - Builder.CreateCondBr(is_forward, result, reverse); - - // BASIC BLOCK: reverse (reverses the bits of the replacement) - Builder.SetInsertPoint(reverse); - // Set up our loop counter as a PHI so we can decrement on each iteration. - // We will loop for the number of bits in the replacement value. - PHINode *Count = Builder.CreatePHI(Type::Int32Ty, "count"); - Count->reserveOperandSpace(2); - Count->addIncoming(NumBits, small); - - // Get the value that we are shifting bits out of as a PHI because - // we'll change this with each iteration. - PHINode *BitsToShift = Builder.CreatePHI(Val->getType(), "val"); - BitsToShift->reserveOperandSpace(2); - BitsToShift->addIncoming(Rep4, small); - - // Get the result of the last computation or zero on first iteration - PHINode *RRes = Builder.CreatePHI(Val->getType(), "rres"); - RRes->reserveOperandSpace(2); - RRes->addIncoming(ValZero, small); - - // Decrement the loop counter by one - Value *Decr = Builder.CreateSub(Count, One); - Count->addIncoming(Decr, reverse); - - // Get the bit that we want to move into the result - Value *Bit = Builder.CreateAnd(BitsToShift, ValOne); - - // Compute the new value of the bits to shift for the next iteration. - Value *NewVal = Builder.CreateLShr(BitsToShift, ValOne); - BitsToShift->addIncoming(NewVal, reverse); - - // Shift the bit we extracted into the low bit of the result. - Value *NewRes = Builder.CreateShl(RRes, ValOne); - NewRes = Builder.CreateOr(NewRes, Bit); - RRes->addIncoming(NewRes, reverse); - - // Terminate loop if we've moved all the bits. - Value *Cond = Builder.CreateICmpEQ(Decr, Zero); - Builder.CreateCondBr(Cond, result, reverse); - - // BASIC BLOCK: result - Builder.SetInsertPoint(result); - PHINode *Rplcmnt = Builder.CreatePHI(Val->getType()); - Rplcmnt->reserveOperandSpace(2); - Rplcmnt->addIncoming(NewRes, reverse); - Rplcmnt->addIncoming(Rep4, small); - Value* t0 = Builder.CreateIntCast(NumBits, ValTy, /* isSigned */ false); - Value* t1 = Builder.CreateShl(ValMask, Lo); - Value* t2 = Builder.CreateNot(t1); - Value* t3 = Builder.CreateShl(t1, t0); - Value* t4 = Builder.CreateOr(t2, t3); - Value* t5 = Builder.CreateAnd(t4, Val); - Value* t6 = Builder.CreateShl(Rplcmnt, Lo); - Value* Rslt = Builder.CreateOr(t5, t6, "part_set"); - Builder.CreateRet(Rslt); - } - - // Return a call to the implementation function - Builder.SetInsertPoint(CI->getParent(), CI); - CallInst *NewCI = Builder.CreateCall4(F, CI->getOperand(1), - CI->getOperand(2), CI->getOperand(3), - CI->getOperand(4)); - NewCI->setName(CI->getName()); - return NewCI; -} - static void ReplaceFPIntrinsicWithCall(CallInst *CI, const char *Fname, const char *Dname, const char *LDname) { @@ -711,14 +379,6 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { break; } - case Intrinsic::part_select: - CI->replaceAllUsesWith(LowerPartSelect(CI)); - break; - - case Intrinsic::part_set: - CI->replaceAllUsesWith(LowerPartSet(CI)); - break; - case Intrinsic::stacksave: case Intrinsic::stackrestore: { if (!Warned) diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index 3882abd..63aa7cf 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -4158,14 +4158,6 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { DAG.setRoot(Tmp.getValue(1)); return 0; } - case Intrinsic::part_select: { - // Currently not implemented: just abort - llvm_report_error("part_select intrinsic not implemented"); - } - case Intrinsic::part_set: { - // Currently not implemented: just abort - llvm_report_error("part_set intrinsic not implemented"); - } case Intrinsic::bswap: setValue(&I, DAG.getNode(ISD::BSWAP, dl, getValue(I.getOperand(1)).getValueType(), -- cgit v1.1