[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