[llvm] aeaca85 - [LoongArch] Add codegen support for handling floating point immediates

Weining Lu via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 6 17:14:39 PDT 2022


Author: gonglingqin
Date: 2022-07-07T08:13:33+08:00
New Revision: aeaca854d123d8a263722b7c80f55333f856d026

URL: https://github.com/llvm/llvm-project/commit/aeaca854d123d8a263722b7c80f55333f856d026
DIFF: https://github.com/llvm/llvm-project/commit/aeaca854d123d8a263722b7c80f55333f856d026.diff

LOG: [LoongArch] Add codegen support for handling floating point immediates

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

Added: 
    llvm/test/CodeGen/LoongArch/double-imm.ll
    llvm/test/CodeGen/LoongArch/float-imm.ll

Modified: 
    llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td
    llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td
    llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
    llvm/lib/Target/LoongArch/LoongArchISelLowering.h
    llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
    llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td
index b1df8db7d480a..9a13b8607dca1 100644
--- a/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchFloat32InstrInfo.td
@@ -182,4 +182,9 @@ defm : LdPat<load, FLD_S, f32>;
 
 defm : StPat<store, FST_S, FPR32, f32>;
 
+/// Floating point constants
+
+def : Pat<(f32 fpimm0), (MOVGR2FR_W R0)>;
+def : Pat<(f32 fpimm0neg), (FNEG_S (MOVGR2FR_W R0))>;
+def : Pat<(f32 fpimm1), (FFINT_S_W (MOVGR2FR_W (ADDI_W R0, 1)))>;
 } // Predicates = [HasBasicF]

diff  --git a/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td
index c3569ae84e9d5..f6402606d9bf6 100644
--- a/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchFloat64InstrInfo.td
@@ -131,6 +131,11 @@ def MOVGR2FR_D  : FP_MOV<0b0000000100010100101010, "movgr2fr.d", FPR64, GPR>;
 def MOVFR2GR_D  : FP_MOV<0b0000000100010100101110, "movfr2gr.d", GPR, FPR64>;
 } // Predicates = [HasBasicD, IsLA64]
 
+// Instructions only available on LA32
+let Predicates = [HasBasicD, IsLA32], isCodeGenOnly = 1 in {
+def MOVGR2FR_W_64 : FP_MOV<0b0000000100010100101001, "movgr2fr.w", FPR64, GPR>;
+} // Predicates = [HasBasicD, IsLA32], isCodeGenOnly = 1
+
 //===----------------------------------------------------------------------===//
 // Pseudo-instructions and codegen patterns
 //===----------------------------------------------------------------------===//
@@ -192,5 +197,18 @@ defm : LdPat<load, FLD_D, f64>;
 /// Stores
 
 defm : StPat<store, FST_D, FPR64, f64>;
-
 } // Predicates = [HasBasicD]
+
+/// Floating point constants
+
+let Predicates = [HasBasicD, IsLA64] in {
+def : Pat<(f64 fpimm0), (MOVGR2FR_D R0)>;
+def : Pat<(f64 fpimm0neg), (FNEG_D (MOVGR2FR_D R0))>;
+def : Pat<(f64 fpimm1), (FFINT_D_L (MOVGR2FR_D (ADDI_D R0, 1)))>;
+} // Predicates = [HasBasicD, IsLA64]
+
+let Predicates = [HasBasicD, IsLA32] in {
+def : Pat<(f64 fpimm0), (MOVGR2FRH_W (MOVGR2FR_W_64 R0), R0)>;
+def : Pat<(f64 fpimm0neg), (FNEG_D (MOVGR2FRH_W (MOVGR2FR_W_64 R0), R0))>;
+def : Pat<(f64 fpimm1), (FCVT_D_S (FFINT_S_W (MOVGR2FR_W (ADDI_W R0, 1))))>;
+} // Predicates = [HasBasicD, IsLA32]

diff  --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 25823b777cbe1..a8f95a0e62db6 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -51,7 +51,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
   setOperationAction(ISD::SRA_PARTS, GRLenVT, Custom);
   setOperationAction(ISD::SRL_PARTS, GRLenVT, Custom);
 
