[llvm] [InstCombine] Add an option to skip simplification on call instruction where a non-void return value is expected while the callee returns void (PR #98536)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 15 14:44:38 PDT 2024
https://github.com/yozhu updated https://github.com/llvm/llvm-project/pull/98536
>From 03bb6f3b5d309c9dd9f0c901ca006783ca98bfca Mon Sep 17 00:00:00 2001
From: YongKang Zhu <yongzhu at fb.com>
Date: Thu, 11 Jul 2024 13:20:54 -0700
Subject: [PATCH 1/2] [InstCombine] Add an option to not take advantage of void
to non-void conversion on return value
---
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 0ca56f08c333d..880932159f570 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -89,6 +89,11 @@ static cl::opt<unsigned> GuardWideningWindow(
cl::desc("How wide an instruction window to bypass looking for "
"another guard"));
+static cl::opt<bool> SkipRetTypeVoidToNonVoidCallInst(
+ "instcombine-skip-call-ret-type-void-to-nonvoid", cl::init(false),
+ cl::desc("skip simplifying call instruction which expects a non-void "
+ "return value but the callee returns void"));
+
/// Return the specified type promoted as it would be to pass though a va_arg
/// area.
static Type *getPromotedType(Type *Ty) {
@@ -4073,7 +4078,7 @@ bool InstCombinerImpl::transformConstExprCastCall(CallBase &Call) {
if (!Caller->use_empty() &&
// void -> non-void is handled specially
- !NewRetTy->isVoidTy())
+ (SkipRetTypeVoidToNonVoidCallInst || !NewRetTy->isVoidTy()))
return false; // Cannot transform this return value.
}
>From 0ac5dd82380eec075492aef8c160b51843a25c4f Mon Sep 17 00:00:00 2001
From: YongKang Zhu <yongzhu at fb.com>
Date: Mon, 15 Jul 2024 14:43:33 -0700
Subject: [PATCH 2/2] Add a test case
---
.../skip-opt-void-to-non-void-conversion.ll | 67 +++++++++++++++++++
1 file changed, 67 insertions(+)
create mode 100644 llvm/test/Transforms/InstCombine/skip-opt-void-to-non-void-conversion.ll
diff --git a/llvm/test/Transforms/InstCombine/skip-opt-void-to-non-void-conversion.ll b/llvm/test/Transforms/InstCombine/skip-opt-void-to-non-void-conversion.ll
new file mode 100644
index 0000000000000..f0d5cc2dd8d03
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/skip-opt-void-to-non-void-conversion.ll
@@ -0,0 +1,67 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: llvm-as %s -o %t.bc
+; RUN: opt --passes=instcombine %t.bc -S | FileCheck %s --check-prefix=OPT
+; RUN: opt --passes=instcombine --instcombine-skip-call-ret-type-void-to-nonvoid %t.bc -S | \
+; RUN: FileCheck %s --check-prefix=SKIP
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-none-linux-android21"
+
+define dso_local void @foo() {
+entry:
+ ret void
+}
+
+define dso_local i32 @bar() {
+; OPT-LABEL: define dso_local i32 @bar() {
+; OPT-NEXT: [[ENTRY:.*:]]
+; OPT-NEXT: [[_RC_:%.*]] = alloca i32, align 4
+; OPT-NEXT: [[TMP0:%.*]] = load i32, ptr [[_RC_]], align 4
+; OPT-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
+; OPT-NEXT: br i1 [[CMP_NOT]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
+; OPT: [[IF_THEN]]:
+; OPT-NEXT: tail call void @foo()
+; OPT-NEXT: br i1 poison, label %[[IF_END]], label %[[CLEANUP:.*]]
+; OPT: [[IF_END]]:
+; OPT-NEXT: store i32 0, ptr [[_RC_]], align 4
+; OPT-NEXT: br label %[[CLEANUP]]
+; OPT: [[CLEANUP]]:
+; OPT-NEXT: [[TMP1:%.*]] = load i32, ptr [[_RC_]], align 4
+; OPT-NEXT: ret i32 [[TMP1]]
+;
+; SKIP-LABEL: define dso_local i32 @bar() {
+; SKIP-NEXT: [[ENTRY:.*:]]
+; SKIP-NEXT: [[_RC_:%.*]] = alloca i32, align 4
+; SKIP-NEXT: [[TMP0:%.*]] = load i32, ptr [[_RC_]], align 4
+; SKIP-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[TMP0]], 0
+; SKIP-NEXT: br i1 [[CMP_NOT]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
+; SKIP: [[IF_THEN]]:
+; SKIP-NEXT: [[CALL:%.*]] = tail call i32 @foo()
+; SKIP-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
+; SKIP-NEXT: br i1 [[CMP]], label %[[IF_END]], label %[[CLEANUP:.*]]
+; SKIP: [[IF_END]]:
+; SKIP-NEXT: store i32 0, ptr [[_RC_]], align 4
+; SKIP-NEXT: br label %[[CLEANUP]]
+; SKIP: [[CLEANUP]]:
+; SKIP-NEXT: [[TMP1:%.*]] = load i32, ptr [[_RC_]], align 4
+; SKIP-NEXT: ret i32 [[TMP1]]
+;
+entry:
+ %_rc_ = alloca i32, align 4
+ %2 = load i32, ptr %_rc_, align 4
+ %cmp.not = icmp eq i32 %2, 0
+ br i1 %cmp.not, label %if.then, label %if.end
+
+if.then:
+ %call = tail call i32 @foo()
+ %cmp = icmp eq i32 %call, 0
+ br i1 %cmp, label %if.end, label %cleanup
+
+if.end:
+ store i32 0, ptr %_rc_, align 4
+ br label %cleanup
+
+cleanup:
+ %7 = load i32, ptr %_rc_, align 4
+ ret i32 %7
+}
More information about the llvm-commits
mailing list