[llvm] [InstCombine] Fold "extract (select (cond, insert(agg, elem), FV))" (PR #115969)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 13 15:33:57 PST 2024
https://github.com/weiguozhi updated https://github.com/llvm/llvm-project/pull/115969
>From a9999a7696b90b7468197f309f796354ce7fa4d5 Mon Sep 17 00:00:00 2001
From: Guozhi Wei <carrot at google.com>
Date: Tue, 12 Nov 2024 16:39:22 -0800
Subject: [PATCH 1/2] [InstCombine] Fold "extract (select (cond, insert(agg,
elem), FV))"
Do the transform
extract (select (cond, insert(agg, elem), FV))
-> select (cond, elem, extract(FV))
---
.../InstCombine/InstructionCombining.cpp | 20 +++++++++++-
.../InstCombine/extract-select-agg.ll | 31 ++++++++++++++-----
2 files changed, 43 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 2a54390c0f1882..5914a7aa422e11 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1692,7 +1692,25 @@ Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op, SelectInst *SI,
Value *TV = SI->getTrueValue();
Value *FV = SI->getFalseValue();
- if (!(isa<Constant>(TV) || isa<Constant>(FV)))
+ if ((Op.getOpcode() == Instruction::ExtractValue) &&
+ (isa<InsertValueInst>(TV) || isa<InsertValueInst>(FV))) {
+ // extract (select (cond, insert(agg, elem), FV))
+ // -> select (cond, elem, extract(FV))
+ ExtractValueInst *EV = dyn_cast<ExtractValueInst>(&Op);
+ Value *NewTV = simplifyExtractValueInst(TV, EV->getIndices(),
+ SQ.getWithInstruction(&Op));
+ Value *NewFV = simplifyExtractValueInst(FV, EV->getIndices(),
+ SQ.getWithInstruction(&Op));
+ if (!NewTV && !NewFV)
+ return nullptr;
+ Builder.SetInsertPoint(SI);
+ if (!NewTV)
+ NewTV = Builder.CreateExtractValue(TV, EV->getIndices());
+ if (!NewFV)
+ NewFV = Builder.CreateExtractValue(FV, EV->getIndices());
+ return SelectInst::Create(SI->getCondition(), NewTV, NewFV, "", nullptr,
+ SI);
+ } else if (!(isa<Constant>(TV) || isa<Constant>(FV)))
return nullptr;
// Bool selects with constant operands can be folded to logical ops.
diff --git a/llvm/test/Transforms/InstCombine/extract-select-agg.ll b/llvm/test/Transforms/InstCombine/extract-select-agg.ll
index 6ba6b1a575601d..2813870feeb931 100644
--- a/llvm/test/Transforms/InstCombine/extract-select-agg.ll
+++ b/llvm/test/Transforms/InstCombine/extract-select-agg.ll
@@ -56,14 +56,9 @@ define void @test_select_agg_multiuse(i1 %cond, i64 %v1, i64 %v2, i64 %v3, i64 %
; CHECK-LABEL: define void @test_select_agg_multiuse(
; CHECK-SAME: i1 [[COND:%.*]], i64 [[V1:%.*]], i64 [[V2:%.*]], i64 [[V3:%.*]], i64 [[V4:%.*]]) {
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A0:%.*]] = insertvalue { i64, i64 } poison, i64 [[V1]], 0
-; CHECK-NEXT: [[A1:%.*]] = insertvalue { i64, i64 } [[A0]], i64 [[V2]], 1
-; CHECK-NEXT: [[B0:%.*]] = insertvalue { i64, i64 } poison, i64 [[V3]], 0
-; CHECK-NEXT: [[B1:%.*]] = insertvalue { i64, i64 } [[B0]], i64 [[V4]], 1
-; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], { i64, i64 } [[A1]], { i64, i64 } [[B1]]
-; CHECK-NEXT: [[X:%.*]] = extractvalue { i64, i64 } [[SEL]], 0
+; CHECK-NEXT: [[X:%.*]] = select i1 [[COND]], i64 [[V1]], i64 [[V3]]
; CHECK-NEXT: call void @use(i64 [[X]])
-; CHECK-NEXT: [[Y:%.*]] = extractvalue { i64, i64 } [[SEL]], 1
+; CHECK-NEXT: [[Y:%.*]] = select i1 [[COND]], i64 [[V2]], i64 [[V4]]
; CHECK-NEXT: call void @use(i64 [[Y]])
; CHECK-NEXT: ret void
;
@@ -81,3 +76,25 @@ entry:
}
declare void @use(i64)
+
+define i64 @test_extract_select_insert(ptr %p1, i64 %v) {
+; CHECK-LABEL: define i64 @test_extract_select_insert(
+; CHECK-SAME: ptr [[P1:%.*]], i64 [[V:%.*]]) {
+; CHECK-NEXT: [[CALL:%.*]] = call { ptr, i64 } @foo()
+; CHECK-NEXT: [[ELM1:%.*]] = extractvalue { ptr, i64 } [[CALL]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[ELM1]], [[V]]
+; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i64 } [[CALL]], 1
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i64 4294967294, i64 [[TMP1]]
+; CHECK-NEXT: ret i64 [[RES]]
+;
+ %call = call { ptr, i64 } @foo()
+ %elm1 = extractvalue { ptr, i64 } %call, 1
+ %cmp = icmp eq i64 %elm1, %v
+ %fca0 = insertvalue { ptr, i64 } poison, ptr %p1, 0
+ %fca1 = insertvalue { ptr, i64 } %fca0, i64 4294967294, 1
+ %select = select i1 %cmp, { ptr, i64 } %fca1, { ptr, i64 } %call
+ %res = extractvalue { ptr, i64 } %select, 1
+ ret i64 %res
+}
+
+declare { ptr, i64 } @foo()
>From f44cade3d723ab109f04bcbc71f0e0160c04d4f6 Mon Sep 17 00:00:00 2001
From: Guozhi Wei <carrot at google.com>
Date: Wed, 13 Nov 2024 15:33:23 -0800
Subject: [PATCH 2/2] Add new test cases.
---
.../InstCombine/InstructionCombining.cpp | 2 +-
.../InstCombine/extract-select-agg.ll | 46 ++++++++++++++++++-
2 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 5914a7aa422e11..66c034b1ad9e62 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1692,7 +1692,7 @@ Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op, SelectInst *SI,
Value *TV = SI->getTrueValue();
Value *FV = SI->getFalseValue();
- if ((Op.getOpcode() == Instruction::ExtractValue) &&
+ if (Op.getOpcode() == Instruction::ExtractValue &&
(isa<InsertValueInst>(TV) || isa<InsertValueInst>(FV))) {
// extract (select (cond, insert(agg, elem), FV))
// -> select (cond, elem, extract(FV))
diff --git a/llvm/test/Transforms/InstCombine/extract-select-agg.ll b/llvm/test/Transforms/InstCombine/extract-select-agg.ll
index 2813870feeb931..3a3da6f6380e66 100644
--- a/llvm/test/Transforms/InstCombine/extract-select-agg.ll
+++ b/llvm/test/Transforms/InstCombine/extract-select-agg.ll
@@ -77,8 +77,8 @@ entry:
declare void @use(i64)
-define i64 @test_extract_select_insert(ptr %p1, i64 %v) {
-; CHECK-LABEL: define i64 @test_extract_select_insert(
+define i64 @test_extract_select_insert_left(ptr %p1, i64 %v) {
+; CHECK-LABEL: define i64 @test_extract_select_insert_left(
; CHECK-SAME: ptr [[P1:%.*]], i64 [[V:%.*]]) {
; CHECK-NEXT: [[CALL:%.*]] = call { ptr, i64 } @foo()
; CHECK-NEXT: [[ELM1:%.*]] = extractvalue { ptr, i64 } [[CALL]], 1
@@ -97,4 +97,46 @@ define i64 @test_extract_select_insert(ptr %p1, i64 %v) {
ret i64 %res
}
+define i64 @test_extract_select_insert_right(ptr %p1, i64 %v) {
+; CHECK-LABEL: define i64 @test_extract_select_insert_right(
+; CHECK-SAME: ptr [[P1:%.*]], i64 [[V:%.*]]) {
+; CHECK-NEXT: [[CALL:%.*]] = call { ptr, i64 } @foo()
+; CHECK-NEXT: [[ELM1:%.*]] = extractvalue { ptr, i64 } [[CALL]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[ELM1]], [[V]]
+; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i64 } [[CALL]], 1
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i64 [[TMP1]], i64 4294967294
+; CHECK-NEXT: ret i64 [[RES]]
+;
+ %call = call { ptr, i64 } @foo()
+ %elm1 = extractvalue { ptr, i64 } %call, 1
+ %cmp = icmp eq i64 %elm1, %v
+ %fca0 = insertvalue { ptr, i64 } poison, ptr %p1, 0
+ %fca1 = insertvalue { ptr, i64 } %fca0, i64 4294967294, 1
+ %select = select i1 %cmp, { ptr, i64 } %call, { ptr, i64 } %fca1
+ %res = extractvalue { ptr, i64 } %select, 1
+ ret i64 %res
+}
+
+define i64 @test_extract_select_insert_negative(ptr %p1, i64 %v) {
+; CHECK-LABEL: define i64 @test_extract_select_insert_negative(
+; CHECK-SAME: ptr [[P1:%.*]], i64 [[V:%.*]]) {
+; CHECK-NEXT: [[CALL:%.*]] = call { ptr, i64 } @foo()
+; CHECK-NEXT: [[CALL2:%.*]] = call { ptr, i64 } @foo()
+; CHECK-NEXT: [[ELM1:%.*]] = extractvalue { ptr, i64 } [[CALL]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[ELM1]], [[V]]
+; CHECK-NEXT: [[FCA1:%.*]] = insertvalue { ptr, i64 } [[CALL2]], ptr [[P1]], 0
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], { ptr, i64 } [[CALL]], { ptr, i64 } [[FCA1]]
+; CHECK-NEXT: [[RES:%.*]] = extractvalue { ptr, i64 } [[SELECT]], 1
+; CHECK-NEXT: ret i64 [[RES]]
+;
+ %call = call { ptr, i64 } @foo()
+ %call2 = call { ptr, i64 } @foo()
+ %elm1 = extractvalue { ptr, i64 } %call, 1
+ %cmp = icmp eq i64 %elm1, %v
+ %fca1 = insertvalue { ptr, i64 } %call2, ptr %p1, 0
+ %select = select i1 %cmp, { ptr, i64 } %call, { ptr, i64 } %fca1
+ %res = extractvalue { ptr, i64 } %select, 1
+ ret i64 %res
+}
+
declare { ptr, i64 } @foo()
More information about the llvm-commits
mailing list