[llvm] [InstCombine] Improve select equiv fold for plain condition (PR #83405)

via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 20 05:14:51 PDT 2024


================
@@ -500,6 +500,51 @@ static bool isSelect01(const APInt &C1I, const APInt &C2I) {
   return C1I.isOne() || C1I.isAllOnes() || C2I.isOne() || C2I.isAllOnes();
 }
 
+/// Try to simplify seletion chain with partially identical conditions, eg:
+///   %s1 = select i1 %c1, i32 23, i32 45
+///   %s2 = select i1 %c2, i32 666, i32 %s1
+///   %s3 = select i1 %c1, i32 789, i32 %s2
+/// -->
+///   %s2 = select i1 %c2, i32 666, i32 45
+///   %s3 = select i1 %c1, i32 789, i32 %s2
+static bool simplifySeqSelectWithSameCond(SelectInst &SI,
+                                          const SimplifyQuery &SQ,
+                                          InstCombinerImpl &IC) {
+  Value *CondVal = SI.getCondition();
+  auto trySimplifySeqSelect = [=, &SI, &IC](unsigned OpIndex) {
+    assert((OpIndex == 1 || OpIndex == 2) && "Unexpected operand index");
+    SelectInst *SINext = &SI;
+    Type *SelType = SINext->getType();
+    Value *ValOp = SINext->getOperand(OpIndex);
+    Value *CondNext;
+    // Don't need propagate FMF flag because we update the operand of SINext
+    // directly.
+    // It is not profitable to build a new select for SINext with multi-arms.
+    while (match(ValOp, m_Select(m_Value(CondNext), m_Value(), m_Value()))) {
+      if (CondNext == CondVal && SINext->hasOneUse()) {
----------------
vfdff wrote:

For the following case, it can be optimized because **%sel1** is a sinle use node.
If we adjust according above change, then it will not optimize because the operand of **%sel1** (%sel0)is multi used.
```
define i8 @sequence_select_with_same_cond_multi_arms_src(i1 %cond0, i1 %cond1, i8 %a, i8 %b) {
  %sel0 = select i1 %cond0, i8 %a, i8 %b
  %sel1 = select i1 %cond1, i8 %sel0, i8 2; %sel1 used in single node
  %sel2 = select i1 %cond1, i8 %sel0, i8 3
  %sel3 = select i1 %cond0, i8 %sel1, i8 %sel2
  ret i8 %sel3
}

define i8 @sequence_select_with_same_cond_multi_arms_tgt(i1 %cond0, i1 %cond1, i8 %a, i8 %b) {
  %sel0 = select i1 %cond0, i8 %a, i8 %b
  %sel1 = select i1 %cond1, i8 %a, i8 2; %sel1 used in single node
  %sel2 = select i1 %cond1, i8 %sel0, i8 3
  %sel3 = select i1 %cond0, i8 %sel1, i8 %sel2
  ret i8 %sel3
}
```

https://github.com/llvm/llvm-project/pull/83405


More information about the llvm-commits mailing list