[llvm] [INSTR COMBINE] implement combine select into cast (PR #114612)

via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 1 15:06:28 PDT 2024


https://github.com/Cr0a3 created https://github.com/llvm/llvm-project/pull/114612

Hi,
I implemented the instruction combination of this:
````
define noundef float @ifelse(i1 noundef zeroext %x) unnamed_addr {
start:
  %. = select i1 %x, float 1.000000e+00, float 0.000000e+00
  ret float %.
}
````
into this:
```

define noundef float @ifelse(i1 noundef zeroext %x) unnamed_addr {
start:
  %.= uitofp i1 %x to float
  ret float %.
}
```

Fixes #107034

@weliveindetail 


>From 2f2b61b826515e7cc59cb4aa936d3f3402ff1d66 Mon Sep 17 00:00:00 2001
From: Cr0a3 <buch.toni at outlook.com>
Date: Fri, 1 Nov 2024 23:00:18 +0100
Subject: [PATCH] [INSTR COMBINE] implementing instr combine of select into
 cast (fixes #107034)

---
 .../InstCombine/InstCombineSelect.cpp         | 35 +++++++++++++++++++
 .../2024-11-07-FoldSelectIntoCast.ll          |  8 +++++
 2 files changed, 43 insertions(+)
 create mode 100644 llvm/test/Transforms/InstCombine/2024-11-07-FoldSelectIntoCast.ll

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 999ad1adff20b8..2758de88c899f6 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -3645,12 +3645,47 @@ static bool hasAffectedValue(Value *V, SmallPtrSetImpl<Value *> &Affected,
   return false;
 }
 
+// Checks for following pattern:
+// ```
+// %any1 = select i1 %any0, float 1.000000e+00, float 0.000000e+00
+// ```
+// which then gets folded into:
+// ```
+// %any1 = uitofp i1 %any0 to float
+// ```
+// (also works with double)
+static std::optional<Instruction*> mabyeFoldIntoCast(Value* CondVal, ConstantFP *TrueVal, ConstantFP *FalseVal, Type *SelType, llvm::StringRef out) {
+  if (TrueVal->getValueAPF().convertToDouble() != 1.0) {
+    return std::optional<Instruction*>();
+  }
+
+  if (FalseVal->getValueAPF().convertToDouble() != 0.0) {
+    return std::optional<Instruction*>();
+  }
+
+  return CastInst::Create(llvm::Instruction::UIToFP, CondVal, SelType, out);
+}
+
+
 Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
   Value *CondVal = SI.getCondition();
   Value *TrueVal = SI.getTrueValue();
   Value *FalseVal = SI.getFalseValue();
   Type *SelType = SI.getType();
 
+  
+  if (ConstantFP *True = dyn_cast<ConstantFP>(TrueVal)) {
+    if (ConstantFP *False = dyn_cast<ConstantFP>(FalseVal)) {
+      if (SelType->isFloatTy() || SelType->isDoubleTy()) {
+        std::optional<Instruction*> folded = mabyeFoldIntoCast(CondVal, True, False, SelType, SI.getName());
+
+        if (folded.has_value()) {
+          return folded.value();
+        }
+      }
+    }
+  }
+
   if (Value *V = simplifySelectInst(CondVal, TrueVal, FalseVal,
                                     SQ.getWithInstruction(&SI)))
     return replaceInstUsesWith(SI, V);
diff --git a/llvm/test/Transforms/InstCombine/2024-11-07-FoldSelectIntoCast.ll b/llvm/test/Transforms/InstCombine/2024-11-07-FoldSelectIntoCast.ll
new file mode 100644
index 00000000000000..98af70d0188629
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/2024-11-07-FoldSelectIntoCast.ll
@@ -0,0 +1,8 @@
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+define noundef float @ifelse(i1 noundef zeroext %x) unnamed_addr {
+start:
+; CHECK: %.= uitofp i1 %x to float
+  %. = select i1 %x, float 1.000000e+00, float 0.000000e+00
+  ret float %.
+}
\ No newline at end of file



More information about the llvm-commits mailing list