Skip to content

Conversation

jhuber6
Copy link
Contributor

@jhuber6 jhuber6 commented Sep 22, 2025

Summary:
The changes made in #156057
allows the alignment value to be increased. We assert effectively
infinite alignment when the pointer argument is invalid / null. The
problem is that for whatever reason the masked load / store functions
use i32 for their alignment value which means this gets truncated to
zero.

Add a special check for this, long term we probably want to just remove
this argument entirely.

Summary:
The changes made in llvm#156057
allows the alignment value to be increased. We assert effectively
infinite alignment when the pointer argument is invalid / null. The
problem is that for whatever reason the masked load / store functions
use i32 for their alignment value which means this gets truncated to
zero.

Add a special check for this, long term we probably want to just remove
this argument entirely.
@llvmbot
Copy link
Member

llvmbot commented Sep 22, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Joseph Huber (jhuber6)

Changes

Summary:
The changes made in #156057
allows the alignment value to be increased. We assert effectively
infinite alignment when the pointer argument is invalid / null. The
problem is that for whatever reason the masked load / store functions
use i32 for their alignment value which means this gets truncated to
zero.

Add a special check for this, long term we probably want to just remove
this argument entirely.


Full diff: https://github.com/llvm/llvm-project/pull/160109.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/Scalar/InferAlignment.cpp (+2-1)
  • (modified) llvm/test/Transforms/InferAlignment/masked.ll (+12)
diff --git a/llvm/lib/Transforms/Scalar/InferAlignment.cpp b/llvm/lib/Transforms/Scalar/InferAlignment.cpp
index b60b15b6c3a2b..995b80396b8af 100644
--- a/llvm/lib/Transforms/Scalar/InferAlignment.cpp
+++ b/llvm/lib/Transforms/Scalar/InferAlignment.cpp
@@ -57,7 +57,8 @@ static bool tryToImproveAlign(
         cast<ConstantInt>(II->getArgOperand(AlignOpIdx))->getAlignValue();
     Align PrefAlign = DL.getPrefTypeAlign(Type);
     Align NewAlign = Fn(PtrOp, OldAlign, PrefAlign);
-    if (NewAlign <= OldAlign)
+    if (NewAlign <= OldAlign ||
+        NewAlign.value() > std::numeric_limits<uint32_t>().max())
       return false;
 
     Value *V =
diff --git a/llvm/test/Transforms/InferAlignment/masked.ll b/llvm/test/Transforms/InferAlignment/masked.ll
index 1b8d26417d75e..13acf9b50e7e8 100644
--- a/llvm/test/Transforms/InferAlignment/masked.ll
+++ b/llvm/test/Transforms/InferAlignment/masked.ll
@@ -29,6 +29,18 @@ entry:
   ret void
 }
 
+define <2 x i32> @null(<2 x i1> %mask, <2 x i32> %val) {
+; CHECK-LABEL: define <2 x i32> @null(
+; CHECK-SAME: <2 x i1> [[MASK:%.*]], <2 x i32> [[VAL:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[MASKED_LOAD:%.*]] = tail call <2 x i32> @llvm.masked.load.v2i32.p0(ptr null, i32 1, <2 x i1> [[MASK]], <2 x i32> [[VAL]])
+; CHECK-NEXT:    ret <2 x i32> [[MASKED_LOAD]]
+;
+entry:
+  %masked_load = tail call <2 x i32> @llvm.masked.load.v2f64.p0(ptr null, i32 1, <2 x i1> %mask, <2 x i32> %val)
+  ret <2 x i32> %masked_load
+}
+
 declare void @llvm.assume(i1)
 declare <2 x i32> @llvm.masked.load.v2i32.p0(ptr, i32, <2 x i1>, <2 x i32>)
 declare void @llvm.masked.store.v2i32.p0(<2 x i32>, ptr, i32, <2 x i1>)

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

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

LGTM

@jhuber6 jhuber6 enabled auto-merge (squash) September 22, 2025 14:05
Align NewAlign = Fn(PtrOp, OldAlign, PrefAlign);
if (NewAlign <= OldAlign)
if (NewAlign <= OldAlign ||
NewAlign.value() > std::numeric_limits<uint32_t>().max())
Copy link
Contributor

Choose a reason for hiding this comment

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

Use Value::MaxAlignmentExponent / MaximumAlignment?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I figured this was more straightforward since the problem is that Align is stored as i64 but this argument is i32, so this makes it clear that it's a size issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

@arsenm We already use MaxAlignmentExponent -- the problem is that these specific intrinsics don't support the full alignment range (the maximum exponent is one less).

@jhuber6 jhuber6 merged commit 4d78801 into llvm:main Sep 22, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants