|
50 | 50 | #include "llvm/Analysis/TargetLibraryInfo.h"
|
51 | 51 | #include "llvm/Analysis/ValueTracking.h"
|
52 | 52 | #include "llvm/IR/Argument.h"
|
| 53 | +#include "llvm/IR/AttributeMask.h" |
53 | 54 | #include "llvm/IR/BasicBlock.h"
|
54 | 55 | #include "llvm/IR/Constant.h"
|
55 | 56 | #include "llvm/IR/ConstantRangeList.h"
|
@@ -563,6 +564,43 @@ static void shortenAssignment(Instruction *Inst, Value *OriginalDest,
|
563 | 564 | for_each(LinkedDVRAssigns, InsertAssignForOverlap);
|
564 | 565 | }
|
565 | 566 |
|
| 567 | +/// Update the attributes given that a memory access is updated (the |
| 568 | +/// dereferenced pointer could be moved forward when shortening a |
| 569 | +/// mem intrinsic). |
| 570 | +static void adjustArgAttributes(AnyMemIntrinsic *Intrinsic, unsigned ArgNo, |
| 571 | + uint64_t PtrOffset) { |
| 572 | + // Remember old attributes. |
| 573 | + AttributeSet OldAttrs = Intrinsic->getParamAttributes(ArgNo); |
| 574 | + |
| 575 | + // Find attributes that should be kept, and remove the rest. |
| 576 | + AttributeMask AttrsToRemove; |
| 577 | + for (auto &Attr : OldAttrs) { |
| 578 | + if (Attr.hasKindAsEnum()) { |
| 579 | + switch (Attr.getKindAsEnum()) { |
| 580 | + default: |
| 581 | + break; |
| 582 | + case Attribute::Alignment: |
| 583 | + // Only keep alignment if PtrOffset satisfy the alignment. |
| 584 | + if (isAligned(Attr.getAlignment().valueOrOne(), PtrOffset)) |
| 585 | + continue; |
| 586 | + break; |
| 587 | + case Attribute::Dereferenceable: |
| 588 | + case Attribute::DereferenceableOrNull: |
| 589 | + // We could reduce the size of these attributes according to |
| 590 | + // PtrOffset. But we simply drop these for now. |
| 591 | + break; |
| 592 | + case Attribute::NonNull: |
| 593 | + case Attribute::NoUndef: |
| 594 | + continue; |
| 595 | + } |
| 596 | + } |
| 597 | + AttrsToRemove.addAttribute(Attr); |
| 598 | + } |
| 599 | + |
| 600 | + // Remove the attributes that should be dropped. |
| 601 | + Intrinsic->removeParamAttrs(ArgNo, AttrsToRemove); |
| 602 | +} |
| 603 | + |
566 | 604 | static bool tryToShorten(Instruction *DeadI, int64_t &DeadStart,
|
567 | 605 | uint64_t &DeadSize, int64_t KillingStart,
|
568 | 606 | uint64_t KillingSize, bool IsOverwriteEnd) {
|
@@ -644,6 +682,7 @@ static bool tryToShorten(Instruction *DeadI, int64_t &DeadStart,
|
644 | 682 | DeadI->getIterator());
|
645 | 683 | NewDestGEP->setDebugLoc(DeadIntrinsic->getDebugLoc());
|
646 | 684 | DeadIntrinsic->setDest(NewDestGEP);
|
| 685 | + adjustArgAttributes(DeadIntrinsic, 0, ToRemoveSize); |
647 | 686 | }
|
648 | 687 |
|
649 | 688 | // Update attached dbg.assign intrinsics. Assume 8-bit byte.
|
|
0 commit comments