-
Notifications
You must be signed in to change notification settings - Fork 14.7k
[licm] don't drop MD_prof
when dropping
#152420
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
mtrofin
wants to merge
1
commit into
main
Choose a base branch
from
users/mtrofin/08-06-_ir_md_prof_is_not_ub-implying
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Conversation
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
This stack of pull requests is managed by Graphite. Learn more about stacking. |
31a3f5c
to
f0cf2e9
Compare
82b2df1
to
9bea77f
Compare
7186d3e
to
15e7ab7
Compare
9bea77f
to
ac134fb
Compare
nikic
reviewed
Aug 9, 2025
nikic
reviewed
Aug 9, 2025
15e7ab7
to
df2474e
Compare
ac134fb
to
cac2eba
Compare
df2474e
to
d35d9df
Compare
cac2eba
to
b8aa221
Compare
d35d9df
to
336185b
Compare
@llvm/pr-subscribers-llvm-transforms Author: Mircea Trofin (mtrofin) ChangesFull diff: https://github.com/llvm/llvm-project/pull/152420.diff 4 Files Affected:
diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h
index 5d25804a684ac..2eb4fd36c5b7d 100644
--- a/llvm/include/llvm/IR/Instruction.h
+++ b/llvm/include/llvm/IR/Instruction.h
@@ -584,9 +584,10 @@ class Instruction : public User,
dropUBImplyingAttrsAndUnknownMetadata(ArrayRef<unsigned> KnownIDs = {});
/// Drop any attributes or metadata that can cause immediate undefined
- /// behavior. Retain other attributes/metadata on a best-effort basis.
- /// This should be used when speculating instructions.
- LLVM_ABI void dropUBImplyingAttrsAndMetadata();
+ /// behavior. Retain other attributes/metadata on a best-effort basis, as well
+ /// as those passed in `Keep`. This should be used when speculating
+ /// instructions.
+ LLVM_ABI void dropUBImplyingAttrsAndMetadata(ArrayRef<unsigned> Keep = {});
/// Return true if this instruction has UB-implying attributes
/// that can cause immediate undefined behavior.
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index cf19b97333514..2815ea8498b4a 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -554,13 +554,15 @@ void Instruction::dropUBImplyingAttrsAndUnknownMetadata(
CB->removeRetAttrs(UBImplyingAttributes);
}
-void Instruction::dropUBImplyingAttrsAndMetadata() {
+void Instruction::dropUBImplyingAttrsAndMetadata(ArrayRef<unsigned> Keep) {
// !annotation metadata does not impact semantics.
// !range, !nonnull and !align produce poison, so they are safe to speculate.
// !noundef and various AA metadata must be dropped, as it generally produces
// immediate undefined behavior.
- unsigned KnownIDs[] = {LLVMContext::MD_annotation, LLVMContext::MD_range,
- LLVMContext::MD_nonnull, LLVMContext::MD_align};
+ SmallVector<unsigned> KnownIDs(Keep.size() + 4);
+ KnownIDs.append({LLVMContext::MD_annotation, LLVMContext::MD_range,
+ LLVMContext::MD_nonnull, LLVMContext::MD_align});
+ append_range(KnownIDs, Keep);
dropUBImplyingAttrsAndUnknownMetadata(KnownIDs);
}
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index 34adc7745f67c..7a203638a1d78 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -1698,8 +1698,12 @@ static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop,
// The check on hasMetadataOtherThanDebugLoc is to prevent us from burning
// time in isGuaranteedToExecute if we don't actually have anything to
// drop. It is a compile time optimization, not required for correctness.
- !SafetyInfo->isGuaranteedToExecute(I, DT, CurLoop))
- I.dropUBImplyingAttrsAndMetadata();
+ !SafetyInfo->isGuaranteedToExecute(I, DT, CurLoop)) {
+ if (ProfcheckDisableMetadataFixes)
+ I.dropUBImplyingAttrsAndMetadata();
+ else
+ I.dropUBImplyingAttrsAndMetadata({LLVMContext::MD_prof});
+ }
if (isa<PHINode>(I))
// Move the new node to the end of the phi list in the destination block.
diff --git a/llvm/test/Transforms/LICM/hoist-profdata.ll b/llvm/test/Transforms/LICM/hoist-profdata.ll
new file mode 100644
index 0000000000000..18fa1b9f92e8a
--- /dev/null
+++ b/llvm/test/Transforms/LICM/hoist-profdata.ll
@@ -0,0 +1,45 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals --version 2
+; Test that hoisting conditional branches copies the debug and profiling info
+; metadata from the branch being hoisted.
+; RUN: opt -S -passes=licm %s -o - | FileCheck %s
+
+declare i32 @foo()
+
+; to_hoist should get hoisted, and that should not result
+; in a loss of profiling info
+define i32 @hoist_select(i1 %cond, i32 %a, i32 %b) nounwind {
+; CHECK-LABEL: define i32 @hoist_select
+; CHECK-SAME: (i1 [[COND:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TO_HOIST:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]], !prof [[PROF0:![0-9]+]]
+; CHECK-NEXT: br label [[L0:%.*]]
+; CHECK: L0:
+; CHECK-NEXT: [[G:%.*]] = call i32 @foo()
+; CHECK-NEXT: [[SUM:%.*]] = add i32 [[G]], [[TO_HOIST]]
+; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[SUM]], 0
+; CHECK-NEXT: br i1 [[C]], label [[L0]], label [[EXIT:%.*]], !prof [[PROF1:![0-9]+]]
+; CHECK: exit:
+; CHECK-NEXT: [[SUM_LCSSA:%.*]] = phi i32 [ [[SUM]], [[L0]] ]
+; CHECK-NEXT: ret i32 [[SUM_LCSSA]]
+;
+entry:
+ br label %L0
+L0:
+ %g = call i32 @foo()
+ %to_hoist = select i1 %cond, i32 %a, i32 %b, !prof !0
+ %sum = add i32 %g, %to_hoist
+ %c = icmp eq i32 %sum, 0
+ br i1 %c, label %L0, label %exit, !prof !1
+
+exit:
+ ret i32 %sum
+}
+
+!0 = !{!"branch_weights", i32 2, i32 5}
+!1 = !{!"branch_weights", i32 101, i32 189}
+;.
+; CHECK: attributes #[[ATTR0]] = { nounwind }
+;.
+; CHECK: [[PROF0]] = !{!"branch_weights", i32 2, i32 5}
+; CHECK: [[PROF1]] = !{!"branch_weights", i32 101, i32 189}
+;.
|
@llvm/pr-subscribers-llvm-ir Author: Mircea Trofin (mtrofin) ChangesFull diff: https://github.com/llvm/llvm-project/pull/152420.diff 4 Files Affected:
diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h
index 5d25804a684ac..2eb4fd36c5b7d 100644
--- a/llvm/include/llvm/IR/Instruction.h
+++ b/llvm/include/llvm/IR/Instruction.h
@@ -584,9 +584,10 @@ class Instruction : public User,
dropUBImplyingAttrsAndUnknownMetadata(ArrayRef<unsigned> KnownIDs = {});
/// Drop any attributes or metadata that can cause immediate undefined
- /// behavior. Retain other attributes/metadata on a best-effort basis.
- /// This should be used when speculating instructions.
- LLVM_ABI void dropUBImplyingAttrsAndMetadata();
+ /// behavior. Retain other attributes/metadata on a best-effort basis, as well
+ /// as those passed in `Keep`. This should be used when speculating
+ /// instructions.
+ LLVM_ABI void dropUBImplyingAttrsAndMetadata(ArrayRef<unsigned> Keep = {});
/// Return true if this instruction has UB-implying attributes
/// that can cause immediate undefined behavior.
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index cf19b97333514..2815ea8498b4a 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -554,13 +554,15 @@ void Instruction::dropUBImplyingAttrsAndUnknownMetadata(
CB->removeRetAttrs(UBImplyingAttributes);
}
-void Instruction::dropUBImplyingAttrsAndMetadata() {
+void Instruction::dropUBImplyingAttrsAndMetadata(ArrayRef<unsigned> Keep) {
// !annotation metadata does not impact semantics.
// !range, !nonnull and !align produce poison, so they are safe to speculate.
// !noundef and various AA metadata must be dropped, as it generally produces
// immediate undefined behavior.
- unsigned KnownIDs[] = {LLVMContext::MD_annotation, LLVMContext::MD_range,
- LLVMContext::MD_nonnull, LLVMContext::MD_align};
+ SmallVector<unsigned> KnownIDs(Keep.size() + 4);
+ KnownIDs.append({LLVMContext::MD_annotation, LLVMContext::MD_range,
+ LLVMContext::MD_nonnull, LLVMContext::MD_align});
+ append_range(KnownIDs, Keep);
dropUBImplyingAttrsAndUnknownMetadata(KnownIDs);
}
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index 34adc7745f67c..7a203638a1d78 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -1698,8 +1698,12 @@ static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop,
// The check on hasMetadataOtherThanDebugLoc is to prevent us from burning
// time in isGuaranteedToExecute if we don't actually have anything to
// drop. It is a compile time optimization, not required for correctness.
- !SafetyInfo->isGuaranteedToExecute(I, DT, CurLoop))
- I.dropUBImplyingAttrsAndMetadata();
+ !SafetyInfo->isGuaranteedToExecute(I, DT, CurLoop)) {
+ if (ProfcheckDisableMetadataFixes)
+ I.dropUBImplyingAttrsAndMetadata();
+ else
+ I.dropUBImplyingAttrsAndMetadata({LLVMContext::MD_prof});
+ }
if (isa<PHINode>(I))
// Move the new node to the end of the phi list in the destination block.
diff --git a/llvm/test/Transforms/LICM/hoist-profdata.ll b/llvm/test/Transforms/LICM/hoist-profdata.ll
new file mode 100644
index 0000000000000..18fa1b9f92e8a
--- /dev/null
+++ b/llvm/test/Transforms/LICM/hoist-profdata.ll
@@ -0,0 +1,45 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals --version 2
+; Test that hoisting conditional branches copies the debug and profiling info
+; metadata from the branch being hoisted.
+; RUN: opt -S -passes=licm %s -o - | FileCheck %s
+
+declare i32 @foo()
+
+; to_hoist should get hoisted, and that should not result
+; in a loss of profiling info
+define i32 @hoist_select(i1 %cond, i32 %a, i32 %b) nounwind {
+; CHECK-LABEL: define i32 @hoist_select
+; CHECK-SAME: (i1 [[COND:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TO_HOIST:%.*]] = select i1 [[COND]], i32 [[A]], i32 [[B]], !prof [[PROF0:![0-9]+]]
+; CHECK-NEXT: br label [[L0:%.*]]
+; CHECK: L0:
+; CHECK-NEXT: [[G:%.*]] = call i32 @foo()
+; CHECK-NEXT: [[SUM:%.*]] = add i32 [[G]], [[TO_HOIST]]
+; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[SUM]], 0
+; CHECK-NEXT: br i1 [[C]], label [[L0]], label [[EXIT:%.*]], !prof [[PROF1:![0-9]+]]
+; CHECK: exit:
+; CHECK-NEXT: [[SUM_LCSSA:%.*]] = phi i32 [ [[SUM]], [[L0]] ]
+; CHECK-NEXT: ret i32 [[SUM_LCSSA]]
+;
+entry:
+ br label %L0
+L0:
+ %g = call i32 @foo()
+ %to_hoist = select i1 %cond, i32 %a, i32 %b, !prof !0
+ %sum = add i32 %g, %to_hoist
+ %c = icmp eq i32 %sum, 0
+ br i1 %c, label %L0, label %exit, !prof !1
+
+exit:
+ ret i32 %sum
+}
+
+!0 = !{!"branch_weights", i32 2, i32 5}
+!1 = !{!"branch_weights", i32 101, i32 189}
+;.
+; CHECK: attributes #[[ATTR0]] = { nounwind }
+;.
+; CHECK: [[PROF0]] = !{!"branch_weights", i32 2, i32 5}
+; CHECK: [[PROF1]] = !{!"branch_weights", i32 101, i32 189}
+;.
|
336ba46
to
6b1a568
Compare
b8aa221
to
223404b
Compare
MD_prof
when dropping
223404b
to
871de1e
Compare
6b1a568
to
9487727
Compare
This was referenced Aug 12, 2025
9487727
to
76de28d
Compare
871de1e
to
8ed35ac
Compare
Base automatically changed from
users/mtrofin/08-05-_licm_clone_metadata_when_hoisting_conditional_branch
to
main
August 13, 2025 00:01
76de28d
to
714993c
Compare
714993c
to
3144e61
Compare
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.
No description provided.