Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
62 changes: 62 additions & 0 deletions llvm/lib/Transforms/IPO/AttributorAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5203,6 +5203,32 @@ static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
TrackUse = true;
return 0;
}
if (auto *II = dyn_cast<IntrinsicInst>(I)) {
if (II->getIntrinsicID() == Intrinsic::ptrmask) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you split the intrinsic case into a separate function, and switch over the intrinsic ID

auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
QueryingAA, IRPosition::value(*(II->getOperand(1))),
DepClassTy::NONE);
const AAAlign *AlignAA = A.getAAFor<AAAlign>(
QueryingAA, IRPosition::value(*(II)), DepClassTy::NONE);
if (ConstVals && ConstVals->isValidState()) {
if (ConstVals->isAtFixpoint()) {
uint64_t TrailingZeros = 64;
for (const auto &It : ConstVals->getAssumedSet())
if (It.countTrailingZeros() < TrailingZeros)
TrailingZeros = It.countTrailingZeros();
if (TrailingZeros < 64) {
Copy link
Contributor

Choose a reason for hiding this comment

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

There's no reason to have a limit of 64 or hardcode it, just directly use the size from the pointer

uint64_t Mask = 1 << TrailingZeros;
if (Mask >= AlignAA->getKnownAlign().value()) {
return 0;
}
}
return AlignAA->getKnownAlign().value();
}
} else if (AlignAA) {
return AlignAA->getKnownAlign().value();
}
}
}

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

ChangeStatus updateImpl(Attributor &A) override {
Instruction *I = getIRPosition().getCtxI();
if (auto *II = dyn_cast<IntrinsicInst>(I)) {
if (II->getIntrinsicID() == Intrinsic::ptrmask) {
const AAPotentialConstantValues *ConstVals =
A.getAAFor<AAPotentialConstantValues>(
*this, IRPosition::value(*(II->getOperand(1))),
DepClassTy::REQUIRED);
const AAAlign *AlignAA =
A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
DepClassTy::REQUIRED);
uint64_t Alignment = 0;
if (ConstVals && ConstVals->isValidState()) {
unsigned TrailingZeros = 64;
Copy link
Contributor

Choose a reason for hiding this comment

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

Take the pointer size instead of assuming 64

for (const auto &It : ConstVals->getAssumedSet())
if (It.countTrailingZeros() < TrailingZeros)
TrailingZeros = It.countTrailingZeros();
if (TrailingZeros < 64)
Alignment = 1 << TrailingZeros;
}
if (AlignAA && AlignAA->isValidState() &&
Alignment < AlignAA->getAssumedAlign().value())
Alignment = AlignAA->getAssumedAlign().value();

if (Alignment != 0) {
uint64_t OldAssumed = getAssumed();
takeAssumedMinimum(Alignment);
return OldAssumed == getAssumed() ? ChangeStatus::UNCHANGED
: ChangeStatus::CHANGED;
} else {
Copy link
Contributor

Choose a reason for hiding this comment

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

No else after return

return ChangeStatus::UNCHANGED;
}
}
}
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
101 changes: 101 additions & 0 deletions llvm/test/Transforms/Attributor/align-ptrmask.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=attributor -S < %s | FileCheck %s

define float @align_ptrmask_back_no_prop(ptr align 2 %x, i1 %cmp1, i1 %cmp2) {
; CHECK-LABEL: define float @align_ptrmask_back_no_prop(
; CHECK-SAME: ptr nofree readonly align 2 [[X:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i64 -32, i64 -8
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP2]], i64 [[SEL]], i64 -16
; CHECK-NEXT: [[P:%.*]] = tail call align 8 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef [[SEL1]]) #[[ATTR2:[0-9]+]]
; CHECK-NEXT: [[RES:%.*]] = load float, ptr [[P]], align 8, !invariant.load [[META0:![0-9]+]]
; CHECK-NEXT: ret float [[RES]]
;
%sel = select i1 %cmp1, i64 -32, i64 -8
%sel1 = select i1 %cmp2, i64 %sel, i64 -16
%p = tail call ptr @llvm.ptrmask(ptr %x, i64 %sel1)
%res = load float, ptr %p, align 8
ret float %res
}

define float @align_ptrmask_back_prop(ptr align 2 %x, i1 %cmp1, i1 %cmp2) {
; CHECK-LABEL: define float @align_ptrmask_back_prop(
; CHECK-SAME: ptr nofree readonly align 16 [[X:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i64 -32, i64 -8
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP2]], i64 [[SEL]], i64 -16
; CHECK-NEXT: [[P:%.*]] = tail call align 16 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef [[SEL1]]) #[[ATTR2]]
; CHECK-NEXT: [[RES:%.*]] = load float, ptr [[P]], align 16, !invariant.load [[META0]]
; CHECK-NEXT: ret float [[RES]]
;
%sel = select i1 %cmp1, i64 -32, i64 -8
%sel1 = select i1 %cmp2, i64 %sel, i64 -16
%p = tail call ptr @llvm.ptrmask(ptr %x, i64 %sel1)
%res = load float, ptr %p, align 16
ret float %res
}