-  setOperationAction(ISD::GlobalAddress, GRLenVT, Custom);
+  setOperationAction({ISD::GlobalAddress, ISD::ConstantPool}, GRLenVT, Custom);
 
   if (Subtarget.is64Bit()) {
     setOperationAction(ISD::SHL, MVT::i32, Custom);
@@ -69,6 +69,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
   if (Subtarget.hasBasicD()) {
     setCondCodeAction(FPCCToExpand, MVT::f64, Expand);
     setOperationAction(ISD::SELECT_CC, MVT::f64, Expand);
+    setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand);
   }
 
   setOperationAction(ISD::BR_CC, GRLenVT, Expand);
@@ -110,9 +111,33 @@ SDValue LoongArchTargetLowering::LowerOperation(SDValue Op,
     assert(Op.getOperand(1).getValueType() == MVT::i32 && Subtarget.is64Bit() &&
            "Unexpected custom legalisation");
     return SDValue();
+  case ISD::ConstantPool:
+    return lowerConstantPool(Op, DAG);
   }
 }
 
+SDValue LoongArchTargetLowering::lowerConstantPool(SDValue Op,
+                                                   SelectionDAG &DAG) const {
+  SDLoc DL(Op);
+  EVT Ty = Op.getValueType();
+  ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
+
+  // FIXME: Only support PC-relative addressing to access the symbol.
+  // Target flags will be added later.
+  if (!isPositionIndependent()) {
+    SDValue ConstantN = DAG.getTargetConstantPool(
+        N->getConstVal(), Ty, N->getAlign(), N->getOffset());
+    SDValue AddrHi(DAG.getMachineNode(LoongArch::PCALAU12I, DL, Ty, ConstantN),
+                   0);
+    SDValue Addr(DAG.getMachineNode(Subtarget.is64Bit() ? LoongArch::ADDI_D
+                                                        : LoongArch::ADDI_W,
+                                    DL, Ty, AddrHi, ConstantN),
+                 0);
+    return Addr;
+  }
+  report_fatal_error("Unable to lower ConstantPool");
+}
+
 SDValue LoongArchTargetLowering::lowerGlobalAddress(SDValue Op,
                                                     SelectionDAG &DAG) const {
   SDLoc DL(Op);
@@ -736,3 +761,14 @@ SDValue LoongArchTargetLowering::LowerReturn(
 
   return DAG.getNode(LoongArchISD::RET, DL, MVT::Other, RetOps);
 }
+
+bool LoongArchTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
+                                           bool ForCodeSize) const {
+  assert((VT == MVT::f32 || VT == MVT::f64) && "Unexpected VT");
+
+  if (VT == MVT::f32 && !Subtarget.hasBasicF())
+    return false;
+  if (VT == MVT::f64 && !Subtarget.hasBasicD())
+    return false;
+  return (Imm.isZero() || Imm.isExactlyValue(+1.0));
+}

diff  --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
index 80845d2d627dd..6e4747a5f9400 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
@@ -96,6 +96,10 @@ class LoongArchTargetLowering : public TargetLowering {
   MachineBasicBlock *
   EmitInstrWithCustomInserter(MachineInstr &MI,
                               MachineBasicBlock *BB) const override;
+  SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
+
+  bool isFPImmLegal(const APFloat &Imm, EVT VT,
+                    bool ForCodeSize) const override;
 };
 
 } // end namespace llvm

diff  --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
index 98c3bffb0c405..57130f169b8fe 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -164,6 +164,11 @@ def NegImm : SDNodeXForm<imm, [{
                                    N->getValueType(0));
 }]>;
 
+// FP immediate patterns.
+def fpimm0    : PatLeaf<(fpimm), [{return N->isExactlyValue(+0.0);}]>;
+def fpimm0neg : PatLeaf<(fpimm), [{return N->isExactlyValue(-0.0);}]>;
+def fpimm1    : PatLeaf<(fpimm), [{return N->isExactlyValue(+1.0);}]>;
+
 def CallSymbol: AsmOperandClass {
   let Name = "CallSymbol";
   let RenderMethod = "addImmOperands";

diff  --git a/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp b/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
index 6c77a79369ad5..488c66f47863c 100644
--- a/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
@@ -57,6 +57,9 @@ bool llvm::lowerLoongArchMachineOperandToMCOperand(const MachineOperand &MO,
   case MachineOperand::MO_Immediate:
     MCOp = MCOperand::createImm(MO.getImm());
     break;
+  case MachineOperand::MO_ConstantPoolIndex:
+    MCOp = lowerSymbolOperand(MO, AP.GetCPISymbol(MO.getIndex()), AP);
+    break;
   case MachineOperand::MO_GlobalAddress:
     MCOp = lowerSymbolOperand(MO, AP.getSymbolPreferLocal(*MO.getGlobal()), AP);
     break;
@@ -69,7 +72,6 @@ bool llvm::lowerLoongArchMachineOperandToMCOperand(const MachineOperand &MO,
     break;
   // TODO: lower special operands
   case MachineOperand::MO_BlockAddress:
-  case MachineOperand::MO_ConstantPoolIndex:
   case MachineOperand::MO_JumpTableIndex:
     break;
   }

diff  --git a/llvm/test/CodeGen/LoongArch/double-imm.ll b/llvm/test/CodeGen/LoongArch/double-imm.ll
new file mode 100644
index 0000000000000..a7782cf85954d
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/double-imm.ll
@@ -0,0 +1,89 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32
+; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64
+
+define double @f64_positive_zero() nounwind {
+; LA32-LABEL: f64_positive_zero:
+; LA32:       # %bb.0:
+; LA32-NEXT:    movgr2fr.w $fa0, $zero
+; LA32-NEXT:    movgr2frh.w $fa0, $zero
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: f64_positive_zero:
+; LA64:       # %bb.0:
+; LA64-NEXT:    movgr2fr.d $fa0, $zero
+; LA64-NEXT:    jirl $zero, $ra, 0
+  ret double 0.0
+}
+
+define double @f64_negative_zero() nounwind {
+; LA32-LABEL: f64_negative_zero:
+; LA32:       # %bb.0:
+; LA32-NEXT:    movgr2fr.w $fa0, $zero
+; LA32-NEXT:    movgr2frh.w $fa0, $zero
+; LA32-NEXT:    fneg.d $fa0, $fa0
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: f64_negative_zero:
+; LA64:       # %bb.0:
+; LA64-NEXT:    movgr2fr.d $fa0, $zero
+; LA64-NEXT:    fneg.d $fa0, $fa0
+; LA64-NEXT:    jirl $zero, $ra, 0
+  ret double -0.0
+}
+
+define double @f64_constant_pi() nounwind {
+; LA32-LABEL: f64_constant_pi:
+; LA32:       # %bb.0:
+; LA32-NEXT:    pcalau12i $a0, .LCPI2_0
+; LA32-NEXT:    addi.w $a0, $a0, .LCPI2_0
+; LA32-NEXT:    fld.d $fa0, $a0, 0
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: f64_constant_pi:
+; LA64:       # %bb.0:
+; LA64-NEXT:    pcalau12i $a0, .LCPI2_0
+; LA64-NEXT:    addi.d $a0, $a0, .LCPI2_0
+; LA64-NEXT:    fld.d $fa0, $a0, 0
+; LA64-NEXT:    jirl $zero, $ra, 0
+  ret double 3.1415926535897931159979634685441851615905761718750
+}
+
+define double @f64_add_fimm1(double %a) nounwind {
+; LA32-LABEL: f64_add_fimm1:
+; LA32:       # %bb.0:
+; LA32-NEXT:    addi.w $a0, $zero, 1
+; LA32-NEXT:    movgr2fr.w $fa1, $a0
+; LA32-NEXT:    ffint.s.w $fa1, $fa1
+; LA32-NEXT:    fcvt.d.s $fa1, $fa1
+; LA32-NEXT:    fadd.d $fa0, $fa0, $fa1
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: f64_add_fimm1:
+; LA64:       # %bb.0:
+; LA64-NEXT:    addi.d $a0, $zero, 1
+; LA64-NEXT:    movgr2fr.d $fa1, $a0
+; LA64-NEXT:    ffint.d.l $fa1, $fa1
+; LA64-NEXT:    fadd.d $fa0, $fa0, $fa1
+; LA64-NEXT:    jirl $zero, $ra, 0
+  %1 = fadd double %a, 1.0
+  ret double %1
+}
+
+define double @f64_positive_fimm1() nounwind {
+; LA32-LABEL: f64_positive_fimm1:
+; LA32:       # %bb.0:
+; LA32-NEXT:    addi.w $a0, $zero, 1
+; LA32-NEXT:    movgr2fr.w $fa0, $a0
+; LA32-NEXT:    ffint.s.w $fa0, $fa0
+; LA32-NEXT:    fcvt.d.s $fa0, $fa0
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: f64_positive_fimm1:
+; LA64:       # %bb.0:
+; LA64-NEXT:    addi.d $a0, $zero, 1
+; LA64-NEXT:    movgr2fr.d $fa0, $a0
+; LA64-NEXT:    ffint.d.l $fa0, $fa0
+; LA64-NEXT:    jirl $zero, $ra, 0
+  ret double 1.0
+}

diff  --git a/llvm/test/CodeGen/LoongArch/float-imm.ll b/llvm/test/CodeGen/LoongArch/float-imm.ll
new file mode 100644
index 0000000000000..a6b542c29ed73
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/float-imm.ll
@@ -0,0 +1,85 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc --mtriple=loongarch32 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA32
+; RUN: llc --mtriple=loongarch64 --mattr=+f,-d < %s | FileCheck %s --check-prefix=LA64
+
+define float @f32_positive_zero() nounwind {
+; LA32-LABEL: f32_positive_zero:
+; LA32:       # %bb.0:
+; LA32-NEXT:    movgr2fr.w $fa0, $zero
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: f32_positive_zero:
+; LA64:       # %bb.0:
+; LA64-NEXT:    movgr2fr.w $fa0, $zero
+; LA64-NEXT:    jirl $zero, $ra, 0
+  ret float 0.0
+}
+
+define float @f32_negative_zero() nounwind {
+; LA32-LABEL: f32_negative_zero:
+; LA32:       # %bb.0:
+; LA32-NEXT:    movgr2fr.w $fa0, $zero
+; LA32-NEXT:    fneg.s $fa0, $fa0
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: f32_negative_zero:
+; LA64:       # %bb.0:
+; LA64-NEXT:    movgr2fr.w $fa0, $zero
+; LA64-NEXT:    fneg.s $fa0, $fa0
+; LA64-NEXT:    jirl $zero, $ra, 0
+  ret float -0.0
+}
+
+define float @f32_constant_pi() nounwind {
+; LA32-LABEL: f32_constant_pi:
+; LA32:       # %bb.0:
+; LA32-NEXT:    pcalau12i $a0, .LCPI2_0
+; LA32-NEXT:    addi.w $a0, $a0, .LCPI2_0
+; LA32-NEXT:    fld.s $fa0, $a0, 0
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: f32_constant_pi:
+; LA64:       # %bb.0:
+; LA64-NEXT:    pcalau12i $a0, .LCPI2_0
+; LA64-NEXT:    addi.d $a0, $a0, .LCPI2_0
+; LA64-NEXT:    fld.s $fa0, $a0, 0
+; LA64-NEXT:    jirl $zero, $ra, 0
+  ret float 3.14159274101257324218750
+}
+
+define float @f32_add_fimm1(float %a) nounwind {
+; LA32-LABEL: f32_add_fimm1:
+; LA32:       # %bb.0:
+; LA32-NEXT:    addi.w $a0, $zero, 1
+; LA32-NEXT:    movgr2fr.w $fa1, $a0
+; LA32-NEXT:    ffint.s.w $fa1, $fa1
+; LA32-NEXT:    fadd.s $fa0, $fa0, $fa1
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: f32_add_fimm1:
+; LA64:       # %bb.0:
+; LA64-NEXT:    addi.w $a0, $zero, 1
+; LA64-NEXT:    movgr2fr.w $fa1, $a0
+; LA64-NEXT:    ffint.s.w $fa1, $fa1
+; LA64-NEXT:    fadd.s $fa0, $fa0, $fa1
+; LA64-NEXT:    jirl $zero, $ra, 0
+  %1 = fadd float %a, 1.0
+  ret float %1
+}
+
+define float @f32_positive_fimm1() nounwind {
+; LA32-LABEL: f32_positive_fimm1:
+; LA32:       # %bb.0:
+; LA32-NEXT:    addi.w $a0, $zero, 1
+; LA32-NEXT:    movgr2fr.w $fa0, $a0
+; LA32-NEXT:    ffint.s.w $fa0, $fa0
+; LA32-NEXT:    jirl $zero, $ra, 0
+;
+; LA64-LABEL: f32_positive_fimm1:
+; LA64:       # %bb.0:
+; LA64-NEXT:    addi.w $a0, $zero, 1
+; LA64-NEXT:    movgr2fr.w $fa0, $a0
+; LA64-NEXT:    ffint.s.w $fa0, $fa0
+; LA64-NEXT:    jirl $zero, $ra, 0
+  ret float 1.0
+}


        


More information about the llvm-commits mailing list