[llvm] [InferAlign] Eliminate `and ptr, -align` pattern (PR #171147)

via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 8 07:56:23 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Nikita Popov (nikic)

<details>
<summary>Changes</summary>

To complement the `and ptr, align-1 -> 0` pattern, also fold `and ptr, -align` to `ptr`.

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


2 Files Affected:

- (modified) llvm/lib/Transforms/Scalar/InferAlignment.cpp (+5) 
- (modified) llvm/test/Transforms/InferAlignment/ptrtoint.ll (+42) 


``````````diff
diff --git a/llvm/lib/Transforms/Scalar/InferAlignment.cpp b/llvm/lib/Transforms/Scalar/InferAlignment.cpp
index c0a147ed78231..93de58f7c8062 100644
--- a/llvm/lib/Transforms/Scalar/InferAlignment.cpp
+++ b/llvm/lib/Transforms/Scalar/InferAlignment.cpp
@@ -50,6 +50,11 @@ static bool tryToImproveAlign(
       I->replaceAllUsesWith(Constant::getNullValue(I->getType()));
       return true;
     }
+    if (Const->uge(
+            APInt::getBitsSetFrom(Const->getBitWidth(), Log2(ActualAlign)))) {
+      I->replaceAllUsesWith(I->getOperand(0));
+      return true;
+    }
   }
 
   IntrinsicInst *II = dyn_cast<IntrinsicInst>(I);
diff --git a/llvm/test/Transforms/InferAlignment/ptrtoint.ll b/llvm/test/Transforms/InferAlignment/ptrtoint.ll
index 3eb1f95d9c026..e4b30330e2220 100644
--- a/llvm/test/Transforms/InferAlignment/ptrtoint.ll
+++ b/llvm/test/Transforms/InferAlignment/ptrtoint.ll
@@ -62,3 +62,45 @@ define i64 @ptrtoaddr(ptr %ptr) {
   %v5 = and i64 %v3, 2
   ret i64 %v5
 }
+
+define i64 @redundant_mask(ptr %ptr) {
+; CHECK-LABEL: define i64 @redundant_mask(
+; CHECK-SAME: ptr [[PTR:%.*]]) {
+; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[PTR]], align 4
+; CHECK-NEXT:    [[INT:%.*]] = ptrtoint ptr [[PTR]] to i64
+; CHECK-NEXT:    [[MASK:%.*]] = and i64 [[INT]], -4
+; CHECK-NEXT:    ret i64 [[INT]]
+;
+  %load = load i32, ptr %ptr, align 4
+  %int = ptrtoint ptr %ptr to i64
+  %mask = and i64 %int, -4
+  ret i64 %mask
+}
+
+define i64 @redundant_mask2(ptr %ptr) {
+; CHECK-LABEL: define i64 @redundant_mask2(
+; CHECK-SAME: ptr [[PTR:%.*]]) {
+; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[PTR]], align 4
+; CHECK-NEXT:    [[INT:%.*]] = ptrtoint ptr [[PTR]] to i64
+; CHECK-NEXT:    [[MASK:%.*]] = and i64 [[INT]], -3
+; CHECK-NEXT:    ret i64 [[INT]]
+;
+  %load = load i32, ptr %ptr, align 4
+  %int = ptrtoint ptr %ptr to i64
+  %mask = and i64 %int, -3
+  ret i64 %mask
+}
+
+define i64 @not_redundant_mask(ptr %ptr) {
+; CHECK-LABEL: define i64 @not_redundant_mask(
+; CHECK-SAME: ptr [[PTR:%.*]]) {
+; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[PTR]], align 4
+; CHECK-NEXT:    [[INT:%.*]] = ptrtoint ptr [[PTR]] to i64
+; CHECK-NEXT:    [[MASK:%.*]] = and i64 [[INT]], -5
+; CHECK-NEXT:    ret i64 [[MASK]]
+;
+  %load = load i32, ptr %ptr, align 4
+  %int = ptrtoint ptr %ptr to i64
+  %mask = and i64 %int, -5
+  ret i64 %mask
+}

``````````

</details>


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


More information about the llvm-commits mailing list