define float @align_ptrmask_forward_mask(ptr align 2 %x, i1 %cmp1, i1 %cmp2) {
; CHECK-LABEL: define float @align_ptrmask_forward_mask(
; CHECK-SAME: ptr nofree readonly align 2 [[X:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i64 -32, i64 -8
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP2]], i64 [[SEL]], i64 -16
; CHECK-NEXT: [[P:%.*]] = tail call align 8 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef [[SEL1]]) #[[ATTR2]]
; CHECK-NEXT: [[RES:%.*]] = load float, ptr [[P]], align 8, !invariant.load [[META0]]
; CHECK-NEXT: ret float [[RES]]
;
%sel = select i1 %cmp1, i64 -32, i64 -8
%sel1 = select i1 %cmp2, i64 %sel, i64 -16
%p = tail call ptr @llvm.ptrmask(ptr %x, i64 %sel1)
%res = load float, ptr %p, align 4
ret float %res
}

define float @align_ptrmask_forward_ptr(ptr align 16 %x, i1 %cmp1, i1 %cmp2) {
; CHECK-LABEL: define float @align_ptrmask_forward_ptr(
; CHECK-SAME: ptr nofree readonly align 16 [[X:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i64 -32, i64 -8
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP2]], i64 [[SEL]], i64 -16
; CHECK-NEXT: [[P:%.*]] = tail call align 16 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 noundef [[SEL1]]) #[[ATTR2]]
; CHECK-NEXT: [[RES:%.*]] = load float, ptr [[P]], align 16, !invariant.load [[META0]]
; CHECK-NEXT: ret float [[RES]]
;
%sel = select i1 %cmp1, i64 -32, i64 -8
%sel1 = select i1 %cmp2, i64 %sel, i64 -16
%p = tail call ptr @llvm.ptrmask(ptr %x, i64 %sel1)
%res = load float, ptr %p, align 4
ret float %res
}

define float @align_ptrmask_forward_nonconst_mask(ptr align 8 %x, i64 %y, i1 %cmp1, i1 %cmp2) {
; CHECK-LABEL: define float @align_ptrmask_forward_nonconst_mask(
; CHECK-SAME: ptr nofree readonly align 8 [[X:%.*]], i64 [[Y:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i64 -32, i64 [[Y]]
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP2]], i64 [[SEL]], i64 -16
; CHECK-NEXT: [[P:%.*]] = tail call align 8 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 [[SEL1]]) #[[ATTR2]]
; CHECK-NEXT: [[RES:%.*]] = load float, ptr [[P]], align 8, !invariant.load [[META0]]
; CHECK-NEXT: ret float [[RES]]
;
%sel = select i1 %cmp1, i64 -32, i64 %y
%sel1 = select i1 %cmp2, i64 %sel, i64 -16
%p = tail call ptr @llvm.ptrmask(ptr %x, i64 %sel1)
%res = load float, ptr %p, align 4
ret float %res
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not return the pointer value to see the inferred align on the return?

}

define float @align_ptrmask_back_nonconst_mask(ptr align 4 %x, i64 %y, i1 %cmp1, i1 %cmp2) {
; CHECK-LABEL: define float @align_ptrmask_back_nonconst_mask(
; CHECK-SAME: ptr nofree readonly align 8 [[X:%.*]], i64 [[Y:%.*]], i1 [[CMP1:%.*]], i1 [[CMP2:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i64 -32, i64 [[Y]]
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP2]], i64 [[SEL]], i64 -16
; CHECK-NEXT: [[P:%.*]] = tail call align 8 ptr @llvm.ptrmask.p0.i64(ptr [[X]], i64 [[SEL1]]) #[[ATTR2]]
; CHECK-NEXT: [[RES:%.*]] = load float, ptr [[P]], align 8, !invariant.load [[META0]]
; CHECK-NEXT: ret float [[RES]]
;
%sel = select i1 %cmp1, i64 -32, i64 %y
%sel1 = select i1 %cmp2, i64 %sel, i64 -16
%p = tail call ptr @llvm.ptrmask(ptr %x, i64 %sel1)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
%p = tail call ptr @llvm.ptrmask(ptr %x, i64 %sel1)
%p = tail call ptr @llvm.ptrmask.p0.i64(ptr %x, i64 %sel1)

Throughout

%res = load float, ptr %p, align 8
ret float %res
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add tests with these degenerate cases:

  • Input mask value is a small positive constant, such that it cannot increase alignment.
  • Mask that exactly matches maximum alignment, i.e. -4294967296
  • Mask with 1 more bit than maximum alignment, i.e. -8589934592
  • Poison mask
  • ptrmask with align attributes on callsite

;.
Copy link
Contributor

Choose a reason for hiding this comment

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

Test cases with constant values, which is the common case. Also test some unknowable cases. Also vectors

Copy link
Contributor Author

@Shoreshen Shoreshen Jul 28, 2025

Choose a reason for hiding this comment

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

Hi @arsenm , I'm not sure if I can find a vector case. The current frame work seems stop it from generating AAAlign attribute for vector case:
image
image

Also extractelement cannot propagate alignment, so I also cannot use store/load to test

Copy link
Contributor

Choose a reason for hiding this comment

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

extractelement can propagate alignment, whether or not it does currently is another question

Copy link
Contributor Author

@Shoreshen Shoreshen Jul 28, 2025

Choose a reason for hiding this comment

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

Hi @arsenm , yep, sorry for how I said it. The current framework seems not supporting propagate alignment through extractelement. Would you like me to add simple support in this PR in order to add vector tests??

Copy link
Contributor

Choose a reason for hiding this comment

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

No, add the vector test that shows it doesn't propagate for later improvement

; CHECK: [[META0]] = !{}
;.