Reapply "[InstCombine] Always fold alignment assumptions into operand bundles (#177597)"#179497
Merged
philnik777 merged 1 commit intollvm:mainfrom Feb 3, 2026
Merged
Conversation
Member
|
@llvm/pr-subscribers-llvm-transforms Author: Nikolas Klauser (philnik777) ChangesTruncating at 32 bits is now avoided by removing a cast to This reverts commit bc73157. Full diff: https://github.com/llvm/llvm-project/pull/179497.diff 4 Files Affected:
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index fcd0c89ea1e11..3559bcff4d932 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3685,8 +3685,7 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
// into
// call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 Constant + 1)]
uint64_t AlignMask = 1;
- if (EnableKnowledgeRetention &&
- (match(IIOperand, m_Not(m_Trunc(m_Value(A)))) ||
+ if ((match(IIOperand, m_Not(m_Trunc(m_Value(A)))) ||
match(IIOperand,
m_SpecificICmp(ICmpInst::ICMP_EQ,
m_And(m_Value(A), m_ConstantInt(AlignMask)),
@@ -3700,7 +3699,7 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
/// TODO: we can generate a GEP instead of merging the alignment with
/// the offset.
RetainedKnowledge RK{Attribute::Alignment,
- (unsigned)MinAlign(Offset, AlignMask + 1), A};
+ MinAlign(Offset, AlignMask + 1), A};
if (auto *Replacement =
buildAssumeFromKnowledge(RK, Next, &AC, &DT)) {
diff --git a/llvm/test/Transforms/InstCombine/assume-loop-align.ll b/llvm/test/Transforms/InstCombine/assume-loop-align.ll
index 24fd343d1448e..7669d5bae5b08 100644
--- a/llvm/test/Transforms/InstCombine/assume-loop-align.ll
+++ b/llvm/test/Transforms/InstCombine/assume-loop-align.ll
@@ -10,14 +10,8 @@ target triple = "x86_64-unknown-linux-gnu"
define void @foo(ptr %a, ptr %b) #0 {
; CHECK-LABEL: @foo(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint ptr [[A:%.*]] to i64
-; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 63
-; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
-; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]])
-; CHECK-NEXT: [[PTRINT1:%.*]] = ptrtoint ptr [[B:%.*]] to i64
-; CHECK-NEXT: [[MASKEDPTR2:%.*]] = and i64 [[PTRINT1]], 63
-; CHECK-NEXT: [[MASKCOND3:%.*]] = icmp eq i64 [[MASKEDPTR2]], 0
-; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND3]])
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A:%.*]], i64 64) ]
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[B:%.*]], i64 64) ]
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
diff --git a/llvm/test/Transforms/InstCombine/assume.ll b/llvm/test/Transforms/InstCombine/assume.ll
index cc87d6542fa12..ffb9bc8d14a2f 100644
--- a/llvm/test/Transforms/InstCombine/assume.ll
+++ b/llvm/test/Transforms/InstCombine/assume.ll
@@ -11,18 +11,10 @@ declare void @llvm.assume(i1) #1
; Check that the assume has not been removed:
define i32 @align_to_bundle(ptr %a) #0 {
-; DEFAULT-LABEL: @align_to_bundle(
-; DEFAULT-NEXT: [[T0:%.*]] = load i32, ptr [[A:%.*]], align 4
-; DEFAULT-NEXT: [[PTRINT:%.*]] = ptrtoint ptr [[A]] to i64
-; DEFAULT-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31
-; DEFAULT-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
-; DEFAULT-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]])
-; DEFAULT-NEXT: ret i32 [[T0]]
-;
-; BUNDLES-LABEL: @align_to_bundle(
-; BUNDLES-NEXT: [[T0:%.*]] = load i32, ptr [[A:%.*]], align 4
-; BUNDLES-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 32) ]
-; BUNDLES-NEXT: ret i32 [[T0]]
+; CHECK-LABEL: @align_to_bundle(
+; CHECK-NEXT: [[T0:%.*]] = load i32, ptr [[A:%.*]], align 4
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 32) ]
+; CHECK-NEXT: ret i32 [[T0]]
;
%t0 = load i32, ptr %a, align 4
%ptrint = ptrtoint ptr %a to i64
@@ -33,18 +25,10 @@ define i32 @align_to_bundle(ptr %a) #0 {
}
define i32 @align_to_bundle_ptrtoaddr(ptr %a) #0 {
-; DEFAULT-LABEL: @align_to_bundle_ptrtoaddr(
-; DEFAULT-NEXT: [[T0:%.*]] = load i32, ptr [[A:%.*]], align 4
-; DEFAULT-NEXT: [[PTRINT:%.*]] = ptrtoaddr ptr [[A]] to i64
-; DEFAULT-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31
-; DEFAULT-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
-; DEFAULT-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]])
-; DEFAULT-NEXT: ret i32 [[T0]]
-;
-; BUNDLES-LABEL: @align_to_bundle_ptrtoaddr(
-; BUNDLES-NEXT: [[T0:%.*]] = load i32, ptr [[A:%.*]], align 4
-; BUNDLES-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 32) ]
-; BUNDLES-NEXT: ret i32 [[T0]]
+; CHECK-LABEL: @align_to_bundle_ptrtoaddr(
+; CHECK-NEXT: [[T0:%.*]] = load i32, ptr [[A:%.*]], align 4
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 32) ]
+; CHECK-NEXT: ret i32 [[T0]]
;
%t0 = load i32, ptr %a, align 4
%ptrint = ptrtoaddr ptr %a to i64
@@ -55,18 +39,10 @@ define i32 @align_to_bundle_ptrtoaddr(ptr %a) #0 {
}
define i32 @align_assume_trunc_cond(ptr %a) #0 {
-; DEFAULT-LABEL: @align_assume_trunc_cond(
-; DEFAULT-NEXT: [[T0:%.*]] = load i32, ptr [[A:%.*]], align 4
-; DEFAULT-NEXT: [[PTRINT:%.*]] = ptrtoint ptr [[A]] to i64
-; DEFAULT-NEXT: [[TRUNC:%.*]] = trunc i64 [[PTRINT]] to i1
-; DEFAULT-NEXT: [[MASKCOND:%.*]] = xor i1 [[TRUNC]], true
-; DEFAULT-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]])
-; DEFAULT-NEXT: ret i32 [[T0]]
-;
-; BUNDLES-LABEL: @align_assume_trunc_cond(
-; BUNDLES-NEXT: [[T0:%.*]] = load i32, ptr [[A:%.*]], align 4
-; BUNDLES-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 2) ]
-; BUNDLES-NEXT: ret i32 [[T0]]
+; CHECK-LABEL: @align_assume_trunc_cond(
+; CHECK-NEXT: [[T0:%.*]] = load i32, ptr [[A:%.*]], align 4
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 2) ]
+; CHECK-NEXT: ret i32 [[T0]]
;
%t0 = load i32, ptr %a, align 4
%ptrint = ptrtoint ptr %a to i64
@@ -76,21 +52,41 @@ define i32 @align_assume_trunc_cond(ptr %a) #0 {
ret i32 %t0
}
+define void @align_32bit(ptr %ptr) {
+; CHECK-LABEL: @align_32bit(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[PTR:%.*]], i64 4294967296) ]
+; CHECK-NEXT: ret void
+;
+entry:
+ %0 = ptrtoint ptr %ptr to i64
+ %trunc = trunc i64 %0 to i32
+ %cmp = icmp eq i32 0, %trunc
+ call void @llvm.assume(i1 %cmp)
+ ret void
+}
+
+define void @align_63bit(ptr %ptr) {
+; CHECK-LABEL: @align_crash(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[PTR:%.*]], i64 -9223372036854775808) ]
+; CHECK-NEXT: ret void
+;
+entry:
+ %0 = ptrtoint ptr %ptr to i64
+ %trunc = trunc i64 %0 to i63
+ %cmp = icmp eq i63 0, %trunc
+ call void @llvm.assume(i1 %cmp)
+ ret void
+}
+
; Same check as in @foo1, but make sure it works if the assume is first too.
define i32 @foo2(ptr %a) #0 {
-; DEFAULT-LABEL: @foo2(
-; DEFAULT-NEXT: [[PTRINT:%.*]] = ptrtoint ptr [[A:%.*]] to i64
-; DEFAULT-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31
-; DEFAULT-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
-; DEFAULT-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]])
-; DEFAULT-NEXT: [[T0:%.*]] = load i32, ptr [[A]], align 4
-; DEFAULT-NEXT: ret i32 [[T0]]
-;
-; BUNDLES-LABEL: @foo2(
-; BUNDLES-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A:%.*]], i64 32) ]
-; BUNDLES-NEXT: [[T0:%.*]] = load i32, ptr [[A]], align 4
-; BUNDLES-NEXT: ret i32 [[T0]]
+; CHECK-LABEL: @foo2(
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A:%.*]], i64 32) ]
+; CHECK-NEXT: [[T0:%.*]] = load i32, ptr [[A]], align 4
+; CHECK-NEXT: ret i32 [[T0]]
;
%ptrint = ptrtoint ptr %a to i64
%maskedptr = and i64 %ptrint, 31
@@ -1075,4 +1071,3 @@ declare void @llvm.dbg.value(metadata, metadata, metadata)
attributes #0 = { nounwind uwtable }
attributes #1 = { nounwind }
-
diff --git a/llvm/test/Transforms/InstCombine/assume_inevitable.ll b/llvm/test/Transforms/InstCombine/assume_inevitable.ll
index 5f27ff1e609ba..f899be41e0584 100644
--- a/llvm/test/Transforms/InstCombine/assume_inevitable.ll
+++ b/llvm/test/Transforms/InstCombine/assume_inevitable.ll
@@ -16,10 +16,7 @@ define i32 @assume_inevitable(ptr %a, ptr %b, ptr %c) {
; CHECK-NEXT: [[M_A:%.*]] = call ptr @llvm.ptr.annotation.p0.p0(ptr nonnull [[M]], ptr nonnull @.str, ptr nonnull @.str1, i32 2, ptr null)
; CHECK-NEXT: [[OBJSZ:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[C:%.*]], i1 false, i1 false, i1 false)
; CHECK-NEXT: store i64 [[OBJSZ]], ptr [[M_A]], align 4
-; CHECK-NEXT: [[PTRINT:%.*]] = ptrtoint ptr [[A]] to i64
-; CHECK-NEXT: [[MASKEDPTR:%.*]] = and i64 [[PTRINT]], 31
-; CHECK-NEXT: [[MASKCOND:%.*]] = icmp eq i64 [[MASKEDPTR]], 0
-; CHECK-NEXT: tail call void @llvm.assume(i1 [[MASKCOND]])
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 32) ]
; CHECK-NEXT: ret i32 [[TMP0]]
;
entry:
|
… bundles (llvm#177597)" Truncating at 32 bits is now avoided by removing a cast to `unsigned`. This would also break at 64 bits, but I don't think LLVM supports such a thing. This reverts commit bc73157.
5c9206e to
33c4659
Compare
rishabhmadan19
pushed a commit
to rishabhmadan19/llvm-project
that referenced
this pull request
Feb 9, 2026
… bundles (llvm#177597)" (llvm#179497) Truncating at 32 bits is now avoided by removing a cast to `unsigned`. This would also break at 64 bits (with the pointer size > 64 bit), but I don't think LLVM supports such a thing. This reverts commit bc73157.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Truncating at 32 bits is now avoided by removing a cast to
unsigned.This would also break at 64 bits (with the pointer size > 64 bit), but I don't think LLVM supports such a
thing.
This reverts commit bc73157.