@@ -316,21 +316,26 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode *N) {
316316SDValue DAGTypeLegalizer::SoftenFloatRes_FCANONICALIZE (SDNode *N) {
317317 SDLoc dl (N);
318318
319- // Create a constant 1.0, then soften it to integer and record the mapping.
320- SDValue CstFP = DAG.getConstantFP (1.0 , dl, N->getValueType (0 ));
321- SDValue CstInt = SoftenFloatRes_ConstantFP (CstFP.getNode ());
322-
323- if (!SoftenedFloats[getTableId (CstFP)])
324- SetSoftenedFloat (CstFP, CstInt);
325-
326- // Multiply the input by 1.0 to canonicalize it. We use `MorphNodeTo` to
327- // avoid constant folding, which happens with `DAG.getNode(ISD::FMUL, ...)`.
328- SDNode *Node =
329- DAG.MorphNodeTo (N, ISD::FMUL, DAG.getVTList (N->getValueType (0 )),
330- {N->getOperand (0 ), CstFP});
331- return SoftenFloatRes_Binary (
332- Node, GetFPLibCall (N->getValueType (0 ), RTLIB::MUL_F32, RTLIB::MUL_F64,
333- RTLIB::MUL_F80, RTLIB::MUL_F128, RTLIB::MUL_PPCF128));
319+ // This implements llvm.canonicalize.f* by multiplication with 1.0, as
320+ // suggested in
321+ // https://llvm.org/docs/LangRef.html#llvm-canonicalize-intrinsic.
322+ // It uses strict_fp operations even outside a strict_fp context in order
323+ // to guarantee that the canonicalization is not optimized away by later
324+ // passes. The result chain introduced by that is intentionally ignored
325+ // since no ordering requirement is intended here.
326+
327+ // Create strict multiplication by 1.0.
328+ SDValue Operand = N->getOperand (0 );
329+ EVT VT = Operand.getValueType ();
330+ SDValue One = DAG.getConstantFP (1.0 , dl, VT);
331+ SDValue Chain = DAG.getEntryNode ();
332+ // Propagate existing flags on canonicalize, and additionally set
333+ // NoFPExcept.
334+ SDNodeFlags CanonicalizeFlags = N->getFlags ();
335+ CanonicalizeFlags.setNoFPExcept (true );
336+ SDValue Mul = DAG.getNode (ISD::STRICT_FMUL, dl, {VT, MVT::Other},
337+ {Chain, Operand, One}, CanonicalizeFlags);
338+ return BitConvertToInteger (Mul);
334339}
335340
336341SDValue DAGTypeLegalizer::SoftenFloatRes_FMINNUM (SDNode *N) {
0 commit comments