[llvm] r217833 - [FastISel][AArch64] Add lowering support for frem.

Juergen Ributzka juergen at apple.com
Mon Sep 15 15:07:49 PDT 2014


Author: ributzka
Date: Mon Sep 15 17:07:49 2014
New Revision: 217833

URL: http://llvm.org/viewvc/llvm-project?rev=217833&view=rev
Log:
[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.

Added:
    llvm/trunk/test/CodeGen/AArch64/fast-isel-frem.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/FastISel.h
    llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp

Modified: llvm/trunk/include/llvm/CodeGen/FastISel.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/FastISel.h?rev=217833&r1=217832&r2=217833&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/FastISel.h (original)
+++ llvm/trunk/include/llvm/CodeGen/FastISel.h Mon Sep 15 17:07:49 2014
@@ -141,8 +141,19 @@ public:
       RetTy = ResultTy;
       Callee = Target;
       CallConv = CC;
+      Args = std::move(ArgsList);
       NumFixedArgs = (FixedArgs == ~0U) ? Args.size() : FixedArgs;
+      return *this;
+    }
+
+    CallLoweringInfo &setCallee(CallingConv::ID CC, Type *ResultTy,
+                                const char *Target, ArgListTy &&ArgsList,
+                                unsigned FixedArgs = ~0U) {
+      RetTy = ResultTy;
+      SymName = Target;
+      CallConv = CC;
       Args = std::move(ArgsList);
+      NumFixedArgs = (FixedArgs == ~0U) ? Args.size() : FixedArgs;
       return *this;
     }
 

Modified: llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp?rev=217833&r1=217832&r2=217833&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64FastISel.cpp Mon Sep 15 17:07:49 2014
@@ -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(Call
   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(Call
   }
 
   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(cons
   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::fastSelectInstruct
     return SelectSelect(I);
   case Instruction::Ret:
     return SelectRet(I);
+  case Instruction::FRem:
+    return selectFRem(I);
   }
 
   // fall-back to target-independent instruction selection.

Added: llvm/trunk/test/CodeGen/AArch64/fast-isel-frem.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/fast-isel-frem.ll?rev=217833&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/fast-isel-frem.ll (added)
+++ llvm/trunk/test/CodeGen/AArch64/fast-isel-frem.ll Mon Sep 15 17:07:49 2014
@@ -0,0 +1,24 @@
+; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort -code-model=small -verify-machineinstrs < %s | FileCheck %s --check-prefix=SMALL
+; RUN: llc -mtriple=aarch64-apple-darwin -fast-isel -fast-isel-abort -code-model=large -verify-machineinstrs < %s | FileCheck %s --check-prefix=LARGE
+
+define float @frem_f32(float %a, float %b) {
+; SMALL-LABEL: frem_f32
+; SMALL:       bl _fmodf
+; LARGE-LABEL: frem_f32
+; LARGE:       adrp  [[REG:x[0-9]+]], _fmodf at GOTPAGE
+; LARGE:       ldr [[REG]], {{\[}}[[REG]], _fmodf at GOTPAGEOFF{{\]}}
+; LARGE-NEXT:  blr [[REG]]
+  %1 = frem float %a, %b
+  ret float %1
+}
+
+define double @frem_f64(double %a, double %b) {
+; SMALL-LABEL: frem_f64
+; SMALL:       bl _fmod
+; LARGE-LABEL: frem_f64
+; LARGE:       adrp  [[REG:x[0-9]+]], _fmod at GOTPAGE
+; LARGE:       ldr [[REG]], {{\[}}[[REG]], _fmod at GOTPAGEOFF{{\]}}
+; LARGE-NEXT:  blr [[REG]]
+  %1 = frem double %a, %b
+  ret double %1
+}





More information about the llvm-commits mailing list