Skip to content

Commit acdf1c7

Browse files
[DAG] Add generic expansion for ISD::FCANONICALIZE nodes (#142105)
This PR takes the work previously done by @pawan-nirpal-031 on X86 in #106370, and makes it available in common code. This should enable all targets to use `__builtin_canonicalize` for all `f(16|32|64|128)` data types. Canonicalization is implemented here as multiplication by `1.0`, as suggested in [the docs](https://llvm.org/docs/LangRef.html#llvm-canonicalize-intrinsic).
1 parent 67076dd commit acdf1c7

File tree

8 files changed

+452
-0
lines changed

8 files changed

+452
-0
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3356,6 +3356,32 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
33563356
Results.push_back(Op);
33573357
break;
33583358
}
3359+
case ISD::FCANONICALIZE: {
3360+
// This implements llvm.canonicalize.f* by multiplication with 1.0, as
3361+
// suggested in
3362+
// https://llvm.org/docs/LangRef.html#llvm-canonicalize-intrinsic.
3363+
// It uses strict_fp operations even outside a strict_fp context in order
3364+
// to guarantee that the canonicalization is not optimized away by later
3365+
// passes. The result chain introduced by that is intentionally ignored
3366+
// since no ordering requirement is intended here.
3367+
3368+
// Create strict multiplication by 1.0.
3369+
SDValue Operand = Node->getOperand(0);
3370+
EVT VT = Operand.getValueType();
3371+
SDValue One = DAG.getConstantFP(1.0, dl, VT);
3372+
SDValue Chain = DAG.getEntryNode();
3373+
SDValue Mul = DAG.getNode(ISD::STRICT_FMUL, dl, {VT, MVT::Other},
3374+
{Chain, Operand, One});
3375+
3376+
// Propagate existing flags on canonicalize, and additionally set
3377+
// NoFPExcept.
3378+
SDNodeFlags CanonicalizeFlags = Node->getFlags();
3379+
CanonicalizeFlags.setNoFPExcept(true);
3380+
Mul->setFlags(CanonicalizeFlags);
3381+
3382+
Results.push_back(Mul);
3383+
break;
3384+
}
33593385
case ISD::SIGN_EXTEND_INREG: {
33603386
EVT ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT();
33613387
EVT VT = Node->getValueType(0);

llvm/lib/CodeGen/TargetLoweringBase.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,10 @@ void TargetLoweringBase::initActions() {
875875
ISD::FATAN2},
876876
{MVT::f32, MVT::f64, MVT::f128}, Expand);
877877

878+
// Insert custom handling default for llvm.canonicalize.*.
879+
setOperationAction(ISD::FCANONICALIZE,
880+
{MVT::f16, MVT::f32, MVT::f64, MVT::f128}, Expand);
881+
878882
// FIXME: Query RuntimeLibCalls to make the decision.
879883
setOperationAction({ISD::LRINT, ISD::LLRINT, ISD::LROUND, ISD::LLROUND},
880884
{MVT::f32, MVT::f64, MVT::f128}, LibCall);

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,12 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
768768
setOperationAction(Op, MVT::v8bf16, Expand);
769769
}
770770

771+
// Legalize fcanonicalize to circumvent default expansion
772+
setOperationAction(ISD::FCANONICALIZE, {MVT::f32, MVT::f64}, Legal);
773+
if (Subtarget->hasFullFP16()) {
774+
setOperationAction(ISD::FCANONICALIZE, MVT::f16, Legal);
775+
}
776+
771777
// fpextend from f16 or bf16 to f32 is legal
772778
setOperationAction(ISD::FP_EXTEND, MVT::f32, Legal);
773779
setOperationAction(ISD::FP_EXTEND, MVT::v4f32, Legal);

llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,11 @@ AMDGPUTargetLowering::AMDGPUTargetLowering(const TargetMachine &TM,
423423
setOperationAction({ISD::FLOG10, ISD::FLOG, ISD::FEXP, ISD::FEXP10}, MVT::f16,
424424
Custom);
425425

426+
setOperationAction(ISD::FCANONICALIZE, {MVT::f32, MVT::f64}, Legal);
427+
if (Subtarget->has16BitInsts()) {
428+
setOperationAction(ISD::FCANONICALIZE, MVT::f16, Legal);
429+
}
430+
426431
// FIXME: These IS_FPCLASS vector fp types are marked custom so it reaches
427432
// scalarization code. Can be removed when IS_FPCLASS expand isn't called by
428433
// default unless marked custom/legal.

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
195195
setOperationAction(ISD::FMINNUM, MVT::f32, Legal);
196196
setOperationAction(ISD::FMAXNUM_IEEE, MVT::f32, Legal);
197197
setOperationAction(ISD::FMAXNUM, MVT::f32, Legal);
198+
setOperationAction(ISD::FCANONICALIZE, MVT::f32, Legal);
198199
setOperationAction(ISD::STRICT_FSETCCS, MVT::f32, Legal);
199200
setOperationAction(ISD::STRICT_FSETCC, MVT::f32, Legal);
200201
setOperationAction(ISD::IS_FPCLASS, MVT::f32, Legal);
@@ -242,6 +243,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
242243
setOperationAction(ISD::FMINNUM_IEEE, MVT::f64, Legal);
243244
setOperationAction(ISD::FMINNUM, MVT::f64, Legal);
244245
setOperationAction(ISD::FMAXNUM_IEEE, MVT::f64, Legal);
246+
setOperationAction(ISD::FCANONICALIZE, MVT::f64, Legal);
245247
setOperationAction(ISD::FMAXNUM, MVT::f64, Legal);
246248
setOperationAction(ISD::IS_FPCLASS, MVT::f64, Legal);
247249
setOperationAction(ISD::FSIN, MVT::f64, Expand);

llvm/lib/Target/Mips/MipsISelLowering.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,8 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
373373
setOperationAction(ISD::FMAXNUM, MVT::f64, Legal);
374374
setOperationAction(ISD::IS_FPCLASS, MVT::f32, Legal);
375375
setOperationAction(ISD::IS_FPCLASS, MVT::f64, Legal);
376+
setOperationAction(ISD::FCANONICALIZE, MVT::f32, Legal);
377+
setOperationAction(ISD::FCANONICALIZE, MVT::f64, Legal);
376378
} else {
377379
setOperationAction(ISD::FCANONICALIZE, MVT::f32, Custom);
378380
setOperationAction(ISD::FCANONICALIZE, MVT::f64, Custom);

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,8 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
777777
setOperationAction(ISD::FMAXNUM_IEEE, MVT::f32, Legal);
778778
setOperationAction(ISD::FMINNUM_IEEE, MVT::f64, Legal);
779779
setOperationAction(ISD::FMINNUM_IEEE, MVT::f32, Legal);
780+
setOperationAction(ISD::FCANONICALIZE, MVT::f64, Legal);
781+
setOperationAction(ISD::FCANONICALIZE, MVT::f32, Legal);
780782
}
781783

782784
if (Subtarget.hasAltivec()) {

0 commit comments

Comments
 (0)