[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
Mon Sep 9 01:45:24 PDT 2024


================
@@ -24150,6 +24150,13 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
                                           DAG.getBitcast(NVT, Op2)));
   }
 
+  // (select cc, 1.0, 0.0) -> (sint_to_fp (zext cc))
+  const ConstantFPSDNode *FPTV = dyn_cast<ConstantFPSDNode>(Op1);
+  const ConstantFPSDNode *FPFV = dyn_cast<ConstantFPSDNode>(Op2);
+  if (FPTV && FPFV && FPTV->isExactlyValue(1.0) && FPFV->isExactlyValue(0.0)) {
----------------
c8ef wrote:

Yes, that's exactly what I did initially. However, we have another combine in X86 (see below), which causes us to repeatedly convert between select and uitofp, leading to an infinite loop.

https://github.com/llvm/llvm-project/blob/caebb4562ce634a22f7b13480b19cffc2a6a6730/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp#L17953-L17959

It seems that when applying this patch, we are switching back and forth between `select` and `uint_to_fp`.

```
  // fold (uint_to_fp (setcc x, y, cc)) -> (select (setcc x, y, cc), 1.0, 0.0)
  if (N0.getOpcode() == ISD::SETCC && !VT.isVector() &&
      (!LegalOperations || TLI.isOperationLegalOrCustom(ISD::ConstantFP, VT))) {
    SDLoc DL(N);
    return DAG.getSelect(DL, VT, N0, DAG.getConstantFP(1.0, DL, VT),
                         DAG.getConstantFP(0.0, DL, VT));
  }
```

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


More information about the llvm-commits mailing list