From ee1fac61d842d628ffe01c5fadd47fd936a2312f Mon Sep 17 00:00:00 2001 From: Erich Keane Date: Thu, 23 Mar 2017 20:38:34 +0000 Subject: [PATCH] LLVM Changes for alloc_align GCC has the alloc_align attribute, which is similar to assume_aligned, except the attribute's parameter is the index of the integer parameter that needs aligning to. This is the required LLVM changes to make this happen. Differential Revision: https://reviews.llvm.org/D29598 llvm-svn: 298643 --- llvm/include/llvm/IR/IRBuilder.h | 77 +++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 17 deletions(-) diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index fb26aeb..bd21237 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -1806,24 +1806,16 @@ public: return V; } - /// \brief Create an assume intrinsic call that represents an alignment - /// assumption on the provided pointer. - /// - /// An optional offset can be provided, and if it is provided, the offset - /// must be subtracted from the provided pointer to get the pointer with the - /// specified alignment. - CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue, - unsigned Alignment, - Value *OffsetValue = nullptr) { - assert(isa(PtrValue->getType()) && - "trying to create an alignment assumption on a non-pointer?"); - - PointerType *PtrTy = cast(PtrValue->getType()); - Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace()); +private: + /// \brief Helper function that creates an assume intrinsic call that + /// represents an alignment assumption on the provided Ptr, Mask, Type + /// and Offset. + CallInst *CreateAlignmentAssumptionHelper(const DataLayout &DL, + Value *PtrValue, Value *Mask, + Type *IntPtrTy, + Value *OffsetValue) { Value *PtrIntValue = CreatePtrToInt(PtrValue, IntPtrTy, "ptrint"); - Value *Mask = ConstantInt::get(IntPtrTy, - Alignment > 0 ? Alignment - 1 : 0); if (OffsetValue) { bool IsOffsetZero = false; if (ConstantInt *CI = dyn_cast(OffsetValue)) @@ -1840,9 +1832,60 @@ public: Value *Zero = ConstantInt::get(IntPtrTy, 0); Value *MaskedPtr = CreateAnd(PtrIntValue, Mask, "maskedptr"); Value *InvCond = CreateICmpEQ(MaskedPtr, Zero, "maskcond"); - return CreateAssumption(InvCond); } + +public: + /// \brief Create an assume intrinsic call that represents an alignment + /// assumption on the provided pointer. + /// + /// An optional offset can be provided, and if it is provided, the offset + /// must be subtracted from the provided pointer to get the pointer with the + /// specified alignment. + CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue, + unsigned Alignment, + Value *OffsetValue = nullptr) { + assert(isa(PtrValue->getType()) && + "trying to create an alignment assumption on a non-pointer?"); + PointerType *PtrTy = cast(PtrValue->getType()); + Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace()); + + Value *Mask = ConstantInt::get(IntPtrTy, Alignment > 0 ? Alignment - 1 : 0); + return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy, + OffsetValue); + } + // + /// \brief Create an assume intrinsic call that represents an alignment + /// assumption on the provided pointer. + /// + /// An optional offset can be provided, and if it is provided, the offset + /// must be subtracted from the provided pointer to get the pointer with the + /// specified alignment. + /// + /// This overload handles the condition where the Alignment is dependent + /// on an existing value rather than a static value. + CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue, + Value *Alignment, + Value *OffsetValue = nullptr) { + assert(isa(PtrValue->getType()) && + "trying to create an alignment assumption on a non-pointer?"); + PointerType *PtrTy = cast(PtrValue->getType()); + Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace()); + + if (Alignment->getType() != IntPtrTy) + Alignment = CreateIntCast(Alignment, IntPtrTy, /*isSigned*/ true, + "alignmentcast"); + Value *IsPositive = + CreateICmp(CmpInst::ICMP_SGT, Alignment, + ConstantInt::get(Alignment->getType(), 0), "ispositive"); + Value *PositiveMask = + CreateSub(Alignment, ConstantInt::get(IntPtrTy, 1), "positivemask"); + Value *Mask = CreateSelect(IsPositive, PositiveMask, + ConstantInt::get(IntPtrTy, 0), "mask"); + + return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy, + OffsetValue); + } }; // Create wrappers for C Binding types (see CBindingWrapping.h). -- 2.7.4