Skip to content
Merged
Show file tree
Hide file tree
Changes from 96 commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
bd9c95b
propagate alignment through ptrmask instruction
Shoreshen Jul 23, 2025
eecf59e
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Jul 23, 2025
3a161f3
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Jul 25, 2025
cd46759
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Jul 28, 2025
48cd7d6
fix matthews comments
Shoreshen Jul 28, 2025
8091ffb
fix lit
Shoreshen Jul 28, 2025
7b1abf2
fix test cases
Shoreshen Jul 28, 2025
461f0b1
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Jul 29, 2025
258238f
add test case not propagate extractelement
Shoreshen Jul 29, 2025
8878983
fix test case
Shoreshen Jul 29, 2025
ec9dccd
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Jul 30, 2025
420ab45
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Jul 30, 2025
22ee90f
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Jul 31, 2025
ebbfc0b
fix comments
Shoreshen Jul 31, 2025
52b16d4
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Jul 31, 2025
47dc434
fix matthew's comments
Shoreshen Aug 1, 2025
4c8af0f
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 4, 2025
9aa5bdb
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 5, 2025
9985f51
try remove optional
Shoreshen Aug 5, 2025
794c7f0
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 6, 2025
3d8aaad
fix test case
Shoreshen Aug 6, 2025
50a1bbd
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 6, 2025
3ee0bba
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 6, 2025
4b69c00
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 7, 2025
6241734
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 8, 2025
4613413
Merge remote-tracking branch 'origin/main' into ptrmask-alignment-att…
Shoreshen Aug 11, 2025
1aaa568
fix test case
Shoreshen Aug 11, 2025
ac0f753
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 12, 2025
166cbf9
fix matthew's comments
Shoreshen Aug 12, 2025
0105ebd
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 13, 2025
9efeb6f
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 14, 2025
5ae0e7f
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 14, 2025
2eeff68
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 15, 2025
801c6b6
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 18, 2025
736bd31
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 19, 2025
63cac5f
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 20, 2025
2213f73
fix comments
Shoreshen Aug 20, 2025
91bc830
fix comments
Shoreshen Aug 20, 2025
e833e8b
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 21, 2025
5b95504
fix comments
Shoreshen Aug 21, 2025
a065a18
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 22, 2025
57b4b2b
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 25, 2025
5268447
fix comments
Shoreshen Aug 25, 2025
7188f35
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 25, 2025
09549d9
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 25, 2025
9755380
fix comments
Shoreshen Aug 25, 2025
2a53aa7
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 26, 2025
d2445fe
fix comment
Shoreshen Aug 26, 2025
c8ddb15
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 27, 2025
1dc52e2
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Aug 28, 2025
bce47af
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Sep 1, 2025
65e7872
Update llvm/lib/Transforms/IPO/AttributorAttributes.cpp
Shoreshen Sep 1, 2025
c6c5131
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Sep 2, 2025
5a9099a
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Sep 3, 2025
c34df24
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Sep 4, 2025
9ffe9ef
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Sep 5, 2025
4fed48b
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Sep 8, 2025
62277ae
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Sep 9, 2025
14e6de2
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Sep 11, 2025
1190cff
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Sep 12, 2025
db748bf
fix matthew's comment
Shoreshen Sep 12, 2025
572e2b2
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Sep 15, 2025
1432758
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Sep 16, 2025
edf463a
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Sep 17, 2025
a4b632b
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Sep 22, 2025
cb48630
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Sep 24, 2025
ff78488
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Sep 26, 2025
62375b2
fix comments and bug
Shoreshen Sep 26, 2025
835bebe
remove undef
Shoreshen Sep 26, 2025
0c5723a
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Sep 28, 2025
ad59b3e
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Sep 29, 2025
f930468
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Oct 9, 2025
add9024
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Oct 10, 2025
eb3b946
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Oct 10, 2025
4716ce0
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Oct 11, 2025
71c1e45
fix comments
Shoreshen Oct 11, 2025
4db0555
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Oct 13, 2025
7b4737a
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Oct 14, 2025
7cf4cf5
Add comment for pulling attribute in initialization
Shoreshen Oct 14, 2025
558acc7
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Oct 15, 2025
2020b77
fix comments
Shoreshen Oct 15, 2025
15322ab
fix test case
Shoreshen Oct 15, 2025
6937c0a
fix comments
Shoreshen Oct 15, 2025
ad75dcc
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Oct 16, 2025
c42ed04
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Oct 17, 2025
91edd4e
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Oct 20, 2025
fca2371
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Oct 21, 2025
9fbc571
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Oct 22, 2025
c5650f1
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Oct 23, 2025
38cac2f
fix shilei's comment
Shoreshen Oct 23, 2025
db99e2e
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Oct 24, 2025
caf71d2
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Oct 27, 2025
7ac364f
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Oct 29, 2025
846e4db
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Nov 3, 2025
0dc1ac3
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Nov 3, 2025
37197f2
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Nov 3, 2025
54e1e6c
inline getAssumedAlignForIntrinsic
Shoreshen Nov 3, 2025
8b023c0
fix switch
Shoreshen Nov 3, 2025
bdf2ec6
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Nov 4, 2025
cf9bc32
Merge branch 'main' into ptrmask-alignment-attribute
Shoreshen Nov 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions llvm/include/llvm/Transforms/IPO/Attributor.h
Original file line number Diff line number Diff line change
Expand Up @@ -5339,6 +5339,17 @@ struct AAPotentialConstantValues
return nullptr;
}

