[llvm] [X86] Convert FP compares split by a nested logic op to FP logic (PR #226222)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 28 06:26:09 PDT 2026


================
@@ -52669,6 +52688,73 @@ static SDValue convertIntLogicToFPLogic(unsigned Opc, const SDLoc &DL, EVT VT,
   assert((Opc == ISD::OR || Opc == ISD::AND || Opc == ISD::XOR) &&
          "Unexpected bit opcode");
 
+  using namespace SDPatternMatch;
+  auto IsLegalFPType = [&](EVT FPVT) {
+    return (Subtarget.hasSSE1() && FPVT == MVT::f32) ||
+           (Subtarget.hasSSE2() && FPVT == MVT::f64) ||
+           (Subtarget.hasFP16() && FPVT == MVT::f16);
+  };
+  // Without AVX512VL, the v8f16 compares are not legal.
+  auto IsLegalFPCmpType = [&](EVT FPVT) {
+    return IsLegalFPType(FPVT) && (FPVT != MVT::f16 || Subtarget.hasVLX());
+  };
+
+  // Look through a single-use inner logic op to pair up two FP compares that
+  // it separates, e.g. by an integer compare. The recursive call only sees
+  // SETCC or converted operands, so this is limited to one level:
+  // logic (logic (setcc X), Y), (setcc Z) -->
+  // logic (logic (setcc X), (setcc Z)), Y
+  auto FPCmp = [](SDValue &Cmp) {
+    return m_Value(
+        Cmp,
+        m_AnyOf(m_SetCC(m_FloatingPointVT(), m_Value(), m_Value()),
+                m_ExtractElt(m_BitwiseLogic(m_Value(), m_Value()), m_Zero())));
+  };
+  SDValue X, Y, Z;
+  auto Inner = m_OneUse(m_c_BinOp(Opc, FPCmp(X), m_Value(Y)));
+  if (VT == MVT::i1 && ((sd_match(N0, Inner) && sd_match(N1, FPCmp(Z))) ||
+                        (sd_match(N1, Inner) && sd_match(N0, FPCmp(Z)))))
+    if (SDValue FPLogic =
+            convertIntLogicToFPLogic(Opc, DL, VT, X, Z, DAG, DCI, Subtarget))
+      return DAG.getNode(Opc, DL, VT, FPLogic, Y);
+
+  // Add an FP compare, or another converted sequence, to FP compares that
+  // were already converted to vector logic (see below):
+  // logic (extelt V, 0), (setcc LHS, RHS) -->
+  // extelt (logic V, (setcc (s2v LHS), (s2v RHS))), 0
+  // logic (extelt V, 0), (extelt W, 0) --> extelt (logic V, W), 0
+  auto IsConverted = [](SDValue Op, SDValue &Vec) {
+    return sd_match(Op, m_OneUse(m_ExtractElt(m_Value(Vec), m_Zero()))) &&
+           isConvertedFPLogic(Vec);
+  };
+  SDValue V, W, LHS, RHS;
+  ISD::CondCode CC;
+  if (VT == MVT::i1 && IsConverted(N1, V))
+    std::swap(N0, N1);
+  if (VT == MVT::i1 && IsConverted(N0, V)) {
+    EVT BoolVecVT = V.getValueType();
+    SDValue Vec1;
+    if (IsConverted(N1, W)) {
+      Vec1 = W;
+    } else if (sd_match(N1, m_OneUse(m_SetCC(m_Value(LHS), m_Value(RHS),
+                                             m_CondCode(CC)))) &&
+               IsLegalFPCmpType(LHS.getValueType()) &&
+               (Subtarget.hasAVX() || cheapX86FSETCC_SSE(CC))) {
+      EVT VecVT = EVT::getVectorVT(*DAG.getContext(), LHS.getValueType(),
+                                   BoolVecVT.getVectorNumElements());
+      if (VecVT.getSizeInBits() == 128) {
+        SDValue VecL = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VecVT, LHS);
+        SDValue VecR = DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VecVT, RHS);
+        Vec1 = DAG.getSetCC(DL, BoolVecVT, VecL, VecR, CC);
+      }
+    }
+    if (Vec1 && Vec1.getValueType() == BoolVecVT) {
+      SDValue Logic = DAG.getNode(Opc, DL, BoolVecVT, V, Vec1);
+      return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, Logic,
----------------
RKSimon wrote:

```suggestion
      return DAG.getExtractVectorElt(DL, VT, Logic, 0);
```

https://github.com/llvm/llvm-project/pull/226222


More information about the llvm-commits mailing list