[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