/// Return the minimum trailing zeros of potential constants
unsigned getAssumedMinTrailingZeros() const {
unsigned TrailingZeros = getAssumedSet().begin()->getBitWidth() + 1;
for (const APInt &It : getAssumedSet()) {
if (It.countTrailingZeros() < TrailingZeros)
TrailingZeros = It.countTrailingZeros();
}
if (TrailingZeros > getAssumedSet().begin()->getBitWidth())
return 0;
return TrailingZeros;
}
/// See AbstractAttribute::getName()
StringRef getName() const override { return "AAPotentialConstantValues"; }

Expand Down
60 changes: 60 additions & 0 deletions llvm/lib/Transforms/IPO/AttributorAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5185,6 +5185,33 @@ struct AADereferenceableCallSiteReturned final
// ------------------------ Align Argument Attribute ------------------------

namespace {

static Align getAssumedAlignForIntrinsic(Attributor &A, AAAlign &QueryingAA,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the known one gets inlined, this one can probably be as well.

const IntrinsicInst &II) {
Align Alignment;
switch (II.getIntrinsicID()) {
case Intrinsic::ptrmask: {
const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
QueryingAA, IRPosition::value(*II.getOperand(1)), DepClassTy::REQUIRED);
const auto *AlignAA =
A.getAAFor<AAAlign>(QueryingAA, IRPosition::value(*(II.getOperand(0))),
DepClassTy::REQUIRED);
if (ConstVals && ConstVals->isValidState()) {
unsigned ShiftValue = std::min(ConstVals->getAssumedMinTrailingZeros(),
Value::MaxAlignmentExponent);
Alignment = Align(UINT64_C(1) << ShiftValue);
}
if (AlignAA && AlignAA->isValidState())
Alignment = std::max(AlignAA->getAssumedAlign(), Alignment);

return std::min(QueryingAA.getAssumedAlign(), Alignment);
}
default:
break;
}
return Alignment;
}

