[llvm] [InstCombine] Fold align assume into load's !align metadata if possible. (PR #123247)
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 16 14:45:36 PST 2025
https://github.com/fhahn updated https://github.com/llvm/llvm-project/pull/123247
>From 2fefc37be23dc910fd5458d3652d7dc69c48f8c9 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Tue, 17 Sep 2024 10:50:09 +0100
Subject: [PATCH 1/8] [InstCombine] Fold align assume into load's !align
metadata if possible.
If an alignment assumption is valid in the context of a corresponding
load of the pointer the assumption applies to, the assumption can be
replaced !align metadata on the load.
The benefits of folding it into !align are that existing code makes
better use of !align and it allows removing the now-redundant call
instructions.
---
.../InstCombine/InstCombineCalls.cpp | 25 ++++++++++++++++---
.../Transforms/InstCombine/assume-align.ll | 7 +++---
2 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 842881156dc67f..6af6f81200ccac 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3199,12 +3199,13 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
// TODO: apply range metadata for range check patterns?
}
- // Separate storage assumptions apply to the underlying allocations, not any
- // particular pointer within them. When evaluating the hints for AA purposes
- // we getUnderlyingObject them; by precomputing the answers here we can
- // avoid having to do so repeatedly there.
for (unsigned Idx = 0; Idx < II->getNumOperandBundles(); Idx++) {
OperandBundleUse OBU = II->getOperandBundleAt(Idx);
+
+ // Separate storage assumptions apply to the underlying allocations, not any
+ // particular pointer within them. When evaluating the hints for AA purposes
+ // we getUnderlyingObject them; by precomputing the answers here we can
+ // avoid having to do so repeatedly there.
if (OBU.getTagName() == "separate_storage") {
assert(OBU.Inputs.size() == 2);
auto MaybeSimplifyHint = [&](const Use &U) {
@@ -3218,6 +3219,22 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
MaybeSimplifyHint(OBU.Inputs[0]);
MaybeSimplifyHint(OBU.Inputs[1]);
}
+
+ // Try to fold alignment assumption into a load's !align metadata, if the assumption is valid in the load's context.
+ if (OBU.getTagName() == "align" && OBU.Inputs.size() == 2) {
+ auto *LI = dyn_cast<LoadInst>(OBU.Inputs[0]);
+ if (!LI || !isValidAssumeForContext(II, LI, &DT, /*AllowEphemerals=*/true))
+ continue;
+ auto *Align = cast<ConstantInt>(OBU.Inputs[1]);
+ if (!isPowerOf2_64(Align->getZExtValue()))
+ continue;
+ LI->setMetadata(LLVMContext::MD_align,
+ MDNode::get(II->getContext(),
+ ValueAsMetadata::getConstant(
+ Align)));
+ auto *New = CallBase::removeOperandBundle(II, OBU.getTagID());
+ return New;
+ }
}
// Convert nonnull assume like:
diff --git a/llvm/test/Transforms/InstCombine/assume-align.ll b/llvm/test/Transforms/InstCombine/assume-align.ll
index 47659ff8c84909..9631872148c010 100644
--- a/llvm/test/Transforms/InstCombine/assume-align.ll
+++ b/llvm/test/Transforms/InstCombine/assume-align.ll
@@ -123,11 +123,9 @@ define i8 @assume_align_non_pow2(ptr %p) {
ret i8 %v
}
-; TODO: Can fold alignment assumption into !align metadata on load.
define ptr @fold_assume_align_pow2_of_loaded_pointer_into_align_metadata(ptr %p) {
; CHECK-LABEL: @fold_assume_align_pow2_of_loaded_pointer_into_align_metadata(
-; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8
-; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i64 8) ]
+; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8, !align [[META0:![0-9]+]]
; CHECK-NEXT: ret ptr [[P2]]
;
%p2 = load ptr, ptr %p
@@ -171,3 +169,6 @@ define ptr @dont_fold_assume_align_zero_of_loaded_pointer_into_align_metadata(pt
call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 0) ]
ret ptr %p2
}
+;.
+; CHECK: [[META0]] = !{i64 8}
+;.
>From 4d7fc2f0ea97769952804bb58f876df218055f14 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Tue, 17 Sep 2024 12:09:07 +0100
Subject: [PATCH 2/8] !fix formatting.
---
.../InstCombine/InstCombineCalls.cpp | 21 ++++++++++---------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 6af6f81200ccac..f5f9805f1e558e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3202,10 +3202,10 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
for (unsigned Idx = 0; Idx < II->getNumOperandBundles(); Idx++) {
OperandBundleUse OBU = II->getOperandBundleAt(Idx);
- // Separate storage assumptions apply to the underlying allocations, not any
- // particular pointer within them. When evaluating the hints for AA purposes
- // we getUnderlyingObject them; by precomputing the answers here we can
- // avoid having to do so repeatedly there.
+ // Separate storage assumptions apply to the underlying allocations, not
+ // any particular pointer within them. When evaluating the hints for AA
+ // purposes we getUnderlyingObject them; by precomputing the answers here
+ // we can avoid having to do so repeatedly there.
if (OBU.getTagName() == "separate_storage") {
assert(OBU.Inputs.size() == 2);
auto MaybeSimplifyHint = [&](const Use &U) {
@@ -3220,18 +3220,19 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
MaybeSimplifyHint(OBU.Inputs[1]);
}
- // Try to fold alignment assumption into a load's !align metadata, if the assumption is valid in the load's context.
+ // Try to fold alignment assumption into a load's !align metadata, if the
+ // assumption is valid in the load's context.
if (OBU.getTagName() == "align" && OBU.Inputs.size() == 2) {
auto *LI = dyn_cast<LoadInst>(OBU.Inputs[0]);
- if (!LI || !isValidAssumeForContext(II, LI, &DT, /*AllowEphemerals=*/true))
+ if (!LI ||
+ !isValidAssumeForContext(II, LI, &DT, /*AllowEphemerals=*/true))
continue;
auto *Align = cast<ConstantInt>(OBU.Inputs[1]);
if (!isPowerOf2_64(Align->getZExtValue()))
continue;
- LI->setMetadata(LLVMContext::MD_align,
- MDNode::get(II->getContext(),
- ValueAsMetadata::getConstant(
- Align)));
+ LI->setMetadata(
+ LLVMContext::MD_align,
+ MDNode::get(II->getContext(), ValueAsMetadata::getConstant(Align)));
auto *New = CallBase::removeOperandBundle(II, OBU.getTagID());
return New;
}
>From b9452e6e27963784f5a969c449d76349bcdbecad Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Tue, 17 Sep 2024 13:04:56 +0100
Subject: [PATCH 3/8] !fixup check alignment is ConstantInt.
---
.../lib/Transforms/InstCombine/InstCombineCalls.cpp | 4 ++--
llvm/test/Transforms/InstCombine/assume-align.ll | 13 +++++++++++++
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index f5f9805f1e558e..dfca84ecd1d9c1 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3227,8 +3227,8 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
if (!LI ||
!isValidAssumeForContext(II, LI, &DT, /*AllowEphemerals=*/true))
continue;
- auto *Align = cast<ConstantInt>(OBU.Inputs[1]);
- if (!isPowerOf2_64(Align->getZExtValue()))
+ auto *Align = dyn_cast<ConstantInt>(OBU.Inputs[1]);
+ if (!Align || !isPowerOf2_64(Align->getZExtValue()))
continue;
LI->setMetadata(
LLVMContext::MD_align,
diff --git a/llvm/test/Transforms/InstCombine/assume-align.ll b/llvm/test/Transforms/InstCombine/assume-align.ll
index 9631872148c010..a021c41ae82e86 100644
--- a/llvm/test/Transforms/InstCombine/assume-align.ll
+++ b/llvm/test/Transforms/InstCombine/assume-align.ll
@@ -169,6 +169,19 @@ define ptr @dont_fold_assume_align_zero_of_loaded_pointer_into_align_metadata(pt
call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 0) ]
ret ptr %p2
}
+
+; !align must have a constant integer alignment.
+define ptr @dont_fold_assume_align_not_constant_of_loaded_pointer_into_align_metadata(ptr %p, i64 %align) {
+; CHECK-LABEL: @dont_fold_assume_align_not_constant_of_loaded_pointer_into_align_metadata(
+; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i64 [[ALIGN:%.*]]) ]
+; CHECK-NEXT: ret ptr [[P2]]
+;
+ %p2 = load ptr, ptr %p
+ call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 %align) ]
+ ret ptr %p2
+}
+
;.
; CHECK: [[META0]] = !{i64 8}
;.
>From cd957511c66975fd8a18e170a5dd3cf82ea12c3e Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Tue, 17 Sep 2024 13:10:16 +0100
Subject: [PATCH 4/8] !fixup check align type size.
---
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 2 +-
llvm/test/Transforms/InstCombine/assume-align.ll | 11 +++++++++++
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index dfca84ecd1d9c1..fa4e088813c31a 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3228,7 +3228,7 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
!isValidAssumeForContext(II, LI, &DT, /*AllowEphemerals=*/true))
continue;
auto *Align = dyn_cast<ConstantInt>(OBU.Inputs[1]);
- if (!Align || !isPowerOf2_64(Align->getZExtValue()))
+ if (!Align || !isPowerOf2_64(Align->getZExtValue()) || Align->getType()->getScalarSizeInBits() != 64)
continue;
LI->setMetadata(
LLVMContext::MD_align,
diff --git a/llvm/test/Transforms/InstCombine/assume-align.ll b/llvm/test/Transforms/InstCombine/assume-align.ll
index a021c41ae82e86..efd18703c49fa5 100644
--- a/llvm/test/Transforms/InstCombine/assume-align.ll
+++ b/llvm/test/Transforms/InstCombine/assume-align.ll
@@ -133,6 +133,17 @@ define ptr @fold_assume_align_pow2_of_loaded_pointer_into_align_metadata(ptr %p)
ret ptr %p2
}
+define ptr @dont_fold_assume_align_i32_pow2_of_loaded_pointer_into_align_metadata(ptr %p) {
+; CHECK-LABEL: @dont_fold_assume_align_i32_pow2_of_loaded_pointer_into_align_metadata(
+; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i32 8) ]
+; CHECK-NEXT: ret ptr [[P2]]
+;
+ %p2 = load ptr, ptr %p
+ call void @llvm.assume(i1 true) [ "align"(ptr %p2, i32 8) ]
+ ret ptr %p2
+}
+
define ptr @dont_fold_assume_align_pow2_of_loaded_pointer_into_align_metadata_due_to_call(ptr %p) {
; CHECK-LABEL: @dont_fold_assume_align_pow2_of_loaded_pointer_into_align_metadata_due_to_call(
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8
>From df2d7a971549e045dbf16b4e418ad7ae0fa47ad3 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Tue, 17 Sep 2024 13:17:56 +0100
Subject: [PATCH 5/8] !fixup use getKnowledgeFromBundle
---
.../lib/Transforms/InstCombine/InstCombineCalls.cpp | 13 +++++++++----
llvm/test/Transforms/InstCombine/assume-align.ll | 9 ++++-----
2 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index fa4e088813c31a..2a615d33479079 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3223,16 +3223,21 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
// Try to fold alignment assumption into a load's !align metadata, if the
// assumption is valid in the load's context.
if (OBU.getTagName() == "align" && OBU.Inputs.size() == 2) {
+ RetainedKnowledge RK = getKnowledgeFromBundle(
+ *cast<AssumeInst>(II), II->bundle_op_info_begin()[Idx]);
+ if (!RK || RK.AttrKind != Attribute::Alignment ||
+ !isPowerOf2_64(RK.ArgValue))
+ continue;
+
auto *LI = dyn_cast<LoadInst>(OBU.Inputs[0]);
if (!LI ||
!isValidAssumeForContext(II, LI, &DT, /*AllowEphemerals=*/true))
continue;
- auto *Align = dyn_cast<ConstantInt>(OBU.Inputs[1]);
- if (!Align || !isPowerOf2_64(Align->getZExtValue()) || Align->getType()->getScalarSizeInBits() != 64)
- continue;
+
LI->setMetadata(
LLVMContext::MD_align,
- MDNode::get(II->getContext(), ValueAsMetadata::getConstant(Align)));
+ MDNode::get(II->getContext(), ValueAsMetadata::getConstant(
+ Builder.getInt64(RK.ArgValue))));
auto *New = CallBase::removeOperandBundle(II, OBU.getTagID());
return New;
}
diff --git a/llvm/test/Transforms/InstCombine/assume-align.ll b/llvm/test/Transforms/InstCombine/assume-align.ll
index efd18703c49fa5..ffd43493deb311 100644
--- a/llvm/test/Transforms/InstCombine/assume-align.ll
+++ b/llvm/test/Transforms/InstCombine/assume-align.ll
@@ -133,10 +133,9 @@ define ptr @fold_assume_align_pow2_of_loaded_pointer_into_align_metadata(ptr %p)
ret ptr %p2
}
-define ptr @dont_fold_assume_align_i32_pow2_of_loaded_pointer_into_align_metadata(ptr %p) {
+define ptr @fold_assume_align_i32_pow2_of_loaded_pointer_into_align_metadata(ptr %p) {
; CHECK-LABEL: @dont_fold_assume_align_i32_pow2_of_loaded_pointer_into_align_metadata(
-; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8
-; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i32 8) ]
+; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8, !align [[META0]]
; CHECK-NEXT: ret ptr [[P2]]
;
%p2 = load ptr, ptr %p
@@ -184,8 +183,7 @@ define ptr @dont_fold_assume_align_zero_of_loaded_pointer_into_align_metadata(pt
; !align must have a constant integer alignment.
define ptr @dont_fold_assume_align_not_constant_of_loaded_pointer_into_align_metadata(ptr %p, i64 %align) {
; CHECK-LABEL: @dont_fold_assume_align_not_constant_of_loaded_pointer_into_align_metadata(
-; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8
-; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i64 [[ALIGN:%.*]]) ]
+; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8, !align [[META1:![0-9]+]]
; CHECK-NEXT: ret ptr [[P2]]
;
%p2 = load ptr, ptr %p
@@ -195,4 +193,5 @@ define ptr @dont_fold_assume_align_not_constant_of_loaded_pointer_into_align_met
;.
; CHECK: [[META0]] = !{i64 8}
+; CHECK: [[META1]] = !{i64 1}
;.
>From 2df1de93ed2ad7a320c7ef7579487e56b548a1f8 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Wed, 18 Sep 2024 11:37:09 +0100
Subject: [PATCH 6/8] !fixup update test check
---
llvm/test/Transforms/InstCombine/assume-align.ll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/Transforms/InstCombine/assume-align.ll b/llvm/test/Transforms/InstCombine/assume-align.ll
index ffd43493deb311..549821802fe674 100644
--- a/llvm/test/Transforms/InstCombine/assume-align.ll
+++ b/llvm/test/Transforms/InstCombine/assume-align.ll
@@ -134,7 +134,7 @@ define ptr @fold_assume_align_pow2_of_loaded_pointer_into_align_metadata(ptr %p)
}
define ptr @fold_assume_align_i32_pow2_of_loaded_pointer_into_align_metadata(ptr %p) {
-; CHECK-LABEL: @dont_fold_assume_align_i32_pow2_of_loaded_pointer_into_align_metadata(
+; CHECK-LABEL: @fold_assume_align_i32_pow2_of_loaded_pointer_into_align_metadata(
; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P:%.*]], align 8, !align [[META0]]
; CHECK-NEXT: ret ptr [[P2]]
;
>From 0782facaf57a28b36c10f60301254805b7fb2052 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Sun, 22 Dec 2024 11:16:58 +0000
Subject: [PATCH 7/8] [InstCombine] Add option to clean up some assumptions.
---
.../llvm/Transforms/InstCombine/InstCombine.h | 6 ++++++
llvm/lib/Passes/PassBuilder.cpp | 2 ++
llvm/lib/Passes/PassBuilderPipelines.cpp | 18 ++++++++++++------
llvm/lib/Passes/PassRegistry.def | 2 +-
.../InstCombine/InstCombineCalls.cpp | 1 -
.../InstCombine/InstCombineInternal.h | 8 ++++++--
.../InstCombine/InstructionCombining.cpp | 4 ++--
7 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/llvm/include/llvm/Transforms/InstCombine/InstCombine.h b/llvm/include/llvm/Transforms/InstCombine/InstCombine.h
index c12d749709cd25..dd9d05cbbcf7c9 100644
--- a/llvm/include/llvm/Transforms/InstCombine/InstCombine.h
+++ b/llvm/include/llvm/Transforms/InstCombine/InstCombine.h
@@ -31,6 +31,7 @@ struct InstCombineOptions {
// Verify that a fix point has been reached after MaxIterations.
bool VerifyFixpoint = false;
unsigned MaxIterations = InstCombineDefaultMaxIterations;
+ bool CleanupAssumptions = false;
InstCombineOptions() = default;
@@ -43,6 +44,11 @@ struct InstCombineOptions {
MaxIterations = Value;
return *this;
}
+
+ InstCombineOptions &setCleanupAssumptions(bool Value) {
+ CleanupAssumptions = Value;
+ return *this;
+ }
};
class InstCombinePass : public PassInfoMixin<InstCombinePass> {
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index f698a3df08ef78..ebf91c2ff1ca90 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -918,6 +918,8 @@ Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
ParamName).str(),
inconvertibleErrorCode());
Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
+ } else if (ParamName == "cleanup-assumptions") {
+ Result.setCleanupAssumptions(Enable);
} else {
return make_error<StringError>(
formatv("invalid InstCombine pass parameter '{0}' ", ParamName).str(),
diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
index 4ec0fb8fc81ea4..9985b946a54833 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -1305,7 +1305,8 @@ void PassBuilder::addVectorPasses(OptimizationLevel Level,
FPM.addPass(LoopLoadEliminationPass());
}
// Cleanup after the loop optimization passes.
- FPM.addPass(InstCombinePass());
+ FPM.addPass(
+ InstCombinePass(InstCombineOptions().setCleanupAssumptions(true)));
if (Level.getSpeedupLevel() > 1 && ExtraVectorizerPasses) {
ExtraFunctionPassManager<ShouldRunExtraVectorPasses> ExtraPasses;
@@ -1317,7 +1318,8 @@ void PassBuilder::addVectorPasses(OptimizationLevel Level,
// dead (or speculatable) control flows or more combining opportunities.
ExtraPasses.addPass(EarlyCSEPass());
ExtraPasses.addPass(CorrelatedValuePropagationPass());
- ExtraPasses.addPass(InstCombinePass());
+ ExtraPasses.addPass(
+ InstCombinePass(InstCombineOptions().setCleanupAssumptions(true)));
LoopPassManager LPM;
LPM.addPass(LICMPass(PTO.LicmMssaOptCap, PTO.LicmMssaNoAccForPromotionCap,
/*AllowSpeculation=*/true));
@@ -1328,7 +1330,8 @@ void PassBuilder::addVectorPasses(OptimizationLevel Level,
/*UseBlockFrequencyInfo=*/true));
ExtraPasses.addPass(
SimplifyCFGPass(SimplifyCFGOptions().convertSwitchRangeToICmp(true)));
- ExtraPasses.addPass(InstCombinePass());
+ ExtraPasses.addPass(
+ InstCombinePass(InstCombineOptions().setCleanupAssumptions(true)));
FPM.addPass(std::move(ExtraPasses));
}
@@ -1351,7 +1354,8 @@ void PassBuilder::addVectorPasses(OptimizationLevel Level,
if (IsFullLTO) {
FPM.addPass(SCCPPass());
- FPM.addPass(InstCombinePass());
+ FPM.addPass(
+ InstCombinePass(InstCombineOptions().setCleanupAssumptions(true)));
FPM.addPass(BDCEPass());
}
@@ -1366,7 +1370,8 @@ void PassBuilder::addVectorPasses(OptimizationLevel Level,
FPM.addPass(VectorCombinePass());
if (!IsFullLTO) {
- FPM.addPass(InstCombinePass());
+ FPM.addPass(
+ InstCombinePass(InstCombineOptions().setCleanupAssumptions(true)));
// Unroll small loops to hide loop backedge latency and saturate any
// parallel execution resources of an out-of-order processor. We also then
// need to clean up redundancies and loop invariant code.
@@ -1392,7 +1397,8 @@ void PassBuilder::addVectorPasses(OptimizationLevel Level,
}
FPM.addPass(InferAlignmentPass());
- FPM.addPass(InstCombinePass());
+ FPM.addPass(
+ InstCombinePass(InstCombineOptions().setCleanupAssumptions(true)));
// This is needed for two reasons:
// 1. It works around problems that instcombine introduces, such as sinking
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index a93a995655a147..fd985e46c71667 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -539,7 +539,7 @@ FUNCTION_PASS_WITH_PARAMS(
[](InstCombineOptions Opts) { return InstCombinePass(Opts); },
parseInstCombineOptions,
"no-use-loop-info;use-loop-info;no-verify-fixpoint;verify-fixpoint;"
- "max-iterations=N")
+ "max-iterations=N;cleanup-assumptions")
FUNCTION_PASS_WITH_PARAMS(
"loop-unroll", "LoopUnrollPass",
[](LoopUnrollOptions Opts) { return LoopUnrollPass(Opts); },
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 2a615d33479079..b8c5681c4aefde 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3228,7 +3228,6 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
if (!RK || RK.AttrKind != Attribute::Alignment ||
!isPowerOf2_64(RK.ArgValue))
continue;
-
auto *LI = dyn_cast<LoadInst>(OBU.Inputs[0]);
if (!LI ||
!isValidAssumeForContext(II, LI, &DT, /*AllowEphemerals=*/true))
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index 83e1da98deeda0..b365a41a87d7ac 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -59,6 +59,8 @@ class User;
class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
: public InstCombiner,
public InstVisitor<InstCombinerImpl, Instruction *> {
+ bool CleanupAssumptions = false;
+
public:
InstCombinerImpl(InstructionWorklist &Worklist, BuilderTy &Builder,
bool MinimizeSize, AAResults *AA, AssumptionCache &AC,
@@ -66,9 +68,11 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
DominatorTree &DT, OptimizationRemarkEmitter &ORE,
BlockFrequencyInfo *BFI, BranchProbabilityInfo *BPI,
ProfileSummaryInfo *PSI, const DataLayout &DL,
- ReversePostOrderTraversal<BasicBlock *> &RPOT)
+ ReversePostOrderTraversal<BasicBlock *> &RPOT,
+ bool CleanupAssumptions)
: InstCombiner(Worklist, Builder, MinimizeSize, AA, AC, TLI, TTI, DT, ORE,
- BFI, BPI, PSI, DL, RPOT) {}
+ BFI, BPI, PSI, DL, RPOT),
+ CleanupAssumptions(CleanupAssumptions) {}
virtual ~InstCombinerImpl() = default;
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 2fb60ef11499c7..d3a44e06eb61fa 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -5545,7 +5545,7 @@ static bool combineInstructionsOverFunction(
<< F.getName() << "\n");
InstCombinerImpl IC(Worklist, Builder, F.hasMinSize(), AA, AC, TLI, TTI, DT,
- ORE, BFI, BPI, PSI, DL, RPOT);
+ ORE, BFI, BPI, PSI, DL, RPOT, Opts.CleanupAssumptions);
IC.MaxArraySizeForCombine = MaxArraySize;
bool MadeChangeInThisIteration = IC.prepareWorklist(F);
MadeChangeInThisIteration |= IC.run();
@@ -5594,7 +5594,7 @@ PreservedAnalyses InstCombinePass::run(Function &F,
FunctionAnalysisManager &AM) {
auto &LRT = AM.getResult<LastRunTrackingAnalysis>(F);
// No changes since last InstCombine pass, exit early.
- if (LRT.shouldSkip(&ID))
+ if (LRT.shouldSkip(&ID) && !Options.CleanupAssumptions)
return PreservedAnalyses::all();
auto &AC = AM.getResult<AssumptionAnalysis>(F);
>From 764e5ece0113a5222bcbfc562361fd1da6ff660a Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Thu, 16 Jan 2025 22:29:43 +0000
Subject: [PATCH 8/8] !fixup skip arguments early
---
llvm/lib/Passes/PassBuilderPipelines.cpp | 10 +++++-----
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 5 +++++
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
index 9985b946a54833..9c17c938a626da 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -1319,7 +1319,7 @@ void PassBuilder::addVectorPasses(OptimizationLevel Level,
ExtraPasses.addPass(EarlyCSEPass());
ExtraPasses.addPass(CorrelatedValuePropagationPass());
ExtraPasses.addPass(
- InstCombinePass(InstCombineOptions().setCleanupAssumptions(true)));
+ InstCombinePass(InstCombineOptions()));
LoopPassManager LPM;
LPM.addPass(LICMPass(PTO.LicmMssaOptCap, PTO.LicmMssaNoAccForPromotionCap,
/*AllowSpeculation=*/true));
@@ -1331,7 +1331,7 @@ void PassBuilder::addVectorPasses(OptimizationLevel Level,
ExtraPasses.addPass(
SimplifyCFGPass(SimplifyCFGOptions().convertSwitchRangeToICmp(true)));
ExtraPasses.addPass(
- InstCombinePass(InstCombineOptions().setCleanupAssumptions(true)));
+ InstCombinePass());
FPM.addPass(std::move(ExtraPasses));
}
@@ -1355,7 +1355,7 @@ void PassBuilder::addVectorPasses(OptimizationLevel Level,
if (IsFullLTO) {
FPM.addPass(SCCPPass());
FPM.addPass(
- InstCombinePass(InstCombineOptions().setCleanupAssumptions(true)));
+ InstCombinePass(InstCombineOptions()));
FPM.addPass(BDCEPass());
}
@@ -1371,7 +1371,7 @@ void PassBuilder::addVectorPasses(OptimizationLevel Level,
if (!IsFullLTO) {
FPM.addPass(
- InstCombinePass(InstCombineOptions().setCleanupAssumptions(true)));
+ InstCombinePass(InstCombineOptions()));
// Unroll small loops to hide loop backedge latency and saturate any
// parallel execution resources of an out-of-order processor. We also then
// need to clean up redundancies and loop invariant code.
@@ -1398,7 +1398,7 @@ void PassBuilder::addVectorPasses(OptimizationLevel Level,
FPM.addPass(InferAlignmentPass());
FPM.addPass(
- InstCombinePass(InstCombineOptions().setCleanupAssumptions(true)));
+ InstCombinePass(InstCombineOptions()));
// This is needed for two reasons:
// 1. It works around problems that instcombine introduces, such as sinking
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index b8c5681c4aefde..856b9242c720f6 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3233,10 +3233,15 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
!isValidAssumeForContext(II, LI, &DT, /*AllowEphemerals=*/true))
continue;
+ if (!CleanupAssumptions && isa<Argument>(LI->getPointerOperand()))
+ continue;
LI->setMetadata(
LLVMContext::MD_align,
MDNode::get(II->getContext(), ValueAsMetadata::getConstant(
Builder.getInt64(RK.ArgValue))));
+ MDNode *MD = MDNode::get(II->getContext(), {});
+ LI->setMetadata(LLVMContext::MD_noundef, MD);
+
auto *New = CallBase::removeOperandBundle(II, OBU.getTagID());
return New;
}
More information about the llvm-commits
mailing list