Thanks to visit codestin.com
Credit goes to github.com

Skip to content

llvm-reduce: Change function return types if function is not called #134035

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

Conversation

arsenm
Copy link
Contributor

@arsenm arsenm commented Apr 2, 2025

Extend the early return on value reduction to mutate the function return
type if the function has no call uses. This could be generalized to rewrite
cases where all callsites are used, but it turns out that complicates the
visitation order given we try to compute all opportunities up front.

This is enough to cleanup the common case where we end up with one
function with a return of an uninteresting constant.

@arsenm arsenm removed the llvm:ir label Apr 2, 2025
@arsenm arsenm marked this pull request as ready for review April 2, 2025 06:25
@llvmbot
Copy link
Member

llvmbot commented Apr 2, 2025

@llvm/pr-subscribers-llvm-ir

Author: Matt Arsenault (arsenm)

Changes

Extend the early return on value reduction to mutate the function return
type if the function has no call uses. This could be generalized to rewrite
cases where all callsites are used, but it turns out that complicates the
visitation order given we try to compute all opportunities up front.

This is enough to cleanup the common case where we end up with one
function with a return of an uninteresting constant.


Full diff: https://github.com/llvm/llvm-project/pull/134035.diff

2 Files Affected:

  • (added) llvm/test/tools/llvm-reduce/reduce-values-to-return-new-return-type.ll (+95)
  • (modified) llvm/tools/llvm-reduce/deltas/ReduceValuesToReturn.cpp (+4-3)
