From: Tim Northover Date: Wed, 8 Feb 2017 23:23:39 +0000 (+0000) Subject: GlobalISel: legalize G_FPOW to a libcall on AArch64. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=03324d2ec16e4254a1d831b5c4ce922dc0755eac;p=llvm GlobalISel: legalize G_FPOW to a libcall on AArch64. There's no instruction to implement it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294531 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index f41af0547a3..1f78243e115 100644 --- a/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -92,6 +92,16 @@ void LegalizerHelper::extractParts(unsigned Reg, LLT Ty, int NumParts, MIRBuilder.buildExtract(VRegs, Indexes, Reg); } +static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size) { + switch (Opcode) { + case TargetOpcode::G_FREM: + return Size == 64 ? RTLIB::REM_F64 : RTLIB::REM_F32; + case TargetOpcode::G_FPOW: + return Size == 64 ? RTLIB::POW_F64 : RTLIB::POW_F32; + } + llvm_unreachable("Unknown libcall function"); +} + LegalizerHelper::LegalizeResult LegalizerHelper::libcall(MachineInstr &MI) { LLT Ty = MRI.getType(MI.getOperand(0).getReg()); @@ -101,14 +111,13 @@ LegalizerHelper::libcall(MachineInstr &MI) { switch (MI.getOpcode()) { default: return UnableToLegalize; + case TargetOpcode::G_FPOW: case TargetOpcode::G_FREM: { auto &Ctx = MIRBuilder.getMF().getFunction()->getContext(); Type *Ty = Size == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx); auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering(); auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering(); - const char *Name = - TLI.getLibcallName(Size == 64 ? RTLIB::REM_F64 : RTLIB::REM_F32); - + const char *Name = TLI.getLibcallName(getRTLibDesc(MI.getOpcode(), Size)); CLI.lowerCall( MIRBuilder, MachineOperand::CreateES(Name), {MI.getOperand(0).getReg(), Ty}, diff --git a/lib/Target/AArch64/AArch64LegalizerInfo.cpp b/lib/Target/AArch64/AArch64LegalizerInfo.cpp index 32f9c5f80d0..c978be9ab10 100644 --- a/lib/Target/AArch64/AArch64LegalizerInfo.cpp +++ b/lib/Target/AArch64/AArch64LegalizerInfo.cpp @@ -78,8 +78,10 @@ AArch64LegalizerInfo::AArch64LegalizerInfo() { for (auto Ty : {s32, s64}) setAction({BinOp, Ty}, Legal); - setAction({G_FREM, s32}, Libcall); - setAction({G_FREM, s64}, Libcall); + for (unsigned BinOp : {G_FREM, G_FPOW}) { + setAction({BinOp, s32}, Libcall); + setAction({BinOp, s64}, Libcall); + } // FIXME: what should we do about G_INSERTs with more than one source value? // For now the default of not specifying means we'll fall back. diff --git a/test/CodeGen/AArch64/GlobalISel/legalize-pow.mir b/test/CodeGen/AArch64/GlobalISel/legalize-pow.mir new file mode 100644 index 00000000000..a693d18b8ca --- /dev/null +++ b/test/CodeGen/AArch64/GlobalISel/legalize-pow.mir @@ -0,0 +1,35 @@ +# RUN: llc -O0 -run-pass=legalizer -global-isel %s -o - 2>&1 | FileCheck %s + +--- | + target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" + target triple = "aarch64--" + define void @test_pow() { + entry: + ret void + } +... + +--- +name: test_pow +body: | + bb.0.entry: + liveins: %d0, %d1, %s2, %s3 + + %0:_(s64) = COPY %d0 + %1:_(s64) = COPY %d1 + %2:_(s32) = COPY %s2 + %3:_(s32) = COPY %s3 + + ; CHECK: %d0 = COPY %0 + ; CHECK: %d1 = COPY %1 + ; CHECK: BL $pow, csr_aarch64_aapcs, implicit-def %lr, implicit %sp, implicit %d0, implicit %d1, implicit-def %d0 + ; CHECK: %4(s64) = COPY %d0 + %4:_(s64) = G_FPOW %0, %1 + + ; CHECK: %s0 = COPY %2 + ; CHECK: %s1 = COPY %3 + ; CHECK: BL $powf, csr_aarch64_aapcs, implicit-def %lr, implicit %sp, implicit %s0, implicit %s1, implicit-def %s0 + ; CHECK: %5(s32) = COPY %s0 + %5:_(s32) = G_FPOW %2, %3 + +...