[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