diff options
author | Tim Northover <tnorthover@apple.com> | 2016-08-29 19:07:16 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2016-08-29 19:07:16 +0000 |
commit | edb3c8ccb8785c90cee8b71c4ed8eb13b72f9ae4 (patch) | |
tree | d7fcadd47e44fb508c8b6b993e1874ef8237988e /llvm | |
parent | fe5f89ba144f03fa10e93307988d787309d3a744 (diff) | |
download | bcm5719-llvm-edb3c8ccb8785c90cee8b71c4ed8eb13b72f9ae4.tar.gz bcm5719-llvm-edb3c8ccb8785c90cee8b71c4ed8eb13b72f9ae4.zip |
GlobalISel: legalize frem to a libcall on AArch64.
llvm-svn: 279988
Diffstat (limited to 'llvm')
8 files changed, 54 insertions, 5 deletions
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h index c293ad25ea3..e96522493ae 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h @@ -88,9 +88,9 @@ class CallLowering { /// needs to be passed. /// /// \return true if the lowering succeeded, false otherwise. - virtual bool lowerCall(MachineIRBuilder &MIRBuilder, MachineOperand &Callee, - ArrayRef<MVT> ResTys, ArrayRef<unsigned> ResRegs, - ArrayRef<MVT> ArgTys, + virtual bool lowerCall(MachineIRBuilder &MIRBuilder, + const MachineOperand &Callee, ArrayRef<MVT> ResTys, + ArrayRef<unsigned> ResRegs, ArrayRef<MVT> ArgTys, ArrayRef<unsigned> ArgRegs) const { return false; } diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h index c3ba7354282..e0b2345888e 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h @@ -61,6 +61,9 @@ public: LegalizeResult legalizeInstr(MachineInstr &MI, const MachineLegalizer &Legalizer); + /// Legalize an instruction by emiting a runtime library call instead. + LegalizeResult libcall(MachineInstr &MI); + /// Legalize an instruction by reducing the width of the underlying scalar /// type. LegalizeResult narrowScalar(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy); diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp index b6ec2b89ad6..afc8289640b 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp @@ -14,10 +14,12 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h" +#include "llvm/CodeGen/GlobalISel/CallLowering.h" #include "llvm/CodeGen/GlobalISel/MachineLegalizer.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetSubtargetInfo.h" #include <sstream> @@ -38,6 +40,8 @@ MachineLegalizeHelper::legalizeInstrStep(MachineInstr &MI, switch (std::get<0>(Action)) { case MachineLegalizer::Legal: return AlreadyLegal; + case MachineLegalizer::Libcall: + return libcall(MI); case MachineLegalizer::NarrowScalar: return narrowScalar(MI, std::get<1>(Action), std::get<2>(Action)); case MachineLegalizer::WidenScalar: @@ -90,6 +94,30 @@ void MachineLegalizeHelper::extractParts(unsigned Reg, LLT Ty, int NumParts, } MachineLegalizeHelper::LegalizeResult +MachineLegalizeHelper::libcall(MachineInstr &MI) { + unsigned Size = MI.getType().getSizeInBits(); + MIRBuilder.setInstr(MI); + + switch (MI.getOpcode()) { + default: + return UnableToLegalize; + case TargetOpcode::G_FREM: { + MVT Ty = MVT::getFloatingPointVT(MI.getType().getSizeInBits()); + 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); + + CLI.lowerCall(MIRBuilder, MachineOperand::CreateES(Name), Ty, + MI.getOperand(0).getReg(), {Ty, Ty}, + {MI.getOperand(1).getReg(), MI.getOperand(2).getReg()}); + MI.eraseFromParent(); + return Legalized; + } + } +} + +MachineLegalizeHelper::LegalizeResult MachineLegalizeHelper::narrowScalar(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy) { // FIXME: Don't know how to handle secondary types yet. diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp index c6ee362c63f..11b04f491ee 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp @@ -127,6 +127,7 @@ LLT MachineLegalizer::findLegalType(const InstrAspect &Aspect, llvm_unreachable("Cannot find legal type"); case Legal: case Lower: + case Libcall: return Aspect.Type; case NarrowScalar: { return findLegalType(Aspect, diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp index 6fa29754f70..48ff3edfc35 100644 --- a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp @@ -131,7 +131,7 @@ bool AArch64CallLowering::lowerFormalArguments( } bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, - MachineOperand &Callee, + const MachineOperand &Callee, ArrayRef<MVT> ResTys, ArrayRef<unsigned> ResRegs, ArrayRef<MVT> ArgTys, diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.h b/llvm/lib/Target/AArch64/AArch64CallLowering.h index 1fe929d1fad..19bbb150e99 100644 --- a/llvm/lib/Target/AArch64/AArch64CallLowering.h +++ b/llvm/lib/Target/AArch64/AArch64CallLowering.h @@ -34,7 +34,7 @@ class AArch64CallLowering: public CallLowering { const Function::ArgumentListType &Args, ArrayRef<unsigned> VRegs) const override; - bool lowerCall(MachineIRBuilder &MIRBuilder, MachineOperand &Callee, + bool lowerCall(MachineIRBuilder &MIRBuilder, const MachineOperand &Callee, ArrayRef<MVT> ResTys, ArrayRef<unsigned> ResRegs, ArrayRef<MVT> ArgTys, ArrayRef<unsigned> ArgRegs) const override; diff --git a/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp b/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp index 0ea86733187..8a0b5b0dcac 100644 --- a/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp +++ b/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp @@ -66,6 +66,9 @@ AArch64MachineLegalizer::AArch64MachineLegalizer() { for (auto Ty : {s32, s64}) setAction({BinOp, Ty}, Legal); + setAction({G_FREM, s32}, Libcall); + setAction({G_FREM, s64}, Libcall); + for (auto MemOp : {G_LOAD, G_STORE}) { for (auto Ty : {s8, s16, s32, s64}) setAction({MemOp, Ty}, Legal); diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-rem.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-rem.mir index cfd0958dae3..53af5eb92fd 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-rem.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-rem.mir @@ -21,6 +21,8 @@ registers: - { id: 6, class: _ } - { id: 7, class: _ } - { id: 8, class: _ } + - { id: 9, class: _ } + - { id: 10, class: _ } body: | bb.0.entry: liveins: %x0, %x1, %x2, %x3 @@ -49,4 +51,16 @@ body: | %7(8) = G_TRUNC { s8, s64 } %1 %8(8) = G_SREM s8 %6, %7 + ; CHECK: %d0 = COPY %0 + ; CHECK: %d1 = COPY %1 + ; CHECK: BL $fmod, csr_aarch64_aapcs, implicit-def %lr, implicit %sp, implicit %d0, implicit %d1, implicit-def %d0 + ; CHECK: %9(64) = COPY %d0 + %9(64) = G_FREM s64 %0, %1 + + ; CHECK: %s0 = COPY %3 + ; CHECK: %s1 = COPY %4 + ; CHECK: BL $fmodf, csr_aarch64_aapcs, implicit-def %lr, implicit %sp, implicit %s0, implicit %s1, implicit-def %s0 + ; CHECK: %10(32) = COPY %s0 + %10(32) = G_FREM s32 %3, %4 + ... |