[llvm] [Attributor] Propagate alignment through ptrmask (PR #150158)

via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 10 18:12:50 PDT 2025


================
@@ -5187,6 +5187,58 @@ struct AADereferenceableCallSiteReturned final
 // ------------------------ Align Argument Attribute ------------------------
 
 namespace {
+
+Align getKnownAlignForIntrinsic(Attributor &A, AAAlign &QueryingAA,
+                                const IntrinsicInst &II) {
+  switch (II.getIntrinsicID()) {
+  case Intrinsic::ptrmask: {
+    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(), (unsigned)63);
+      Align ConstAlign(UINT64_C(1) << ShiftValue);
+      if (ConstAlign >= AlignAA->getKnownAlign())
+        return Align(1);
----------------
Shoreshen wrote:

Hi @arsenm , this may not be the case due to the following reason:
1. The final alignment is going to be max of known and assumed.
2. The known alignment is going to be set during `initialization` of the attribute and can only increase after that.
3. The assumed will be updated according to its dependencies (which is the source of `%x`) during `update`

With example if I have:
```
define internal ptr @test(ptr align 4 %x) {
  %p = tail call ptr @llvm.ptrmask.p0.i64(ptr %x, i64 -8)
  store float 1.0, ptr %p, align 8
  ret ptr %p
}
define void @func(ptr align 2 %x) {
  ...
  %ptr = call @test(%x)
}
```
While the user of argument `%x` is a ptrmask, and assume:
1. We report the maximum assumed
2. Function `@test` will calculate attribute first

Then:
1. The calculation of known is at `initialization` and will not go across functions. So at that time, the assumed for `%x` in `@test` is 4. So the known alignment is 4 and will not be reduced for it.
2. When updating the attribute, it will seek for all caller and found out the only source is `%x` in `@func` and its alignment is 2.
3. The final alignment is `max(known, assumed)=max(4,2)=4` which is not correct.

https://github.com/llvm/llvm-project/pull/150158


More information about the llvm-commits mailing list