summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AArch64/AArch64FastISel.cpp
diff options
context:
space:
mode:
authorJuergen Ributzka <juergen@apple.com>2014-09-15 22:07:49 +0000
committerJuergen Ributzka <juergen@apple.com>2014-09-15 22:07:49 +0000
commitafa034fb61f64c9b9ca11a4feb144720e440e8f9 (patch)
treed52a07c8ae03fdfe6d837acd317928d3b0d65b9c /llvm/lib/Target/AArch64/AArch64FastISel.cpp
parent3c5f180255ba462d9f1c19adc453efe6d1cc14a0 (diff)
downloadbcm5719-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.cpp45
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.
OpenPOWER on IntegriCloud