diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -231,6 +231,11 @@ TargetLoweringBase &operator=(const TargetLoweringBase &) = delete; virtual ~TargetLoweringBase() = default; + /// Return true if the target support strict float operation + bool isStrictFPEnabled() const { + return IsStrictFPEnabled; + } + protected: /// Initialize all of the actions to default values. void initActions(); @@ -2909,6 +2914,8 @@ /// details. MachineBasicBlock *emitXRayTypedEvent(MachineInstr &MI, MachineBasicBlock *MBB) const; + + bool IsStrictFPEnabled; }; /// This class defines information used to lower LLVM code to legal SelectionDAG diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -2805,12 +2805,18 @@ break; } case ISD::STRICT_FP_ROUND: - // This expansion does not honor the "strict" properties anyway, - // so prefer falling back to the non-strict operation if legal. + // When strict mode is enforced we can't do expansion because it + // does not honor the "strict" properties. Only libcall is allowed. + if (TLI.isStrictFPEnabled()) + break; + // We might as well mutate to FP_ROUND when FP_ROUND operation is legal + // since this operation is more efficient than stack operation. if (TLI.getStrictFPOperationAction(Node->getOpcode(), Node->getValueType(0)) == TargetLowering::Legal) break; + // We fall back to use stack operation when the FP_ROUND operation + // isn't available. Tmp1 = EmitStackConvert(Node->getOperand(1), Node->getValueType(0), Node->getValueType(0), dl, Node->getOperand(0)); @@ -2825,12 +2831,18 @@ Results.push_back(Tmp1); break; case ISD::STRICT_FP_EXTEND: - // This expansion does not honor the "strict" properties anyway, - // so prefer falling back to the non-strict operation if legal. + // When strict mode is enforced we can't do expansion because it + // does not honor the "strict" properties. Only libcall is allowed. + if (TLI.isStrictFPEnabled()) + break; + // We might as well mutate to FP_EXTEND when FP_EXTEND operation is legal + // since this operation is more efficient than stack operation. if (TLI.getStrictFPOperationAction(Node->getOpcode(), Node->getValueType(0)) == TargetLowering::Legal) break; + // We fall back to use stack operation when the FP_EXTEND operation + // isn't available. Tmp1 = EmitStackConvert(Node->getOperand(1), Node->getOperand(1).getValueType(), Node->getValueType(0), dl, Node->getOperand(0)); @@ -3701,7 +3713,7 @@ break; } - if (Results.empty() && Node->isStrictFPOpcode()) { + if (!TLI.isStrictFPEnabled() && Results.empty() && Node->isStrictFPOpcode()) { // FIXME: We were asked to expand a strict floating-point operation, // but there is currently no expansion implemented that would preserve // the "strict" properties. For now, we just fall back to the non-strict diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp @@ -319,9 +319,9 @@ // best approach, except in the case where the resulting strict (scalar) // operations would themselves use the fallback mutation to non-strict. // In that specific case, just do the fallback on the vector op. - if (Action == TargetLowering::Expand && + if (Action == TargetLowering::Expand && !TLI.isStrictFPEnabled() && TLI.getStrictFPOperationAction(Node->getOpcode(), - Node->getValueType(0)) + Node->getValueType(0)) == TargetLowering::Legal) { EVT EltVT = Node->getValueType(0).getVectorElementType(); if (TLI.getOperationAction(Node->getOpcode(), EltVT) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1156,7 +1156,7 @@ // we convert them to normal FP opcodes instead at this point. This // will allow them to be handled by existing target-specific instruction // selectors. - if (Node->isStrictFPOpcode() && + if (!TLI->isStrictFPEnabled() && Node->isStrictFPOpcode() && (TLI->getOperationAction(Node->getOpcode(), Node->getValueType(0)) == TargetLowering::Expand)) Node = CurDAG->mutateStrictFPToFP(Node); diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -88,6 +88,14 @@ cl::desc("Minimum density for building a jump table in " "an optsize function")); +// FIXME: This option is only to test if the strict fp operation processed +// correctly by preventing mutating strict fp operation to normal fp operation +// during development. When the backend supports strict float operation, this +// option will be meaningless. +static cl::opt DisableStrictNodeMutation("disable-strictnode-mutation", + cl::desc("Don't mutate strict-float node to a legalize node"), + cl::init(false), cl::Hidden); + static bool darwinHasSinCos(const Triple &TT) { assert(TT.isOSDarwin() && "should be called with darwin triple"); // Don't bother with 32 bit x86. @@ -585,6 +593,7 @@ BooleanVectorContents = UndefinedBooleanContent; SchedPreferenceInfo = Sched::ILP; GatherAllAliasesMaxDepth = 18; + IsStrictFPEnabled = DisableStrictNodeMutation; // TODO: the default will be switched to 0 in the next commit, along // with the Target-specific changes necessary. MaxAtomicSizeInBitsSupported = 1024; diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -634,6 +634,9 @@ // than "STC;MVC". Handle the choice in target-specific code instead. MaxStoresPerMemset = 0; MaxStoresPerMemsetOptSize = 0; + + // Default to having -disable-strictnode-mutation on + IsStrictFPEnabled = true; } EVT SystemZTargetLowering::getSetCCResultType(const DataLayout &DL,