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

via llvm-commits llvm-commits at lists.llvm.org
Sat Nov 2 00:39:35 PDT 2024


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

>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 1/2] [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

>From ae39fbbda9ca5d2c3766ea543d3192ffef65b1db Mon Sep 17 00:00:00 2001
From: Cr0a3 <buch.toni at outlook.com>
Date: Sat, 2 Nov 2024 08:38:47 +0100
Subject: [PATCH 2/2] [FMT] running git clang format

---
 .../Transforms/InstCombine/InstCombineSelect.cpp    | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 2758de88c899f6..4e86f30100dc68 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -3654,30 +3654,31 @@ static bool hasAffectedValue(Value *V, SmallPtrSetImpl<Value *> &Affected,
 // %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) {
+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*>();
+    return std::optional<Instruction *>();
   }
 
   if (FalseVal->getValueAPF().convertToDouble() != 0.0) {
-    return std::optional<Instruction*>();
+    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());
+        std::optional<Instruction *> folded =
+            mabyeFoldIntoCast(CondVal, True, False, SelType, SI.getName());
 
         if (folded.has_value()) {
           return folded.value();



More information about the llvm-commits mailing list