[llvm] [InstCombine] Add fold for select of symmetric selects (PR #98813)
Tim Gymnich via llvm-commits
llvm-commits at lists.llvm.org
Sun Jul 14 06:47:22 PDT 2024
https://github.com/tgymnich updated https://github.com/llvm/llvm-project/pull/98813
>From 12b5833be0c4bad2fee19b6db58b16b4c83faf96 Mon Sep 17 00:00:00 2001
From: Tim Gymnich <tgymnich at icloud.com>
Date: Sun, 14 Jul 2024 15:33:31 +0200
Subject: [PATCH 1/2] [InstCombine] Add fold for select of symmetric selects
---
.../InstCombine/InstCombineSelect.cpp | 33 +++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 394dfca262e13..1bcbc3fdf884f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -3012,6 +3012,36 @@ struct DecomposedSelect {
};
} // namespace
+/// Folds patterns like:
+/// select c2 (select c1 a b) (select c1 b a)
+/// into:
+/// select (xor c1 c2) b a
+static Instruction *
+foldSelectOfSymmetricSelect(SelectInst &OuterSelVal,
+ InstCombiner::BuilderTy &Builder) {
+
+ DecomposedSelect OuterSel, InnerSel1, InnerSel2;
+
+ if (!match(
+ &OuterSelVal,
+ m_Select(m_Value(OuterSel.Cond),
+ m_Select(m_Value(InnerSel1.Cond), m_Value(InnerSel1.TrueVal),
+ m_Value(InnerSel1.FalseVal)),
+ m_Select(m_Value(InnerSel2.Cond), m_Value(InnerSel2.TrueVal),
+ m_Value(InnerSel2.FalseVal)))))
+ return nullptr;
+
+ bool InnerSelsSymmetric = InnerSel1.Cond == InnerSel2.Cond &&
+ InnerSel1.TrueVal == InnerSel2.FalseVal &&
+ InnerSel1.FalseVal == InnerSel2.TrueVal;
+
+ if (!InnerSelsSymmetric)
+ return nullptr;
+
+ Value *Xor = Builder.CreateXor(InnerSel1.Cond, OuterSel.Cond);
+ return SelectInst::Create(Xor, InnerSel1.FalseVal, InnerSel1.TrueVal);
+}
+
/// Look for patterns like
/// %outer.cond = select i1 %inner.cond, i1 %alt.cond, i1 false
/// %inner.sel = select i1 %inner.cond, i8 %inner.sel.t, i8 %inner.sel.f
@@ -3987,6 +4017,9 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
}
}
+ if (Instruction *I = foldSelectOfSymmetricSelect(SI, Builder))
+ return I;
+
if (Instruction *I = foldNestedSelects(SI, Builder))
return I;
>From 03b54bc3f239d85ac25c5854373c7fe7bae4dcdb Mon Sep 17 00:00:00 2001
From: Tim Gymnich <tgymnich at icloud.com>
Date: Sun, 14 Jul 2024 15:47:11 +0200
Subject: [PATCH 2/2] add test
---
.../InstCombine/select-of-sym-selects.ll | 14 ++++++++++++++
1 file changed, 14 insertions(+)
create mode 100644 llvm/test/Transforms/InstCombine/select-of-sym-selects.ll
diff --git a/llvm/test/Transforms/InstCombine/select-of-sym-selects.ll b/llvm/test/Transforms/InstCombine/select-of-sym-selects.ll
new file mode 100644
index 0000000000000..afac5c0164aff
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/select-of-sym-selects.ll
@@ -0,0 +1,14 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+define i32 @src(i32 %a, i32 %b, i1 %c1, i1 %c2) {
+; CHECK-LABEL: @src(
+; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[C1:%.*]], [[C2:%.*]]
+; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP1]], i32 [[B:%.*]], i32 [[A:%.*]]
+; CHECK-NEXT: ret i32 [[RET]]
+;
+ %sel1 = select i1 %c1, i32 %a, i32 %b
+ %sel2 = select i1 %c1, i32 %b, i32 %a
+ %ret = select i1 %c2, i32 %sel1, i32 %sel2
+ ret i32 %ret
+}
More information about the llvm-commits
mailing list