Skip to content

Commit 3e0e1c1

Browse files
authored
[RISCV][GISel] Support fp128 arithmetic and conversion for RV64. (#118707)
We can support these via libcalls in libgcc/compiler-rt or integer operations for fneg/fabs/fcopysign. fp128 values will be passed in two 64-bit GPRs according to the psABI. Supporting RV32 requires sret which is not supported by libcall handling in LegalizerHelper.cpp yet. It doesn't call canLowerReturn.
1 parent dba0861 commit 3e0e1c1

File tree

3 files changed

+559
-8
lines changed

3 files changed

+559
-8
lines changed

llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,11 @@ class LegalizeRuleSet {
778778
LegalizeRuleSet &libcallFor(std::initializer_list<LLT> Types) {
779779
return actionFor(LegalizeAction::Libcall, Types);
780780
}
781+
LegalizeRuleSet &libcallFor(bool Pred, std::initializer_list<LLT> Types) {
782+
if (!Pred)
783+
return *this;
784+
return actionFor(LegalizeAction::Libcall, Types);
785+
}
781786
LegalizeRuleSet &
782787
libcallFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
783788
return actionFor(LegalizeAction::Libcall, Types);

llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -491,21 +491,24 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
491491

492492
// FP Operations
493493

494+
// FIXME: Support s128 for rv32 when libcall handling is able to use sret.
494495
getActionDefinitionsBuilder(
495496
{G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FMA, G_FSQRT, G_FMAXNUM, G_FMINNUM})
496497
.legalFor(ST.hasStdExtF(), {s32})
497498
.legalFor(ST.hasStdExtD(), {s64})
498499
.legalFor(ST.hasStdExtZfh(), {s16})
499-
.libcallFor({s32, s64});
500+
.libcallFor({s32, s64})
501+
.libcallFor(ST.is64Bit(), {s128});
500502

501503
getActionDefinitionsBuilder({G_FNEG, G_FABS})
502504
.legalFor(ST.hasStdExtF(), {s32})
503505
.legalFor(ST.hasStdExtD(), {s64})
504506
.legalFor(ST.hasStdExtZfh(), {s16})
505-
.lowerFor({s32, s64});
507+
.lowerFor({s32, s64, s128});
506508

507509
getActionDefinitionsBuilder(G_FREM)
508510
.libcallFor({s32, s64})
511+
.libcallFor(ST.is64Bit(), {s128})
509512
.minScalar(0, s32)
510513
.scalarize(0);
511514

@@ -521,19 +524,22 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
521524
.legalFor(ST.hasStdExtD(), {{s32, s64}})
522525
.legalFor(ST.hasStdExtZfh(), {{s16, s32}})
523526
.legalFor(ST.hasStdExtZfh() && ST.hasStdExtD(), {{s16, s64}})
524-
.libcallFor({{s32, s64}});
527+
.libcallFor({{s32, s64}})
528+
.libcallFor(ST.is64Bit(), {{s32, s128}, {s64, s128}});
525529
getActionDefinitionsBuilder(G_FPEXT)
526530
.legalFor(ST.hasStdExtD(), {{s64, s32}})
527531
.legalFor(ST.hasStdExtZfh(), {{s32, s16}})
528532
.legalFor(ST.hasStdExtZfh() && ST.hasStdExtD(), {{s64, s16}})
529-
.libcallFor({{s64, s32}});
533+
.libcallFor({{s64, s32}})
534+
.libcallFor(ST.is64Bit(), {{s128, s32}, {s128, s64}});
530535

531536
getActionDefinitionsBuilder(G_FCMP)
532537
.legalFor(ST.hasStdExtF(), {{sXLen, s32}})
533538
.legalFor(ST.hasStdExtD(), {{sXLen, s64}})
534539
.legalFor(ST.hasStdExtZfh(), {{sXLen, s16}})
535540
.clampScalar(0, sXLen, sXLen)
536-
.libcallFor({{sXLen, s32}, {sXLen, s64}});
541+
.libcallFor({{sXLen, s32}, {sXLen, s64}})
542+
.libcallFor(ST.is64Bit(), {{sXLen, s128}});
537543

538544
// TODO: Support vector version of G_IS_FPCLASS.
539545
getActionDefinitionsBuilder(G_IS_FPCLASS)
@@ -546,7 +552,7 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
546552
.legalFor(ST.hasStdExtF(), {s32})
547553
.legalFor(ST.hasStdExtD(), {s64})
548554
.legalFor(ST.hasStdExtZfh(), {s16})
549-
.lowerFor({s32, s64});
555+
.lowerFor({s32, s64, s128});
550556

551557
getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
552558
.legalFor(ST.hasStdExtF(), {{sXLen, s32}})
@@ -558,7 +564,8 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
558564
.widenScalarToNextPow2(0)
559565
.minScalar(0, s32)
560566
.libcallFor({{s32, s32}, {s64, s32}, {s32, s64}, {s64, s64}})
561-
.libcallFor(ST.is64Bit(), {{s128, s32}, {s128, s64}});
567+
.libcallFor(ST.is64Bit(), {{s32, s128}, {s64, s128}}) // FIXME RV32.
568+
.libcallFor(ST.is64Bit(), {{s128, s32}, {s128, s64}, {s128, s128}});
562569

563570
getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
564571
.legalFor(ST.hasStdExtF(), {{s32, sXLen}})
@@ -579,7 +586,8 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
579586
// Otherwise only promote to s32 since we have si libcalls.
580587
.minScalar(1, s32)
581588
.libcallFor({{s32, s32}, {s64, s32}, {s32, s64}, {s64, s64}})
582-
.libcallFor(ST.is64Bit(), {{s32, s128}, {s64, s128}});
589+
.libcallFor(ST.is64Bit(), {{s128, s32}, {s128, s64}}) // FIXME RV32.
590+
.libcallFor(ST.is64Bit(), {{s32, s128}, {s64, s128}, {s128, s128}});
583591

584592
// FIXME: We can do custom inline expansion like SelectionDAG.
585593
// FIXME: Legal with Zfa.

0 commit comments

Comments
 (0)