[llvm] [InstCombine] Move alignment assumptions to the base of a gep if alignment is preserved (PR #203032)

Nikolas Klauser via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 10 08:57:38 PDT 2026


https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/203032

None

>From f7412474da69cd364f7cd0b7f2bd9d3b9fbf358b Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Wed, 10 Jun 2026 17:55:45 +0200
Subject: [PATCH] [InstCombine] Move alignment assumptions to the base of a gep
 if alignment is preserved

---
 .../InstCombine/InstCombineCalls.cpp          |  8 +++++++
 llvm/test/Transforms/InstCombine/assume.ll    | 21 +++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index babf425dfbd5f..438df9552e47d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3665,6 +3665,14 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
         if (*Alignment == 1 || !isPowerOf2_64(*Alignment))
           return RemoveBundle();
 
+        if (auto *GEP = dyn_cast<GEPOperator>(Ptr);
+            GEP &&
+            GEP->getMaxPreservedAlignment(getDataLayout()) >= *Alignment) {
+          Builder.CreateAlignmentAssumption(
+              getDataLayout(), GEP->getPointerOperand(), *Alignment);
+          return RemoveBundle();
+        }
+
         // Don't try to remove align assumptions for pointers derived from
         // arguments. We might lose information if the function gets inline and
         // the align argument attribute disappears.
diff --git a/llvm/test/Transforms/InstCombine/assume.ll b/llvm/test/Transforms/InstCombine/assume.ll
index bf073b8d7ce70..f794eaa84a045 100644
--- a/llvm/test/Transforms/InstCombine/assume.ll
+++ b/llvm/test/Transforms/InstCombine/assume.ll
@@ -178,6 +178,27 @@ define void @align_with_variable_offset(ptr %ptr, i64 %offset) {
   ret void
 }
 
+define void @align_on_gep_keeping_alignment(ptr %ptr, i64 %offset) {
+; CHECK-LABEL: @align_on_gep_keeping_alignment(
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[PTR:%.*]], i64 8) ]
+; CHECK-NEXT:    ret void
+;
+  %ptr2 = getelementptr [8 x i8], ptr %ptr, i64 %offset
+  call void @llvm.assume(i1 true) [ "align"(ptr %ptr2, i64 8) ]
+  ret void
+}
+
+define void @align_on_gep_not_keeping_alignment(ptr %ptr, i64 %offset) {
+; CHECK-LABEL: @align_on_gep_not_keeping_alignment(
+; CHECK-NEXT:    [[PTR2:%.*]] = getelementptr [4 x i8], ptr [[PTR:%.*]], i64 [[OFFSET:%.*]]
+; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "align"(ptr [[PTR2]], i64 8) ]
+; CHECK-NEXT:    ret void
+;
+  %ptr2 = getelementptr [4 x i8], ptr %ptr, i64 %offset
+  call void @llvm.assume(i1 true) [ "align"(ptr %ptr2, i64 8) ]
+  ret void
+}
+
 define void @redundant_align() {
 ; CHECK-LABEL: @redundant_align(
 ; CHECK-NEXT:    [[PTR:%.*]] = call ptr @get_ptr()



More information about the llvm-commits mailing list