Index: include/llvm/IR/IRBuilder.h =================================================================== --- include/llvm/IR/IRBuilder.h +++ include/llvm/IR/IRBuilder.h @@ -2123,14 +2123,24 @@ return V; } + /// Used to optionally propagate some additional information from the + /// `CreateAlignmentAssumptionHelper` to the original caller, + /// in addition to the normally returned `CallInst *` that was built. + struct AlignmentAssumptionIntrospection { + /// The actual value on which the alignment check is performed. + Value *PtrIntValue = nullptr; + /// The alignment check itself (`i1`), which is then used in the assumption. + Value *InvCond = nullptr; + }; + private: /// 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) { + /// and Offset. It may be sometimes useful to do some other logic + /// based on this alignment check, thus it can be stored into 'Info'. + CallInst *CreateAlignmentAssumptionHelper( + const DataLayout &DL, Value *PtrValue, Value *Mask, Type *IntPtrTy, + Value *OffsetValue, AlignmentAssumptionIntrospection *Info = nullptr) { Value *PtrIntValue = CreatePtrToInt(PtrValue, IntPtrTy, "ptrint"); if (OffsetValue) { @@ -2149,6 +2159,10 @@ Value *Zero = ConstantInt::get(IntPtrTy, 0); Value *MaskedPtr = CreateAnd(PtrIntValue, Mask, "maskedptr"); Value *InvCond = CreateICmpEQ(MaskedPtr, Zero, "maskcond"); + if (Info) { + Info->PtrIntValue = PtrIntValue; + Info->InvCond = InvCond; + } return CreateAssumption(InvCond); } @@ -2159,9 +2173,13 @@ /// 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) { + /// + /// It may be sometimes useful to do some other logic + /// based on this alignment check, thus it can be stored into 'Info'. + CallInst * + CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue, + unsigned Alignment, Value *OffsetValue = nullptr, + AlignmentAssumptionIntrospection *Info = nullptr) { assert(isa(PtrValue->getType()) && "trying to create an alignment assumption on a non-pointer?"); auto *PtrTy = cast(PtrValue->getType()); @@ -2169,7 +2187,7 @@ Value *Mask = ConstantInt::get(IntPtrTy, Alignment > 0 ? Alignment - 1 : 0); return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy, - OffsetValue); + OffsetValue, Info); } /// Create an assume intrinsic call that represents an alignment @@ -2179,11 +2197,15 @@ /// must be subtracted from the provided pointer to get the pointer with the /// specified alignment. /// + /// It may be sometimes useful to do some other logic + /// based on this alignment check, thus it can be stored into 'Info'. + /// /// 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) { + CallInst * + CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue, + Value *Alignment, Value *OffsetValue = nullptr, + AlignmentAssumptionIntrospection *Info = nullptr) { assert(isa(PtrValue->getType()) && "trying to create an alignment assumption on a non-pointer?"); auto *PtrTy = cast(PtrValue->getType()); @@ -2201,7 +2223,7 @@ ConstantInt::get(IntPtrTy, 0), "mask"); return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy, - OffsetValue); + OffsetValue, Info); } };