diff --git a/llvm/test/tools/llvm-reduce/reduce-values-to-return-new-return-type.ll b/llvm/test/tools/llvm-reduce/reduce-values-to-return-new-return-type.ll
new file mode 100644
index 0000000000000..9ddbbe3def44f
--- /dev/null
+++ b/llvm/test/tools/llvm-reduce/reduce-values-to-return-new-return-type.ll
@@ -0,0 +1,95 @@
+; Test that llvm-reduce can move intermediate values by inserting
+; early returns when the function already has a different return type
+;
+; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=instructions-to-return --test FileCheck --test-arg --check-prefix=INTERESTING --test-arg %s --test-arg --input-file %s -o %t
+; RUN: FileCheck --check-prefix=RESULT %s < %t
+
+
+@gv = global i32 0, align 4
+@ptr_array = global [2 x ptr] [ptr @inst_to_return_has_different_type_but_no_func_call_use,
+                               ptr @multiple_callsites_wrong_return_type]
+
+; Should rewrite this return from i64 to i32 since the function has no
+; uses.
+; INTERESTING-LABEL: @inst_to_return_has_different_type_but_no_func_call_use(
+; RESULT-LABEL: define i32 @inst_to_return_has_different_type_but_no_func_call_use(ptr %arg) {
+; RESULT-NEXT: %load = load i32, ptr %arg, align 4
+; RESULT-NEXT: ret i32 %load
+define i64 @inst_to_return_has_different_type_but_no_func_call_use(ptr %arg) {
+  %load = load i32, ptr %arg
+  store i32 %load, ptr @gv
+  ret i64 0
+}
+
+; INTERESTING-LABEL: @callsite_different_type_unused_0(
+; RESULT-LABEL: define i64 @inst_to_return_has_different_type_but_call_result_unused(
+; RESULT-NEXT: %load = load i32, ptr %arg
+; RESULT-NEXT: store i32 %load, ptr @gv
+; RESULT-NEXT: ret i64 0
+define void @callsite_different_type_unused_0(ptr %arg) {
+  %unused0 = call i64 @inst_to_return_has_different_type_but_call_result_unused(ptr %arg)
+  %unused1 = call i64 @inst_to_return_has_different_type_but_call_result_unused(ptr null)
+  ret void
+}
+
+; TODO: Could rewrite this return from i64 to i32 since the callsite is unused.
+; INTERESTING-LABEL: @inst_to_return_has_different_type_but_call_result_unused(
+; RESULT-LABEL: define i64 @inst_to_return_has_different_type_but_call_result_unused(
+; RESULT: ret i64 0
+define i64 @inst_to_return_has_different_type_but_call_result_unused(ptr %arg) {
+  %load = load i32, ptr %arg
+  store i32 %load, ptr @gv
+  ret i64 0
+}
+
+; INTERESTING-LABEL: @multiple_callsites_wrong_return_type(
+; RESULT-LABEL: define i64 @multiple_callsites_wrong_return_type(
+; RESULT: ret i64 0
+define i64 @multiple_callsites_wrong_return_type(ptr %arg) {
+  %load = load i32, ptr %arg
+  store i32 %load, ptr @gv
+  ret i64 0
+}
+
+; INTERESTING-LABEL: @unused_with_wrong_return_types(
+; RESULT-LABEL: define i64 @unused_with_wrong_return_types(
+; RESULT-NEXT: %unused0 = call i64 @multiple_callsites_wrong_return_type(ptr %arg)
+; RESULT-NEXT: ret i64 %unused0
+define void @unused_with_wrong_return_types(ptr %arg) {
+  %unused0 = call i64 @multiple_callsites_wrong_return_type(ptr %arg)
+  %unused1 = call i32 @multiple_callsites_wrong_return_type(ptr %arg)
+  %unused2 = call ptr @multiple_callsites_wrong_return_type(ptr %arg)
+  ret void
+}
+
+; INTERESTING-LABEL: @multiple_returns_wrong_return_type(
+; INTERESTING: %load0 = load i32,
+
+; RESULT-LABEL: define i32 @multiple_returns_wrong_return_type(
+; RESULT: ret i32
+; RESULT: ret i32
+; RESULT: ret i32
+define i32 @multiple_returns_wrong_return_type(ptr %arg, i1 %cond, i32 %arg2) {
+entry:
+  br i1 %cond, label %bb0, label %bb1
+
+bb0:
+  %load0 = load i32, ptr %arg
+  store i32 %load0, ptr @gv
+  ret i32 234
+
+bb1:
+  ret i32 %arg2
+
+bb2:
+  ret i32 34
+}
+
+; INTERESTING-LABEL: @call_multiple_returns_wrong_return_type(
+; RESULT-LABEL: define <2 x i32> @call_multiple_returns_wrong_return_type(
+; RESULT-NEXT: %unused = call <2 x i32> @multiple_returns_wrong_return_type(
+; RESULT-NEXT: ret <2 x i32> %unused
+define void @call_multiple_returns_wrong_return_type(ptr %arg, i1 %cond, i32 %arg2) {
+  %unused = call <2 x i32> @multiple_returns_wrong_return_type(ptr %arg, i1 %cond, i32 %arg2)
+  ret void
+}
diff --git a/llvm/tools/llvm-reduce/deltas/ReduceValuesToReturn.cpp b/llvm/tools/llvm-reduce/deltas/ReduceValuesToReturn.cpp
index 3e400ffc89482..0a02298acc73e 100644
--- a/llvm/tools/llvm-reduce/deltas/ReduceValuesToReturn.cpp
+++ b/llvm/tools/llvm-reduce/deltas/ReduceValuesToReturn.cpp
@@ -164,7 +164,9 @@ static bool canReplaceFuncUsers(const Function &F, Type *NewRetTy) {
     if (CB->getType() == NewRetTy)
       continue;
 
-    LLVM_DEBUG(dbgs() << "Cannot replace callsite with wrong type: " << *CB
+    // TODO: If all callsites have no uses, we could mutate the type of all the
+    // callsites. This will complicate the visit and rewrite ordering though.
+    LLVM_DEBUG(dbgs() << "Cannot replace used callsite with wrong type: " << *CB
                       << '\n');
     return false;
   }
@@ -200,8 +202,7 @@ static bool shouldForwardValueToReturn(const BasicBlock &BB, const Value *V,
   if (!isReallyValidReturnType(V->getType()))
     return false;
 
-  return (RetTy->isVoidTy() ||
-          (RetTy == V->getType() && shouldReplaceNonVoidReturnValue(BB, V))) &&
+  return (RetTy->isVoidTy() || shouldReplaceNonVoidReturnValue(BB, V)) &&
          canReplaceFuncUsers(*BB.getParent(), V->getType());
 }
 

@arsenm
Copy link
Contributor Author

arsenm commented Apr 2, 2025

Forgot the part to fix the multiple return case

@arsenm arsenm force-pushed the users/arsenm/llvm-reduce/rewrite-function-return-types-no-call-uses branch from a413a52 to 4baf45b Compare April 2, 2025 07:44
Copy link

github-actions bot commented Apr 2, 2025

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff HEAD~1 HEAD --extensions cpp -- llvm/tools/llvm-reduce/deltas/ReduceValuesToReturn.cpp
View the diff from clang-format here.
diff --git a/llvm/tools/llvm-reduce/deltas/ReduceValuesToReturn.cpp b/llvm/tools/llvm-reduce/deltas/ReduceValuesToReturn.cpp
index 4ef2f50a6..8a5ccb998 100644
--- a/llvm/tools/llvm-reduce/deltas/ReduceValuesToReturn.cpp
+++ b/llvm/tools/llvm-reduce/deltas/ReduceValuesToReturn.cpp
@@ -59,7 +59,8 @@ static void rewriteFuncWithReturnType(Function &OldF, Value *NewRetValue) {
 
   Type *OldRetTy = OldFuncTy->getReturnType();
 
-  // Hack up any return values in other blocks, we can't leave them as returning OldRetTy.
+  // Hack up any return values in other blocks, we can't leave them as returning
+  // OldRetTy.
   if (OldRetTy != NewRetTy) {
     for (BasicBlock &OtherRetBB : OldF) {
       if (&OtherRetBB != NewRetBlock) {

@arsenm arsenm force-pushed the users/arsenm/llvm-reduce/add-reduce-values-to-return-argument-case branch from 449b087 to 3e646d9 Compare April 2, 2025 07:51
@arsenm arsenm force-pushed the users/arsenm/llvm-reduce/rewrite-function-return-types-no-call-uses branch from 4baf45b to 5490073 Compare April 2, 2025 07:51
@regehr
Copy link
Contributor

regehr commented Apr 2, 2025

LGTM!

@arsenm arsenm force-pushed the users/arsenm/llvm-reduce/rewrite-function-return-types-no-call-uses branch from 5490073 to f86430f Compare April 8, 2025 06:47
@arsenm arsenm force-pushed the users/arsenm/llvm-reduce/add-reduce-values-to-return-argument-case branch from 3e646d9 to 57ba2fd Compare April 8, 2025 06:47
Copy link
Contributor

@fhahn fhahn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks

@arsenm arsenm force-pushed the users/arsenm/llvm-reduce/rewrite-function-return-types-no-call-uses branch from f86430f to 59926c0 Compare April 23, 2025 20:19
@arsenm arsenm force-pushed the users/arsenm/llvm-reduce/add-reduce-values-to-return-argument-case branch from 57ba2fd to 51fde94 Compare April 23, 2025 20:19
@arsenm arsenm force-pushed the users/arsenm/llvm-reduce/rewrite-function-return-types-no-call-uses branch from 59926c0 to 254c039 Compare April 25, 2025 14:50
@arsenm arsenm force-pushed the users/arsenm/llvm-reduce/add-reduce-values-to-return-argument-case branch from 51fde94 to 19664d8 Compare April 25, 2025 14:50
@arsenm arsenm force-pushed the users/arsenm/llvm-reduce/rewrite-function-return-types-no-call-uses branch from 254c039 to 579ac18 Compare May 2, 2025 10:09
@arsenm arsenm force-pushed the users/arsenm/llvm-reduce/add-reduce-values-to-return-argument-case branch from 19664d8 to 562a680 Compare May 2, 2025 10:09
@arsenm arsenm force-pushed the users/arsenm/llvm-reduce/rewrite-function-return-types-no-call-uses branch from 579ac18 to d5457f8 Compare May 2, 2025 11:52
@arsenm arsenm force-pushed the users/arsenm/llvm-reduce/add-reduce-values-to-return-argument-case branch from 562a680 to 53a063e Compare May 2, 2025 11:52
Copy link
Contributor Author

arsenm commented May 2, 2025

Merge activity

  • May 2, 10:06 AM EDT: A user started a stack merge that includes this pull request via Graphite.
  • May 2, 10:18 AM EDT: Graphite rebased this pull request as part of a merge.
  • May 2, 10:20 AM EDT: @arsenm merged this pull request with Graphite.

@arsenm arsenm force-pushed the users/arsenm/llvm-reduce/add-reduce-values-to-return-argument-case branch 2 times, most recently from c48d5d5 to bc20481 Compare May 2, 2025 14:14
Base automatically changed from users/arsenm/llvm-reduce/add-reduce-values-to-return-argument-case to main May 2, 2025 14:17
arsenm and others added 5 commits May 2, 2025 14:17
Extend the early return on value reduction to mutate the function return
type if the function has no call uses. This could be generalized to rewrite
cases where all callsites are used, but it turns out that complicates the
visitation order given we try to compute all opportunities up front.

This is enough to cleanup the common case where we end up with one
function with a return of an uninteresting constant.
@arsenm arsenm force-pushed the users/arsenm/llvm-reduce/rewrite-function-return-types-no-call-uses branch from 19ec5ce to 07008f3 Compare May 2, 2025 14:17
@arsenm arsenm merged commit e3a81df into main May 2, 2025
4 of 9 checks passed
@arsenm arsenm deleted the users/arsenm/llvm-reduce/rewrite-function-return-types-no-call-uses branch May 2, 2025 14:20
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…lvm#134035)

Extend the early return on value reduction to mutate the function return
type if the function has no call uses. This could be generalized to rewrite
cases where all callsites are used, but it turns out that complicates the
visitation order given we try to compute all opportunities up front.

This is enough to cleanup the common case where we end up with one
function with a return of an uninteresting constant.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…lvm#134035)

Extend the early return on value reduction to mutate the function return
type if the function has no call uses. This could be generalized to rewrite
cases where all callsites are used, but it turns out that complicates the
visitation order given we try to compute all opportunities up front.

This is enough to cleanup the common case where we end up with one
function with a return of an uninteresting constant.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…lvm#134035)

Extend the early return on value reduction to mutate the function return
type if the function has no call uses. This could be generalized to rewrite
cases where all callsites are used, but it turns out that complicates the
visitation order given we try to compute all opportunities up front.

This is enough to cleanup the common case where we end up with one
function with a return of an uninteresting constant.
GeorgeARM pushed a commit to GeorgeARM/llvm-project that referenced this pull request May 7, 2025
…lvm#134035)

Extend the early return on value reduction to mutate the function return
type if the function has no call uses. This could be generalized to rewrite
cases where all callsites are used, but it turns out that complicates the
visitation order given we try to compute all opportunities up front.

This is enough to cleanup the common case where we end up with one
function with a return of an uninteresting constant.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants