]> granicus.if.org Git - llvm/commitdiff
[MIPS] Use custom bitcast lowering to avoid excessive instructions
authorSimon Atanasyan <simon@atanasyan.com>
Thu, 25 Apr 2019 07:47:28 +0000 (07:47 +0000)
committerSimon Atanasyan <simon@atanasyan.com>
Thu, 25 Apr 2019 07:47:28 +0000 (07:47 +0000)
On Mips32r2 bitcast can be expanded to two sw instructions and an ldc1
when using bitcast i64 to double or an sdc1 and two lw instructions when
using bitcast double to i64. By introducing custom lowering that uses
mtc1/mthc1 we can avoid excessive instructions.

Patch by Mirko Brkusanin.

Differential Revision: https://reviews.llvm.org/D61069

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@359171 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MipsISelLowering.cpp
lib/Target/Mips/MipsSEISelLowering.cpp
lib/Target/Mips/MipsSEISelLowering.h
test/CodeGen/Mips/llvm-ir/bitcast.ll

index 99de079788e41b0f1ccb286c12ceb0f629678a8a..943f4f2d4c4eee14997aef6517cc5f6479e9f2ca 100644 (file)
@@ -1203,8 +1203,9 @@ MipsTargetLowering::LowerOperationWrapper(SDNode *N,
                                           SelectionDAG &DAG) const {
   SDValue Res = LowerOperation(SDValue(N, 0), DAG);
 
-  for (unsigned I = 0, E = Res->getNumValues(); I != E; ++I)
-    Results.push_back(Res.getValue(I));
+  if (Res)
+    for (unsigned I = 0, E = Res->getNumValues(); I != E; ++I)
+      Results.push_back(Res.getValue(I));
 }
 
 void
index 9698a4979e58fa05032e53f302f358386759bf9c..6fbdba4c6919009266397d285d9f3a7a7a4c629d 100644 (file)
@@ -213,6 +213,11 @@ MipsSETargetLowering::MipsSETargetLowering(const MipsTargetMachine &TM,
   setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
   setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
 
+  if (Subtarget.hasMips32r2() && !Subtarget.useSoftFloat() &&
+      !Subtarget.hasMips64()) {
+    setOperationAction(ISD::BITCAST, MVT::i64, Custom);
+  }
+
   if (NoDPLoadStore) {
     setOperationAction(ISD::LOAD, MVT::f64, Custom);
     setOperationAction(ISD::STORE, MVT::f64, Custom);
@@ -462,6 +467,7 @@ SDValue MipsSETargetLowering::LowerOperation(SDValue Op,
   case ISD::BUILD_VECTOR:       return lowerBUILD_VECTOR(Op, DAG);
   case ISD::VECTOR_SHUFFLE:     return lowerVECTOR_SHUFFLE(Op, DAG);
   case ISD::SELECT:             return lowerSELECT(Op, DAG);
+  case ISD::BITCAST:            return lowerBITCAST(Op, DAG);
   }
 
   return MipsTargetLowering::LowerOperation(Op, DAG);
@@ -1220,6 +1226,36 @@ SDValue MipsSETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {
                       Nd.getMemOperand()->getFlags(), Nd.getAAInfo());
 }
 
+SDValue MipsSETargetLowering::lowerBITCAST(SDValue Op,
+                                           SelectionDAG &DAG) const {
+  SDLoc DL(Op);
+  MVT Src = Op.getOperand(0).getValueType().getSimpleVT();
+  MVT Dest = Op.getValueType().getSimpleVT();
+
+  // Bitcast i64 to double.
+  if (Src == MVT::i64 && Dest == MVT::f64) {
+    SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32,
+                             Op.getOperand(0), DAG.getIntPtrConstant(0, DL));
+    SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32,
+                             Op.getOperand(0), DAG.getIntPtrConstant(1, DL));
+    return DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
+  }
+
+  // Bitcast double to i64.
+  if (Src == MVT::f64 && Dest == MVT::i64) {
+    SDValue Lo =
+        DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0),
+                    DAG.getConstant(0, DL, MVT::i32));
+    SDValue Hi =
+        DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0),
+                    DAG.getConstant(1, DL, MVT::i32));
+    return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi);
+  }
+
+  // Skip other cases of bitcast and use default lowering.
+  return SDValue();
+}
+
 SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
                                           bool HasLo, bool HasHi,
                                           SelectionDAG &DAG) const {
index 3da78921f84f5785c36932e550e0d003c19c83ba..787e2ac394df191c1bce009f227aa9e781e3f4be 100644 (file)
@@ -72,6 +72,7 @@ class TargetRegisterClass;
 
     SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const;
     SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const;
+    SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const;
 
     SDValue lowerMulDiv(SDValue Op, unsigned NewOpc, bool HasLo, bool HasHi,
                         SelectionDAG &DAG) const;
index 6593103de8df7a5e088323311e2601bf9a47bbc3..a649234342dd2a56a7014a731e78bf39a57f18b1 100644 (file)
@@ -1,13 +1,13 @@
 ; RUN: llc -march=mips -mcpu=mips32r2                         -asm-show-inst \
-; RUN: -mno-ldc1-sdc1 < %s | FileCheck %s --check-prefix=MIPS32R2
+; RUN: < %s | FileCheck %s --check-prefix=MIPS32R2
 ; RUN: llc -march=mips -mcpu=mips32r2 -mattr=+fp64            -asm-show-inst \
-; RUN: -mno-ldc1-sdc1 < %s | FileCheck %s --check-prefix=MIPS32FP64
+; RUN: < %s | FileCheck %s --check-prefix=MIPS32FP64
 ; RUN: llc -march=mips -mcpu=mips32r3 -mattr=+micromips       -asm-show-inst \
-; RUN: -mno-ldc1-sdc1 < %s | FileCheck %s --check-prefix=MM
+; RUN: < %s | FileCheck %s --check-prefix=MM
 ; RUN: llc -march=mips -mcpu=mips32r3 -mattr=+micromips,+fp64 -asm-show-inst \
-; RUN: -mno-ldc1-sdc1 < %s | FileCheck %s --check-prefix=MMFP64
+; RUN: < %s | FileCheck %s --check-prefix=MMFP64
 ; RUN: llc -march=mips -mcpu=mips32r6 -mattr=+micromips       -asm-show-inst \
-; RUN: -mno-ldc1-sdc1 < %s | FileCheck %s --check-prefix=MMR6
+; RUN: < %s | FileCheck %s --check-prefix=MMR6
 
 define double @mthc1(i64 %a) {
 ; MIPS32R2:   mthc1   {{.*}}                 # <MCInst #{{[0-9]+}} MTHC1_D32