[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