diff options
author | Juergen Ributzka <juergen@apple.com> | 2014-09-15 22:07:49 +0000 |
---|---|---|
committer | Juergen Ributzka <juergen@apple.com> | 2014-09-15 22:07:49 +0000 |
commit | afa034fb61f64c9b9ca11a4feb144720e440e8f9 (patch) | |
tree | d52a07c8ae03fdfe6d837acd317928d3b0d65b9c /llvm/lib/Target/AArch64/AArch64FastISel.cpp | |
parent | 3c5f180255ba462d9f1c19adc453efe6d1cc14a0 (diff) | |
download | bcm5719-llvm-afa034fb61f64c9b9ca11a4feb144720e440e8f9.tar.gz bcm5719-llvm-afa034fb61f64c9b9ca11a4feb144720e440e8f9.zip |
[FastISel][AArch64] Add lowering support for frem.
This lowers frem to a runtime libcall inside fast-isel.
The test case also checks the CallLoweringInfo bug that was exposed by this
change.
This fixes rdar://problem/18342783.
llvm-svn: 217833
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64FastISel.cpp')
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64FastISel.cpp | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp index 0ea99d442bb..9658834b750 100644 --- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp +++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp @@ -132,6 +132,7 @@ private: bool SelectMul(const Instruction *I); bool SelectShift(const Instruction *I); bool SelectBitCast(const Instruction *I); + bool selectFRem(const Instruction *I); // Utility helper routines. bool isTypeLegal(Type *Ty, MVT &VT); @@ -2322,6 +2323,9 @@ bool AArch64FastISel::fastLowerCall(CallLoweringInfo &CLI) { const Value *Callee = CLI.Callee; const char *SymName = CLI.SymName; + if (!Callee && !SymName) + return false; + // Allow SelectionDAG isel to handle tail calls. if (IsTailCall) return false; @@ -2368,7 +2372,7 @@ bool AArch64FastISel::fastLowerCall(CallLoweringInfo &CLI) { } Address Addr; - if (!ComputeCallAddress(Callee, Addr)) + if (Callee && !ComputeCallAddress(Callee, Addr)) return false; // Handle the arguments now that we've gotten them. @@ -3624,6 +3628,43 @@ bool AArch64FastISel::SelectBitCast(const Instruction *I) { return true; } +bool AArch64FastISel::selectFRem(const Instruction *I) { + MVT RetVT; + if (!isTypeLegal(I->getType(), RetVT)) + return false; + + RTLIB::Libcall LC; + switch (RetVT.SimpleTy) { + default: + return false; + case MVT::f32: + LC = RTLIB::REM_F32; + break; + case MVT::f64: + LC = RTLIB::REM_F64; + break; + } + + ArgListTy Args; + Args.reserve(I->getNumOperands()); + + // Populate the argument list. + for (auto &Arg : I->operands()) { + ArgListEntry Entry; + Entry.Val = Arg; + Entry.Ty = Arg->getType(); + Args.push_back(Entry); + } + + CallLoweringInfo CLI; + CLI.setCallee(TLI.getLibcallCallingConv(LC), I->getType(), + TLI.getLibcallName(LC), std::move(Args)); + if (!lowerCallTo(CLI)) + return false; + updateValueMap(I, CLI.ResultReg); + return true; +} + bool AArch64FastISel::fastSelectInstruction(const Instruction *I) { switch (I->getOpcode()) { default: @@ -3698,6 +3739,8 @@ bool AArch64FastISel::fastSelectInstruction(const Instruction *I) { return SelectSelect(I); case Instruction::Ret: return SelectRet(I); + case Instruction::FRem: + return selectFRem(I); } // fall-back to target-independent instruction selection. |