[llvm] [SDAG] Reverse the canonicalization of isInf/isNanOrInf (PR #81404)

Andy Kaylor via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 12 10:58:29 PST 2024


================
@@ -3467,12 +3467,50 @@ void SelectionDAGBuilder::visitICmp(const User &I) {
   setValue(&I, DAG.getSetCC(getCurSDLoc(), DestVT, Op1, Op2, Opcode));
 }
 
+SDValue SelectionDAGBuilder::lowerIsFpClass(Value *ClassVal,
+                                            FPClassTest ClassTest) {
+  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+  const DataLayout &DL = DAG.getDataLayout();
+  SDLoc sdl = getCurSDLoc();
+
+  EVT DestVT =
+      TLI.getValueType(DL, CmpInst::makeCmpResultType(ClassVal->getType()));
+  EVT ArgVT = TLI.getValueType(DL, ClassVal->getType());
+  MachineFunction &MF = DAG.getMachineFunction();
+  const Function &F = MF.getFunction();
+  SDValue Op = getValue(ClassVal);
+  SDNodeFlags Flags;
+  Flags.setNoFPExcept(!F.getAttributes().hasFnAttr(llvm::Attribute::StrictFP));
+  // If ISD::IS_FPCLASS should be expanded, do it right now, because the
+  // expansion can use illegal types. Making expansion early allows
+  // legalizing these types prior to selection.
+  if (!TLI.isOperationLegalOrCustom(ISD::IS_FPCLASS, ArgVT))
+    return TLI.expandIS_FPCLASS(DestVT, Op, ClassTest, Flags, sdl, DAG);
+
+  SDValue Check = DAG.getTargetConstant(ClassTest, sdl, MVT::i32);
+  return DAG.getNode(ISD::IS_FPCLASS, sdl, DestVT, {Op, Check}, Flags);
+}
+
 void SelectionDAGBuilder::visitFCmp(const User &I) {
   FCmpInst::Predicate predicate = FCmpInst::BAD_FCMP_PREDICATE;
-  if (const FCmpInst *FC = dyn_cast<FCmpInst>(&I))
+  if (const FCmpInst *FC = dyn_cast<FCmpInst>(&I)) {
     predicate = FC->getPredicate();
-  else if (const ConstantExpr *FC = dyn_cast<ConstantExpr>(&I))
+
+    // Reverse the canonicalization if it is a FP class test
+    auto ShouldReverseTransform = [](FPClassTest ClassTest) {
+      return ClassTest == fcInf || ClassTest == (fcInf | fcNan);
+    };
+    auto [ClassVal, ClassTest] =
+        fcmpToClassTest(predicate, *FC->getParent()->getParent(),
+                        FC->getOperand(0), FC->getOperand(1));
+    if (ClassVal && (ShouldReverseTransform(ClassTest) ||
+                     ShouldReverseTransform(~ClassTest))) {
+      setValue(&I, lowerIsFpClass(ClassVal, ClassTest));
+      return;
+    }
+  } else if (const ConstantExpr *FC = dyn_cast<ConstantExpr>(&I))
     predicate = FCmpInst::Predicate(FC->getPredicate());
+
----------------
andykaylor wrote:

```suggestion
  }
```

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


More information about the llvm-commits mailing list