[llvm] [DAG] Fixing the non-optimal code with the following: `select i1 %0, float 1.0, float 0.0`. (PR #107732)

via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 7 18:55:26 PDT 2024


https://github.com/c8ef created https://github.com/llvm/llvm-project/pull/107732

Fixes #107034.

>From 486ea64b373226f8e5ce31c18209f6dd88c77d6f Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Sun, 8 Sep 2024 09:52:37 +0800
Subject: [PATCH] fold

---
 llvm/lib/Target/X86/X86ISelLowering.cpp    | 25 ++++++++++++++++++++++
 llvm/test/CodeGen/X86/fp-select-cmp-and.ll | 19 ++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 839b87dd5d4dd8..e40e28bacd4f66 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -45844,6 +45844,28 @@ static SDValue combineSelectOfTwoConstants(SDNode *N, SelectionDAG &DAG,
   return SDValue();
 }
 
+static SDValue combineSelectOfTwoFPConstants(SDNode *N, SelectionDAG &DAG,
+                                             const SDLoc &DL) {
+  SDValue Cond = N->getOperand(0);
+  SDValue LHS = N->getOperand(1);
+  SDValue RHS = N->getOperand(2);
+  EVT VT = N->getValueType(0);
+
+  auto *TrueC = dyn_cast<ConstantFPSDNode>(LHS);
+  auto *FalseC = dyn_cast<ConstantFPSDNode>(RHS);
+  if (!TrueC || !FalseC)
+    return SDValue();
+
+  const APFloat &TrueVal = TrueC->getValueAPF();
+  const APFloat &FalseVal = FalseC->getValueAPF();
+
+  if (TrueVal == APFloat::getOne(TrueVal.getSemantics()) && FalseVal.isZero()) {
+    return DAG.getNode(ISD::UINT_TO_FP, DL, VT, Cond);
+  }
+
+  return SDValue();
+}
+
 /// If this is a *dynamic* select (non-constant condition) and we can match
 /// this node with one of the variable blend instructions, restructure the
 /// condition so that blends can use the high (sign) bit of each element.
@@ -46336,6 +46358,9 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
   if (SDValue V = combineSelectOfTwoConstants(N, DAG, DL))
     return V;
 
+  if (SDValue V = combineSelectOfTwoFPConstants(N, DAG, DL))
+    return V;
+
   if (N->getOpcode() == ISD::SELECT && Cond.getOpcode() == ISD::SETCC &&
       Cond.hasOneUse()) {
     EVT CondVT = Cond.getValueType();
diff --git a/llvm/test/CodeGen/X86/fp-select-cmp-and.ll b/llvm/test/CodeGen/X86/fp-select-cmp-and.ll
index 0f6159d36ea818..64e6c410742754 100644
--- a/llvm/test/CodeGen/X86/fp-select-cmp-and.ll
+++ b/llvm/test/CodeGen/X86/fp-select-cmp-and.ll
@@ -213,3 +213,22 @@ define double @test18(double %a, double %b, double %c, double %eps) {
   ret double %cond
 }
 
+define float @test19(i1 %cmp) {
+; CHECK-LABEL: test19:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    andl $1, %edi
+; CHECK-NEXT:    cvtsi2ss %edi, %xmm0
+; CHECK-NEXT:    retq
+  %cond = select i1 %cmp, float 1.000000e+00, float 0.000000e+00
+  ret float %cond
+}
+
+define double @test20(i1 %cmp) {
+; CHECK-LABEL: test20:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    andl $1, %edi
+; CHECK-NEXT:    cvtsi2sd %edi, %xmm0
+; CHECK-NEXT:    retq
+  %cond = select i1 %cmp, double 1.000000e+00, double 0.000000e+00
+  ret double %cond
+}



More information about the llvm-commits mailing list