static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
Value &AssociatedValue, const Use *U,
const Instruction *I, bool &TrackUse) {
Expand All @@ -5200,6 +5227,28 @@ static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
TrackUse = true;
return 0;
}
if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
switch (II->getIntrinsicID()) {
case Intrinsic::ptrmask: {
// Is it appropriate to pull attribute in initialization?
const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
QueryingAA, IRPosition::value(*II->getOperand(1)), DepClassTy::NONE);
const auto *AlignAA = A.getAAFor<AAAlign>(
QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
if (ConstVals && ConstVals->isValidState() && ConstVals->isAtFixpoint()) {
unsigned ShiftValue = std::min(ConstVals->getAssumedMinTrailingZeros(),
Value::MaxAlignmentExponent);
Align ConstAlign(UINT64_C(1) << ShiftValue);
if (ConstAlign >= AlignAA->getKnownAlign())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might just not be understanding the attributor very well, but it seems weird that we're setting align 1 here. I assume it's because there's some handling later that fixes this case?

I can tell from the tests that all this code is doing what I'd intuitively expect, so I'll just let myself be confused.

Copy link
Contributor Author

@Shoreshen Shoreshen Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @krzysz00 this means the mask is going to "cancel out" the alignment requirement, say if we have:

define internal ptr @test(ptr align 4 %x) {
  %p = tail call ptr @llvm.ptrmask.p0.i64(ptr %x, i64 -16)
  store float 1.0, ptr %p, align 8
  ret ptr %p
}

And we are calculating the alignment of %x, since %p is masked by -16, it is aligned at 16. Then it doesn't matter what is the alignment of %x. So this use of %x returns 1, which means no alignment requirement of this use for %x. The final required alignment of %x depends on all of its use.

Otherwise, if we have:

define internal ptr @test(ptr align 4 %x) {
  %p = tail call ptr @llvm.ptrmask.p0.i64(ptr %x, i64 -4)
  store float 1.0, ptr %p, align 8
  ret ptr %p
}

Then if %x is aligned at 4, it must not meet the requirement for the store instruction, so the alignment of %x should be at least 8. Same, for this use of %x it requires %x's alignment is at least 8

return Align(1).value();
}
if (AlignAA)
return AlignAA->getKnownAlign().value();
break;
}
default:
break;
}

MaybeAlign MA;
if (const auto *CB = dyn_cast<CallBase>(I)) {
Expand Down Expand Up @@ -5499,6 +5548,17 @@ struct AAAlignCallSiteReturned final
AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A)
: Base(IRP, A) {}

ChangeStatus updateImpl(Attributor &A) override {
Instruction *I = getIRPosition().getCtxI();
if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
Align Align = getAssumedAlignForIntrinsic(A, *this, *II);
if (Align.value() > 1) {
return clampStateAndIndicateChange<StateType>(this->getState(),
Align.value());
}
}
return Base::updateImpl(A);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we want to simply give up here if it is an intrinsic call and getAssumedAlignForIntrinsic can't handle it.

Copy link
Contributor Author

@Shoreshen Shoreshen Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @shiltian , same as known alignment I cannot tell from the return value that if it is correctly handled.

But what is different here is if it is intrinsic, the call will be equivalently handled as call to deceleration, which will create a pessimistic alignment attribute for the caller. so the following handle can be ignored and directly return here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can compare with Align(), no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @shiltian , Align() is same as Align(1), the ShiftValue = 0 and the value() returns uint64_t(1) << ShiftValue

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm lost here. 1 << 0 is also Align(1) right? Align(1) is the worst alignment anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @shiltian , Align(n) is giving an alignment of n , it will take log of the input:
image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm so confused. Inside getAssumedAlignForIntrinsic, if the intrinsic can't be handled, it simply returns Align(), no? That being said, instead of completely giving up when getAssumedAlignForIntrinsic can't handle, you can still check if getAssumedAlignForIntrinsic returns Align(). If it does, it can continue.

Copy link
Contributor Author

@Shoreshen Shoreshen Oct 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @shiltian , if the return is Align, we cannot tell from the return value that if the intrinsic is handled.... I used to use std::optional<Align> but Matt said it should be Align. And it also confused me that Align()=Align(1), the default ShiftValue is 0, and if we take the log of 1, it's also 0.......

However if I'm not wrong, let it continue will simply return the alignment of the intrinsic. Since intrinsics are function declaration, so it will initialize but not update and directly indicate pessimistic and make the "assumed = known".

May be we can implement the logic inside getAssumedAlignForIntrinsic??

Copy link
Contributor

@shiltian shiltian Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When it returns Align() (the one from default c'tor), it doesn't matter whether it is the intrinsic not handled, or it is already handled but just happens to be that, because Align() is the worst case anyway. It also doesn't matter whether the state is persimistic or optimistic if the intrinsic indeed is Align().

I understand for now it will not make any difference but I'd just like to be a little bit future proof here.

};
/// See AbstractAttribute::trackStatistics()
void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
};
Expand Down
Loading
Loading