[llvm] [EarlyCSE] Rematerialize alignment assumption. (PR #109131)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 24 08:56:35 PDT 2025
https://github.com/fhahn updated https://github.com/llvm/llvm-project/pull/109131
>From ca01092df8251271e18eb8230bcb81e3d8a9a65f Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Thu, 16 Jan 2025 17:24:35 +0000
Subject: [PATCH 1/6] [PhaseOrdering] Add eest making sure alignment doesn't
get dropped.
---
.../infer-align-from-assumption.ll | 82 +++++++++++++++++++
1 file changed, 82 insertions(+)
create mode 100644 llvm/test/Transforms/PhaseOrdering/infer-align-from-assumption.ll
diff --git a/llvm/test/Transforms/PhaseOrdering/infer-align-from-assumption.ll b/llvm/test/Transforms/PhaseOrdering/infer-align-from-assumption.ll
new file mode 100644
index 0000000000000..998f6fe5b7efc
--- /dev/null
+++ b/llvm/test/Transforms/PhaseOrdering/infer-align-from-assumption.ll
@@ -0,0 +1,82 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes='default<O3>' -S %s | FileCheck %s
+
+target triple = "arm64-apple-macosx"
+
+declare void @llvm.assume(i1 noundef)
+
+define i32 @entry(ptr %0) {
+; CHECK-LABEL: define i32 @entry(
+; CHECK-SAME: ptr nocapture [[TMP0:%.*]]) local_unnamed_addr {
+; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0]], align 8
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP2]], i64 4) ]
+; CHECK-NEXT: [[DOT0_COPYLOAD_I_I_I:%.*]] = load i32, ptr [[TMP2]], align 4
+; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 @swap(i32 [[DOT0_COPYLOAD_I_I_I]])
+; CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP0]], align 8
+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP4]], i64 4
+; CHECK-NEXT: store ptr [[TMP5]], ptr [[TMP0]], align 8
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP5]], i64 4) ]
+; CHECK-NEXT: [[DOT0_COPYLOAD_I_I_I1:%.*]] = load i32, ptr [[TMP5]], align 4
+; CHECK-NEXT: [[TMP6:%.*]] = tail call i32 @swap(i32 [[DOT0_COPYLOAD_I_I_I1]])
+; CHECK-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP0]], align 8
+; CHECK-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[TMP7]], i64 4
+; CHECK-NEXT: store ptr [[TMP8]], ptr [[TMP0]], align 8
+; CHECK-NEXT: ret i32 [[TMP6]]
+;
+ %2 = call i32 @fn1(ptr %0)
+ %3 = call i32 @fn1(ptr %0)
+ ret i32 %3
+}
+
+
+define i32 @fn1(ptr %0) {
+; CHECK-LABEL: define i32 @fn1(
+; CHECK-SAME: ptr nocapture [[TMP0:%.*]]) local_unnamed_addr {
+; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0]], align 8
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP2]], i64 4) ]
+; CHECK-NEXT: [[DOT0_COPYLOAD_I_I:%.*]] = load i32, ptr [[TMP2]], align 4
+; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 @swap(i32 [[DOT0_COPYLOAD_I_I]])
+; CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP0]], align 8
+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP4]], i64 4
+; CHECK-NEXT: store ptr [[TMP5]], ptr [[TMP0]], align 8
+; CHECK-NEXT: ret i32 [[TMP3]]
+;
+ %2 = call i32 @fn2(ptr %0)
+ ret i32 %2
+}
+
+define i32 @fn2(ptr %0) {
+; CHECK-LABEL: define i32 @fn2(
+; CHECK-SAME: ptr nocapture [[TMP0:%.*]]) local_unnamed_addr {
+; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0]], align 8
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP2]], i64 4) ]
+; CHECK-NEXT: [[DOT0_COPYLOAD_I:%.*]] = load i32, ptr [[TMP2]], align 4
+; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 @swap(i32 [[DOT0_COPYLOAD_I]])
+; CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[TMP0]], align 8
+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP4]], i64 4
+; CHECK-NEXT: store ptr [[TMP5]], ptr [[TMP0]], align 8
+; CHECK-NEXT: ret i32 [[TMP3]]
+;
+ %2 = load ptr, ptr %0, align 8
+ %3 = call i32 @load_assume_aligned(ptr %2)
+ %4 = load ptr, ptr %0, align 8
+ %5 = getelementptr i8, ptr %4, i64 4
+ store ptr %5, ptr %0, align 8
+ ret i32 %3
+}
+
+define i32 @load_assume_aligned(ptr %0) {
+; CHECK-LABEL: define i32 @load_assume_aligned(
+; CHECK-SAME: ptr [[TMP0:%.*]]) local_unnamed_addr {
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP0]], i64 4) ]
+; CHECK-NEXT: [[DOT0_COPYLOAD:%.*]] = load i32, ptr [[TMP0]], align 4
+; CHECK-NEXT: [[TMP2:%.*]] = tail call i32 @swap(i32 [[DOT0_COPYLOAD]])
+; CHECK-NEXT: ret i32 [[TMP2]]
+;
+ call void @llvm.assume(i1 true) [ "align"(ptr %0, i64 4) ]
+ %.0.copyload = load i32, ptr %0, align 1
+ %2 = call i32 @swap(i32 %.0.copyload)
+ ret i32 %2
+}
+
+declare i32 @swap(i32)
>From ee761ebfe02d86b37d4c6c2e6ccfeb9d75a00b18 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Wed, 18 Sep 2024 13:38:52 +0100
Subject: [PATCH 2/6] [EarlyCSE] Rematerialize alignment assumption.
---
llvm/lib/Transforms/Scalar/EarlyCSE.cpp | 13 +++++++++++++
.../EarlyCSE/materialize-align-assumptions.ll | 3 +++
2 files changed, 16 insertions(+)
diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
index 0f8cc6ca6ed21..26542ec6446da 100644
--- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
+++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
@@ -31,6 +31,7 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
@@ -1600,6 +1601,18 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
if (InVal.IsLoad)
if (auto *I = dyn_cast<Instruction>(Op))
combineMetadataForCSE(I, &Inst, false);
+
+ // If the load has align metadata, preserve it via an alignment
+ // assumption. Note that this doesn't use salavageKnowledge, as we need
+ // to create the assumption for the value we replaced the load with.
+ if (auto *AlignMD = Inst.getMetadata(LLVMContext::MD_align)) {
+ auto *A = mdconst::extract<ConstantInt>(AlignMD->getOperand(0));
+ if (Op->getPointerAlignment(SQ.DL).value() % A->getZExtValue() != 0) {
+ IRBuilder B(&Inst);
+ B.CreateAlignmentAssumption(SQ.DL, Op, A);
+ }
+ }
+
if (!Inst.use_empty())
Inst.replaceAllUsesWith(Op);
salvageKnowledge(&Inst, &AC);
diff --git a/llvm/test/Transforms/EarlyCSE/materialize-align-assumptions.ll b/llvm/test/Transforms/EarlyCSE/materialize-align-assumptions.ll
index ea63376957162..628577b097507 100644
--- a/llvm/test/Transforms/EarlyCSE/materialize-align-assumptions.ll
+++ b/llvm/test/Transforms/EarlyCSE/materialize-align-assumptions.ll
@@ -10,6 +10,7 @@ define ptr @align_replacement_does_not_have_align_metadata(ptr noalias %p) {
; CHECK-NEXT: call void @foo(ptr [[L_1]])
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[L_1]], i64 4
; CHECK-NEXT: store ptr [[GEP]], ptr [[P]], align 8
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[GEP]], i64 4) ]
; CHECK-NEXT: ret ptr [[GEP]]
;
%l.1 = load ptr, ptr %p, align 8
@@ -27,6 +28,7 @@ define ptr @align_replacement_does_not_have_align_metadata2(ptr noalias %p) {
; CHECK-NEXT: [[L_1:%.*]] = load ptr, ptr [[P]], align 8
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[L_1]], i64 4
; CHECK-NEXT: store ptr [[GEP]], ptr [[P]], align 8
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[GEP]], i64 4) ]
; CHECK-NEXT: ret ptr [[GEP]]
;
%l.1 = load ptr, ptr %p, align 8
@@ -54,6 +56,7 @@ define ptr @align_replacement_has_smaller_alignment(ptr noalias %p) {
; CHECK-SAME: ptr noalias [[P:%.*]]) {
; CHECK-NEXT: [[L_1:%.*]] = load ptr, ptr [[P]], align 8, !align [[META0]]
; CHECK-NEXT: call void @foo(ptr [[L_1]])
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[L_1]], i64 8) ]
; CHECK-NEXT: ret ptr [[L_1]]
;
%l.1 = load ptr, ptr %p, align 8, !align !0
>From f65dd4bfad861e18d41e72664f65df8fa71063a2 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Thu, 19 Sep 2024 21:33:40 +0100
Subject: [PATCH 3/6] !fixup check noundef
---
llvm/lib/Transforms/Scalar/EarlyCSE.cpp | 20 ++++++-----
.../EarlyCSE/materialize-align-assumptions.ll | 35 ++++++++++++++-----
2 files changed, 39 insertions(+), 16 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
index 26542ec6446da..44efe78c5c721 100644
--- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
+++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
@@ -1602,14 +1602,18 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
if (auto *I = dyn_cast<Instruction>(Op))
combineMetadataForCSE(I, &Inst, false);
- // If the load has align metadata, preserve it via an alignment
- // assumption. Note that this doesn't use salavageKnowledge, as we need
- // to create the assumption for the value we replaced the load with.
- if (auto *AlignMD = Inst.getMetadata(LLVMContext::MD_align)) {
- auto *A = mdconst::extract<ConstantInt>(AlignMD->getOperand(0));
- if (Op->getPointerAlignment(SQ.DL).value() % A->getZExtValue() != 0) {
- IRBuilder B(&Inst);
- B.CreateAlignmentAssumption(SQ.DL, Op, A);
+ // If the load has align and noundef metadata, preserve it via an
+ // alignment assumption. Note that this doesn't use salavageKnowledge,
+ // as we need to create the assumption for the value we replaced the
+ // load with.
+ if (Inst.hasMetadata(LLVMContext::MD_noundef)) {
+ if (auto *AlignMD = Inst.getMetadata(LLVMContext::MD_align)) {
+ auto *A = mdconst::extract<ConstantInt>(AlignMD->getOperand(0));
+ if (Op->getPointerAlignment(SQ.DL).value() % A->getZExtValue() !=
+ 0) {
+ IRBuilder B(&Inst);
+ B.CreateAlignmentAssumption(SQ.DL, Op, A);
+ }
}
}
diff --git a/llvm/test/Transforms/EarlyCSE/materialize-align-assumptions.ll b/llvm/test/Transforms/EarlyCSE/materialize-align-assumptions.ll
index 628577b097507..837a73a00d643 100644
--- a/llvm/test/Transforms/EarlyCSE/materialize-align-assumptions.ll
+++ b/llvm/test/Transforms/EarlyCSE/materialize-align-assumptions.ll
@@ -3,6 +3,24 @@
declare void @foo(ptr)
+define ptr @align_replacement_does_not_have_align_metadata_missing_noundef(ptr noalias %p) {
+; CHECK-LABEL: define ptr @align_replacement_does_not_have_align_metadata_missing_noundef(
+; CHECK-SAME: ptr noalias [[P:%.*]]) {
+; CHECK-NEXT: [[L_1:%.*]] = load ptr, ptr [[P]], align 8
+; CHECK-NEXT: call void @foo(ptr [[L_1]])
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[L_1]], i64 4
+; CHECK-NEXT: store ptr [[GEP]], ptr [[P]], align 8
+; CHECK-NEXT: ret ptr [[GEP]]
+;
+ %l.1 = load ptr, ptr %p, align 8
+ call void @foo(ptr %l.1)
+ %l.2 = load ptr, ptr %p, align 8
+ %gep = getelementptr i8, ptr %l.2, i64 4
+ store ptr %gep, ptr %p, align 8
+ %l.3 = load ptr, ptr %p, align 8, !align !0
+ ret ptr %l.3
+}
+
define ptr @align_replacement_does_not_have_align_metadata(ptr noalias %p) {
; CHECK-LABEL: define ptr @align_replacement_does_not_have_align_metadata(
; CHECK-SAME: ptr noalias [[P:%.*]]) {
@@ -18,7 +36,7 @@ define ptr @align_replacement_does_not_have_align_metadata(ptr noalias %p) {
%l.2 = load ptr, ptr %p, align 8
%gep = getelementptr i8, ptr %l.2, i64 4
store ptr %gep, ptr %p, align 8
- %l.3 = load ptr, ptr %p, align 8, !align !0
+ %l.3 = load ptr, ptr %p, align 8, !align !0, !noundef !{}
ret ptr %l.3
}
@@ -34,7 +52,7 @@ define ptr @align_replacement_does_not_have_align_metadata2(ptr noalias %p) {
%l.1 = load ptr, ptr %p, align 8
%gep = getelementptr i8, ptr %l.1, i64 4
store ptr %gep, ptr %p, align 8
- %l.2 = load ptr, ptr %p, align 8, !align !0
+ %l.2 = load ptr, ptr %p, align 8, !align !0, !noundef !{}
ret ptr %l.2
}
@@ -61,7 +79,7 @@ define ptr @align_replacement_has_smaller_alignment(ptr noalias %p) {
;
%l.1 = load ptr, ptr %p, align 8, !align !0
call void @foo(ptr %l.1)
- %l.2 = load ptr, ptr %p, align 8, !align !1
+ %l.2 = load ptr, ptr %p, align 8, !align !1, !noundef !{}
ret ptr %l.2
}
@@ -70,12 +88,12 @@ define ptr @align_replacement_has_larger_alignment(ptr %p) {
; CHECK-SAME: ptr [[P:%.*]]) {
; CHECK-NEXT: [[L_1:%.*]] = load ptr, ptr [[P]], align 8, !align [[META1:![0-9]+]]
; CHECK-NEXT: call void @foo(ptr [[L_1]])
-; CHECK-NEXT: [[L_2:%.*]] = load ptr, ptr [[P]], align 8, !align [[META0]]
+; CHECK-NEXT: [[L_2:%.*]] = load ptr, ptr [[P]], align 8, !align [[META0]], !noundef [[META2:![0-9]+]]
; CHECK-NEXT: ret ptr [[L_2]]
;
%l.1 = load ptr, ptr %p, align 8, !align !1
call void @foo(ptr %l.1)
- %l.2 = load ptr, ptr %p, align 8, !align !0
+ %l.2 = load ptr, ptr %p, align 8, !align !0, !noundef !{}
ret ptr %l.2
}
@@ -84,12 +102,12 @@ define ptr @align_1(ptr %p) {
; CHECK-SAME: ptr [[P:%.*]]) {
; CHECK-NEXT: [[L_1:%.*]] = load ptr, ptr [[P]], align 8
; CHECK-NEXT: call void @foo(ptr [[L_1]])
-; CHECK-NEXT: [[L_2:%.*]] = load ptr, ptr [[P]], align 8, !align [[META2:![0-9]+]]
+; CHECK-NEXT: [[L_2:%.*]] = load ptr, ptr [[P]], align 8, !align [[META3:![0-9]+]], !noundef [[META2]]
; CHECK-NEXT: ret ptr [[L_2]]
;
%l.1 = load ptr, ptr %p, align 8
call void @foo(ptr %l.1)
- %l.2 = load ptr, ptr %p, align 8, !align !2
+ %l.2 = load ptr, ptr %p, align 8, !align !2, !noundef !{}
ret ptr %l.2
}
@@ -99,5 +117,6 @@ define ptr @align_1(ptr %p) {
;.
; CHECK: [[META0]] = !{i64 4}
; CHECK: [[META1]] = !{i64 8}
-; CHECK: [[META2]] = !{i64 1}
+; CHECK: [[META2]] = !{}
+; CHECK: [[META3]] = !{i64 1}
;.
>From ada7b3fb2939a98c5d941e1b624c0f4ed582df5a Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Mon, 13 Jan 2025 21:31:42 +0000
Subject: [PATCH 4/6] Use computeKnownBits.
---
llvm/lib/Transforms/Scalar/EarlyCSE.cpp | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
index 44efe78c5c721..0dd32ac333dc8 100644
--- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
+++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
@@ -16,6 +16,7 @@
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopedHashTable.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AssumptionCache.h"
@@ -1608,9 +1609,11 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
// load with.
if (Inst.hasMetadata(LLVMContext::MD_noundef)) {
if (auto *AlignMD = Inst.getMetadata(LLVMContext::MD_align)) {
+ Inst.setMetadata(LLVMContext::MD_align, nullptr);
auto *A = mdconst::extract<ConstantInt>(AlignMD->getOperand(0));
- if (Op->getPointerAlignment(SQ.DL).value() % A->getZExtValue() !=
- 0) {
+ auto KB = computeKnownBits(Op, SQ.DL);
+ unsigned AlignFromKB = 1 << KB.countMinTrailingZeros();
+ if (AlignFromKB < A->getZExtValue()) {
IRBuilder B(&Inst);
B.CreateAlignmentAssumption(SQ.DL, Op, A);
}
>From 814eda2e32571c31fce5b5193941dce1fdb17685 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Tue, 14 Jan 2025 14:08:44 +0000
Subject: [PATCH 5/6] step
---
llvm/lib/Transforms/Scalar/EarlyCSE.cpp | 55 ++++++++++++++++++++++---
1 file changed, 49 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
index 0dd32ac333dc8..7bae85528a338 100644
--- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
+++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
@@ -1607,15 +1607,58 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
// alignment assumption. Note that this doesn't use salavageKnowledge,
// as we need to create the assumption for the value we replaced the
// load with.
- if (Inst.hasMetadata(LLVMContext::MD_noundef)) {
- if (auto *AlignMD = Inst.getMetadata(LLVMContext::MD_align)) {
+ if (auto *AlignMD = Inst.getMetadata(LLVMContext::MD_align)) {
+ if (Inst.hasMetadata(LLVMContext::MD_noundef) ||
+ programUndefinedIfPoison(&Inst)) {
Inst.setMetadata(LLVMContext::MD_align, nullptr);
- auto *A = mdconst::extract<ConstantInt>(AlignMD->getOperand(0));
+ auto *B = mdconst::extract<ConstantInt>(AlignMD->getOperand(0));
auto KB = computeKnownBits(Op, SQ.DL);
unsigned AlignFromKB = 1 << KB.countMinTrailingZeros();
- if (AlignFromKB < A->getZExtValue()) {
- IRBuilder B(&Inst);
- B.CreateAlignmentAssumption(SQ.DL, Op, A);
+ if (AlignFromKB < B->getZExtValue()) {
+ SetVector<const Value *> WorkList;
+ bool AlignNeeded = false;
+ for (const User *U : Inst.users())
+ if (auto *I = dyn_cast<Instruction>(U))
+ WorkList.insert(I);
+
+ for (unsigned I = 0; I != WorkList.size(); ++I) {
+ auto *Curr = WorkList[I];
+ if (auto *LI = dyn_cast<LoadInst>(Curr)) {
+ if (LI->getAlign().value() < B->getZExtValue()) {
+ AlignNeeded = true;
+ break;
+ }
+ continue;
+ }
+ if (auto *SI = dyn_cast<StoreInst>(Curr)) {
+ if (SI->getAlign().value() < B->getZExtValue()) {
+ AlignNeeded = true;
+ break;
+ }
+ continue;
+ }
+ if (isa<ReturnInst>(Curr)) {
+ AlignNeeded = true;
+ break;
+ }
+ if (isa<ICmpInst>(Curr) &&
+ !isa<Constant>(cast<Instruction>(Curr)->getOperand(0)) &&
+ !isa<Constant>(cast<Instruction>(Curr)->getOperand(1))) {
+ AlignNeeded = true;
+ break;
+ }
+ if (WorkList.size() > 16) {
+ AlignNeeded = true;
+ break;
+ }
+
+ for (const User *U : Curr->users())
+ WorkList.insert(cast<Instruction>(U));
+ }
+ if (AlignNeeded) {
+ IRBuilder Builder(&Inst);
+ Builder.CreateAlignmentAssumption(SQ.DL, Op, B);
+ }
}
}
}
>From a5610274add045426dcd0a120c4b37c8b0f1596b Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Wed, 24 Sep 2025 16:55:52 +0100
Subject: [PATCH 6/6] !fixup update tests
---
.../PhaseOrdering/infer-align-from-assumption.ll | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/test/Transforms/PhaseOrdering/infer-align-from-assumption.ll b/llvm/test/Transforms/PhaseOrdering/infer-align-from-assumption.ll
index 998f6fe5b7efc..e9bab1eac3ece 100644
--- a/llvm/test/Transforms/PhaseOrdering/infer-align-from-assumption.ll
+++ b/llvm/test/Transforms/PhaseOrdering/infer-align-from-assumption.ll
@@ -7,7 +7,7 @@ declare void @llvm.assume(i1 noundef)
define i32 @entry(ptr %0) {
; CHECK-LABEL: define i32 @entry(
-; CHECK-SAME: ptr nocapture [[TMP0:%.*]]) local_unnamed_addr {
+; CHECK-SAME: ptr captures(none) [[TMP0:%.*]]) local_unnamed_addr {
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0]], align 8
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP2]], i64 4) ]
; CHECK-NEXT: [[DOT0_COPYLOAD_I_I_I:%.*]] = load i32, ptr [[TMP2]], align 4
@@ -31,7 +31,7 @@ define i32 @entry(ptr %0) {
define i32 @fn1(ptr %0) {
; CHECK-LABEL: define i32 @fn1(
-; CHECK-SAME: ptr nocapture [[TMP0:%.*]]) local_unnamed_addr {
+; CHECK-SAME: ptr captures(none) [[TMP0:%.*]]) local_unnamed_addr {
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0]], align 8
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP2]], i64 4) ]
; CHECK-NEXT: [[DOT0_COPYLOAD_I_I:%.*]] = load i32, ptr [[TMP2]], align 4
@@ -47,7 +47,7 @@ define i32 @fn1(ptr %0) {
define i32 @fn2(ptr %0) {
; CHECK-LABEL: define i32 @fn2(
-; CHECK-SAME: ptr nocapture [[TMP0:%.*]]) local_unnamed_addr {
+; CHECK-SAME: ptr captures(none) [[TMP0:%.*]]) local_unnamed_addr {
; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP0]], align 8
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP2]], i64 4) ]
; CHECK-NEXT: [[DOT0_COPYLOAD_I:%.*]] = load i32, ptr [[TMP2]], align 4
@@ -67,7 +67,7 @@ define i32 @fn2(ptr %0) {
define i32 @load_assume_aligned(ptr %0) {
; CHECK-LABEL: define i32 @load_assume_aligned(
-; CHECK-SAME: ptr [[TMP0:%.*]]) local_unnamed_addr {
+; CHECK-SAME: ptr readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr {
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP0]], i64 4) ]
; CHECK-NEXT: [[DOT0_COPYLOAD:%.*]] = load i32, ptr [[TMP0]], align 4
; CHECK-NEXT: [[TMP2:%.*]] = tail call i32 @swap(i32 [[DOT0_COPYLOAD]])
More information about the llvm-commits
mailing list