Skip to content

Commit 611b50e

Browse files
[DAG] Implement generic llvm.canonicalize.f(16|32|64|128).
Previously, this expansion for the intrinsic has been implemented in the X86 backend. As suggested in the comments for the PR that merges that implementation (#106370), this commit replicates that implementation (at least for `f(16|32|64|128)`) in common code. Canonicalization is thus implemented here as multiplication with 1.0. This commit also touches the following backends: AArch64, AMDGPU, Mips, PowerPC, and LoongArch. These backends previously added their own legalization for `ISD::FCANONICALIZE`, but did not set the OperationAction accordingly, since there was no default OperationAction in common code. Thus, this commit adds the required `setOperationAction` calls and is otherwise intended as NFC for these backends.
1 parent f1cc0b6 commit 611b50e

File tree

7 files changed

+46
-0
lines changed

7 files changed

+46
-0
lines changed

llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3356,6 +3356,31 @@ 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.
3366+
3367+
// Create strict multiplication by 1.0.
3368+
SDValue Operand = Node->getOperand(0);
3369+
EVT VT = Operand.getValueType();
3370+
SDValue One = DAG.getConstantFP(1.0, dl, VT);
3371+
SDValue Chain = DAG.getEntryNode();
3372+
SDValue Mul = DAG.getNode(ISD::STRICT_FMUL, dl, {VT, MVT::Other},
3373+
{Chain, Operand, One});
3374+
3375+
// Propagate existing flags on canonicalize, and additionally set
3376+
// NoFPExcept.
3377+
SDNodeFlags CanonicalizeFlags = Node->getFlags();
3378+
CanonicalizeFlags.setNoFPExcept(true);
3379+
Mul->setFlags(CanonicalizeFlags);
3380+
3381+
Results.push_back(Mul);
3382+
break;
3383+
}
33593384
case ISD::SIGN_EXTEND_INREG: {
33603385
EVT ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT();
33613386
EVT VT = Node->getValueType(0);

llvm/lib/CodeGen/TargetLoweringBase.cpp

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

875+
// Insert custom handling default for llvm.canonicalize.*.
876+
setOperationAction(ISD::FCANONICALIZE,
877+
{MVT::f16, MVT::f32, MVT::f64, MVT::f128}, Expand);
878+
875879
// FIXME: Query RuntimeLibCalls to make the decision.
876880
setOperationAction({ISD::LRINT, ISD::LLRINT, ISD::LROUND, ISD::LLROUND},
877881
{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)