[llvm] [InlineCost] Simplify extractvalue across callsite (PR #145054)

Tobias Stadler via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 23 10:22:42 PDT 2025


https://github.com/tobias-stadler updated https://github.com/llvm/llvm-project/pull/145054

>From f2890102b2ad4bd5ae4c3677e1811def99f31ca6 Mon Sep 17 00:00:00 2001
From: Tobias Stadler <mail at stadler-tobias.de>
Date: Wed, 18 Jun 2025 23:31:35 +0100
Subject: [PATCH 1/2] [InlineCost] Simplify extractvalue across callsite

---
 llvm/lib/Analysis/InlineCost.cpp              | 15 +++++--
 .../Inline/simplify-crosscallsite.ll          | 39 +++++++++++++++++++
 2 files changed, 51 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/Transforms/Inline/simplify-crosscallsite.ll

diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp
index fe1ceb74429c9..773a60479ae22 100644
--- a/llvm/lib/Analysis/InlineCost.cpp
+++ b/llvm/lib/Analysis/InlineCost.cpp
@@ -2316,9 +2316,18 @@ bool CallAnalyzer::visitStore(StoreInst &I) {
 }
 
 bool CallAnalyzer::visitExtractValue(ExtractValueInst &I) {
-  // Constant folding for extract value is trivial.
-  if (simplifyInstruction(I))
-    return true;
+  Value *Op = I.getAggregateOperand();
+
+  // Special handling, because we want to simplify extractvalue with a
+  // potential insertvalue from the caller.
+  if (Value *SimpleOp = getSimplifiedValueUnchecked(Op)) {
+    SimplifyQuery SQ(DL);
+    Value *SimpleV = simplifyExtractValueInst(SimpleOp, I.getIndices(), SQ);
+    if (SimpleV) {
+      SimplifiedValues[&I] = SimpleV;
+      return true;
+    }
+  }
 
   // SROA can't look through these, but they may be free.
   return Base::visitExtractValue(I);
diff --git a/llvm/test/Transforms/Inline/simplify-crosscallsite.ll b/llvm/test/Transforms/Inline/simplify-crosscallsite.ll
new file mode 100644
index 0000000000000..0c0207a4883da
--- /dev/null
+++ b/llvm/test/Transforms/Inline/simplify-crosscallsite.ll
@@ -0,0 +1,39 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -S -passes=inline | FileCheck %s
+
+define i32 @callee([2 x i32] %agg) {
+; CHECK-LABEL: define i32 @callee(
+; CHECK-SAME: [2 x i32] [[AGG:%.*]]) {
+; CHECK-NEXT:    [[V:%.*]] = extractvalue [2 x i32] [[AGG]], 0
+; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[V]], 0
+; CHECK-NEXT:    br i1 [[C]], label %[[IS_NULL:.*]], label %[[NON_NULL:.*]]
+; CHECK:       [[IS_NULL]]:
+; CHECK-NEXT:    ret i32 0
+; CHECK:       [[NON_NULL]]:
+; CHECK-NEXT:    [[R:%.*]] = call i32 @callee([2 x i32] [[AGG]])
+; CHECK-NEXT:    ret i32 [[R]]
+;
+  %v = extractvalue [2 x i32] %agg, 0
+  %c = icmp eq i32 %v, 0
+  br i1 %c, label %is_null, label %non_null
+
+is_null:
+  ret i32 0
+
+non_null:
+  %r = call i32 @callee([2 x i32] %agg)
+  ret i32 %r
+}
+
+define i32 @caller(i32 %arg) {
+; CHECK-LABEL: define i32 @caller(
+; CHECK-SAME: i32 [[ARG:%.*]]) {
+; CHECK-NEXT:    [[AGG0:%.*]] = insertvalue [2 x i32] poison, i32 0, 0
+; CHECK-NEXT:    [[AGG1:%.*]] = insertvalue [2 x i32] [[AGG0]], i32 [[ARG]], 1
+; CHECK-NEXT:    ret i32 0
+;
+  %agg0 = insertvalue [2 x i32] poison, i32 0, 0
+  %agg1 = insertvalue [2 x i32] %agg0, i32 %arg, 1
+  %v = call i32 @callee([2 x i32] %agg1)
+  ret i32 %v
+}

>From 0767ab9e80aabe7fda36416c34dd5178d4d1de4d Mon Sep 17 00:00:00 2001
From: Tobias Stadler <mail at stadler-tobias.de>
Date: Mon, 23 Jun 2025 17:26:38 +0100
Subject: [PATCH 2/2] Add negative test

---
 .../Inline/simplify-crosscallsite.ll           | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/llvm/test/Transforms/Inline/simplify-crosscallsite.ll b/llvm/test/Transforms/Inline/simplify-crosscallsite.ll
index 0c0207a4883da..4c55595ddd2c5 100644
--- a/llvm/test/Transforms/Inline/simplify-crosscallsite.ll
+++ b/llvm/test/Transforms/Inline/simplify-crosscallsite.ll
@@ -25,8 +25,8 @@ non_null:
   ret i32 %r
 }
 
-define i32 @caller(i32 %arg) {
-; CHECK-LABEL: define i32 @caller(
+define i32 @caller_simplified(i32 %arg) {
+; CHECK-LABEL: define i32 @caller_simplified(
 ; CHECK-SAME: i32 [[ARG:%.*]]) {
 ; CHECK-NEXT:    [[AGG0:%.*]] = insertvalue [2 x i32] poison, i32 0, 0
 ; CHECK-NEXT:    [[AGG1:%.*]] = insertvalue [2 x i32] [[AGG0]], i32 [[ARG]], 1
@@ -37,3 +37,17 @@ define i32 @caller(i32 %arg) {
   %v = call i32 @callee([2 x i32] %agg1)
   ret i32 %v
 }
+
+define i32 @caller_not_simplified(i32 %arg) {
+; CHECK-LABEL: define i32 @caller_not_simplified(
+; CHECK-SAME: i32 [[ARG:%.*]]) {
+; CHECK-NEXT:    [[AGG0:%.*]] = insertvalue [2 x i32] poison, i32 1, 0
+; CHECK-NEXT:    [[AGG1:%.*]] = insertvalue [2 x i32] [[AGG0]], i32 [[ARG]], 1
+; CHECK-NEXT:    [[V:%.*]] = call i32 @callee([2 x i32] [[AGG1]])
+; CHECK-NEXT:    ret i32 [[V]]
+;
+  %agg0 = insertvalue [2 x i32] poison, i32 1, 0
+  %agg1 = insertvalue [2 x i32] %agg0, i32 %arg, 1
+  %v = call i32 @callee([2 x i32] %agg1)
+  ret i32 %v
+}



More information about the llvm-commits mailing list