forked from OSchip/llvm-project
[llvm][IRBuilder] Introspection for CreateAlignmentAssumption*() functions
Summary: Clang calls these functions to produce IR for assume-aligned attributes. I would like to teach UBSAN to verify these assumptions. For that, i need to access the final pointer on which the check is performed, and the actual `icmp` that does the check. The alternative to this would be to fully re-implement this in clang. Reviewers: spatel, dneilson, craig.topper, dblaikie, hfinkel Reviewed By: hfinkel Subscribers: hfinkel, llvm-commits Differential Revision: https://reviews.llvm.org/D54588 llvm-svn: 351104
This commit is contained in:
parent
bfe2ee453a
commit
c7f215dbff
|
@ -2126,11 +2126,12 @@ public:
|
|||
private:
|
||||
/// Helper function that creates an assume intrinsic call that
|
||||
/// represents an alignment assumption on the provided Ptr, Mask, Type
|
||||
/// and Offset.
|
||||
/// and Offset. It may be sometimes useful to do some other logic
|
||||
/// based on this alignment check, thus it can be stored into 'TheCheck'.
|
||||
CallInst *CreateAlignmentAssumptionHelper(const DataLayout &DL,
|
||||
Value *PtrValue, Value *Mask,
|
||||
Type *IntPtrTy,
|
||||
Value *OffsetValue) {
|
||||
Type *IntPtrTy, Value *OffsetValue,
|
||||
Value **TheCheck) {
|
||||
Value *PtrIntValue = CreatePtrToInt(PtrValue, IntPtrTy, "ptrint");
|
||||
|
||||
if (OffsetValue) {
|
||||
|
@ -2149,6 +2150,9 @@ private:
|
|||
Value *Zero = ConstantInt::get(IntPtrTy, 0);
|
||||
Value *MaskedPtr = CreateAnd(PtrIntValue, Mask, "maskedptr");
|
||||
Value *InvCond = CreateICmpEQ(MaskedPtr, Zero, "maskcond");
|
||||
if (TheCheck)
|
||||
*TheCheck = InvCond;
|
||||
|
||||
return CreateAssumption(InvCond);
|
||||
}
|
||||
|
||||
|
@ -2159,9 +2163,13 @@ public:
|
|||
/// 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.
|
||||
///
|
||||
/// It may be sometimes useful to do some other logic
|
||||
/// based on this alignment check, thus it can be stored into 'TheCheck'.
|
||||
CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue,
|
||||
unsigned Alignment,
|
||||
Value *OffsetValue = nullptr) {
|
||||
Value *OffsetValue = nullptr,
|
||||
Value **TheCheck = nullptr) {
|
||||
assert(isa<PointerType>(PtrValue->getType()) &&
|
||||
"trying to create an alignment assumption on a non-pointer?");
|
||||
auto *PtrTy = cast<PointerType>(PtrValue->getType());
|
||||
|
@ -2169,7 +2177,7 @@ public:
|
|||
|
||||
Value *Mask = ConstantInt::get(IntPtrTy, Alignment > 0 ? Alignment - 1 : 0);
|
||||
return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy,
|
||||
OffsetValue);
|
||||
OffsetValue, TheCheck);
|
||||
}
|
||||
|
||||
/// Create an assume intrinsic call that represents an alignment
|
||||
|
@ -2179,11 +2187,15 @@ public:
|
|||
/// 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 'TheCheck'.
|
||||
///
|
||||
/// 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) {
|
||||
Value *OffsetValue = nullptr,
|
||||
Value **TheCheck = nullptr) {
|
||||
assert(isa<PointerType>(PtrValue->getType()) &&
|
||||
"trying to create an alignment assumption on a non-pointer?");
|
||||
auto *PtrTy = cast<PointerType>(PtrValue->getType());
|
||||
|
@ -2201,7 +2213,7 @@ public:
|
|||
ConstantInt::get(IntPtrTy, 0), "mask");
|
||||
|
||||
return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy,
|
||||
OffsetValue);
|
||||
OffsetValue, TheCheck);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue