Use a range loop. NFC.
[oota-llvm.git] / lib / Target / AArch64 / AArch64FastISel.cpp
index 316111d432ddf76de7354c229cb1cdcb65279a37..5114acaec41afe07512039b3ac00eb1ea9d8e6eb 100644 (file)
@@ -217,19 +217,7 @@ unsigned AArch64FastISel::TargetMaterializeAlloca(const AllocaInst *AI) {
 unsigned AArch64FastISel::AArch64MaterializeInt(const ConstantInt *CI, MVT VT) {
   if (VT > MVT::i64)
     return 0;
-
-  if (!CI->isZero())
-    return FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
-
-  // Create a copy from the zero register to materialize a "0" value.
-  const TargetRegisterClass *RC = (VT == MVT::i64) ? &AArch64::GPR64RegClass
-                                                   : &AArch64::GPR32RegClass;
-  unsigned ZeroReg = (VT == MVT::i64) ? AArch64::XZR : AArch64::WZR;
-  unsigned ResultReg = createResultReg(RC);
-  BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
-          TII.get(TargetOpcode::COPY), ResultReg)
-    .addReg(ZeroReg, getKillRegState(true));
-  return ResultReg;
+  return FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
 }
 
 unsigned AArch64FastISel::AArch64MaterializeFP(const ConstantFP *CFP, MVT VT) {
@@ -242,10 +230,19 @@ unsigned AArch64FastISel::AArch64MaterializeFP(const ConstantFP *CFP, MVT VT) {
   // This checks to see if we can use FMOV instructions to materialize
   // a constant, otherwise we have to materialize via the constant pool.
   if (TLI.isFPImmLegal(Val, VT)) {
+    unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
+    // Positive zero (+0.0) has to be materialized with a fmov from the zero
+    // register, because the immediate version of fmov cannot encode zero.
+    if (Val.isPosZero()) {
+      unsigned ZReg = Is64Bit ? AArch64::XZR : AArch64::WZR;
+      unsigned Opc = Is64Bit ? AArch64::FMOVDr : AArch64::FMOVSr;
+      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
+        .addReg(ZReg, getKillRegState(true));
+      return ResultReg;
+    }
     int Imm = Is64Bit ? AArch64_AM::getFP64Imm(Val)
                       : AArch64_AM::getFP32Imm(Val);
     unsigned Opc = Is64Bit ? AArch64::FMOVDi : AArch64::FMOVSi;
-    unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
       .addImm(Imm);
     return ResultReg;
@@ -1566,10 +1563,15 @@ bool AArch64FastISel::FinishCall(CallLoweringInfo &CLI, MVT RetVT,
 
 bool AArch64FastISel::FastLowerCall(CallLoweringInfo &CLI) {
   CallingConv::ID CC  = CLI.CallConv;
+  bool IsTailCall     = CLI.IsTailCall;
   bool IsVarArg       = CLI.IsVarArg;
   const Value *Callee = CLI.Callee;
   const char *SymName = CLI.SymName;
 
+  // Allow SelectionDAG isel to handle tail calls.
+  if (IsTailCall)
+    return false;
+
   CodeModel::Model CM = TM.getCodeModel();
   // Only support the small and large code model.
   if (CM != CodeModel::Small && CM != CodeModel::Large)