[llvm] [MIPS] Support MIPS I hard-float double loads/stores with LWC1/SWC1 (PR #209362)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 13 20:48:15 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-mips

Author: yingopq

<details>
<summary>Changes</summary>

MIPS I lacks LDC1/SDC1. This patch implements double precision loads/stores using LWC1/SWC1 instructions.

* Add BuildPairF64_FPR and ExtractElementF64_FPR nodes
* Use them in lowerLOAD/lowerSTORE for MIPS I hard-float
* Avoid redundant mtc1/mfc1 instructions

Matches GCC behavior for MIPS I hard-float.

Fix #<!-- -->62190.

---
Full diff: https://github.com/llvm/llvm-project/pull/209362.diff


10 Files Affected:

- (modified) llvm/lib/Target/Mips/MipsInstrFPU.td (+24-4) 
- (modified) llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp (+27) 
- (modified) llvm/lib/Target/Mips/MipsSEISelLowering.cpp (+22-12) 
- (modified) llvm/lib/Target/Mips/MipsSEInstrInfo.cpp (+4) 
- (modified) llvm/lib/Target/Mips/MipsScheduleGeneric.td (+2-1) 
- (modified) llvm/lib/Target/Mips/MipsScheduleP5600.td (+2-2) 
- (modified) llvm/test/CodeGen/Mips/llvm-ir/load.ll (+12-4) 
- (modified) llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll (+2-1) 
- (modified) llvm/test/CodeGen/Mips/mips1-load-in-delay-slot.ll (+1-2) 
- (added) llvm/test/CodeGen/Mips/mips1-not-support-ldc1-sdc1.ll (+49) 


``````````diff
diff --git a/llvm/lib/Target/Mips/MipsInstrFPU.td b/llvm/lib/Target/Mips/MipsInstrFPU.td
index 7dcebff2406fc..37defa45161db 100644
--- a/llvm/lib/Target/Mips/MipsInstrFPU.td
+++ b/llvm/lib/Target/Mips/MipsInstrFPU.td
@@ -34,9 +34,15 @@ def SDT_MipsTruncIntFP : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>;
 def SDT_MipsBuildPairF64 : SDTypeProfile<1, 2, [SDTCisVT<0, f64>,
                                                 SDTCisVT<1, i32>,
                                                 SDTCisSameAs<1, 2>]>;
+def SDT_MipsBuildPairF64_FPR : SDTypeProfile<1, 2, [SDTCisVT<0, f64>,
+                                                SDTCisVT<1, f32>,
+                                                SDTCisSameAs<1, 2>]>;
 def SDT_MipsExtractElementF64 : SDTypeProfile<1, 2, [SDTCisVT<0, i32>,
                                                      SDTCisVT<1, f64>,
                                                      SDTCisVT<2, i32>]>;
+def SDT_MipsExtractElementF64_FPR : SDTypeProfile<1, 2, [SDTCisVT<0, f32>,
+                                                     SDTCisVT<1, f64>,
+                                                     SDTCisVT<2, i32>]>;
 
 def SDT_MipsMTC1_D64 : SDTypeProfile<1, 1, [SDTCisVT<0, f64>,
                                             SDTCisVT<1, i32>]>;
@@ -57,8 +63,12 @@ def MipsTruncIntFP : SDNode<"MipsISD::TruncIntFP", SDT_MipsTruncIntFP>;
 
 def MipsBuildPairF64 : SDNode<"MipsISD::BuildPairF64", SDT_MipsBuildPairF64>;
 def : GINodeEquiv<G_MERGE_VALUES, MipsBuildPairF64>;
+def MipsBuildPairF64_FPR : SDNode<"MipsISD::BuildPairF64_FPR", SDT_MipsBuildPairF64_FPR>;
+def : GINodeEquiv<G_MERGE_VALUES, MipsBuildPairF64_FPR>;
 def MipsExtractElementF64 : SDNode<"MipsISD::ExtractElementF64",
                                    SDT_MipsExtractElementF64>;
+def MipsExtractElementF64_FPR : SDNode<"MipsISD::ExtractElementF64_FPR",
+                                   SDT_MipsExtractElementF64_FPR>;
 
 // Node used to generate an MTC1 i32 to f64 instruction
 def MipsMTC1_D64 : SDNode<"MipsISD::MTC1_D64", SDT_MipsMTC1_D64>;
@@ -836,7 +846,12 @@ class BuildPairF64Base<RegisterOperand RO> :
   PseudoSE<(outs RO:$dst), (ins GPR32Opnd:$lo, GPR32Opnd:$hi),
            [(set RO:$dst, (MipsBuildPairF64 GPR32Opnd:$lo, GPR32Opnd:$hi))]>;
 
+class BuildPairF64Base_FPR<RegisterOperand RO> :
+  PseudoSE<(outs RO:$dst), (ins FGR32Opnd:$lo, FGR32Opnd:$hi),
+           [(set RO:$dst, (MipsBuildPairF64_FPR FGR32Opnd:$lo, FGR32Opnd:$hi))]>;
+
 def BuildPairF64 : BuildPairF64Base<AFGR64Opnd>, FGR_32, HARDFLOAT;
+def BuildPairF64_FPR : BuildPairF64Base_FPR<AFGR64Opnd>, FGR_32, HARDFLOAT;
 def BuildPairF64_64 : BuildPairF64Base<FGR64Opnd>, FGR_64, HARDFLOAT;
 
 // This pseudo instr gets expanded into 2 mfc1 instrs after register
@@ -849,7 +864,12 @@ class ExtractElementF64Base<RegisterOperand RO> :
   PseudoSE<(outs GPR32Opnd:$dst), (ins RO:$src, i32imm:$n),
            [(set GPR32Opnd:$dst, (MipsExtractElementF64 RO:$src, imm:$n))]>;
 
+class ExtractElementF64Base_FPR<RegisterOperand RO> :
+  PseudoSE<(outs FGR32Opnd:$dst), (ins RO:$src, i32imm:$n),
+           [(set FGR32Opnd:$dst, (MipsExtractElementF64_FPR RO:$src, imm:$n))]>;
+
 def ExtractElementF64 : ExtractElementF64Base<AFGR64Opnd>, FGR_32, HARDFLOAT;
+def ExtractElementF64_FPR : ExtractElementF64Base_FPR<AFGR64Opnd>, FGR_32, HARDFLOAT;
 def ExtractElementF64_64 : ExtractElementF64Base<FGR64Opnd>, FGR_64, HARDFLOAT;
 
 def PseudoTRUNC_W_S : MipsAsmPseudoInst<(outs FGR32Opnd:$fd),
@@ -1090,10 +1110,10 @@ let AdditionalPredicates = [NotInMicroMips] in {
     def : LoadRegImmPat<LWC1, f32, load>, ISA_MIPS1;
     def : StoreRegImmPat<SWC1, f32>, ISA_MIPS1;
 
-    def : LoadRegImmPat<LDC164, f64, load>, ISA_MIPS1, FGR_64;
-    def : StoreRegImmPat<SDC164, f64>, ISA_MIPS1, FGR_64;
+    def : LoadRegImmPat<LDC164, f64, load>, ISA_MIPS2, FGR_64;
+    def : StoreRegImmPat<SDC164, f64>, ISA_MIPS2, FGR_64;
 
-    def : LoadRegImmPat<LDC1, f64, load>, ISA_MIPS1, FGR_32;
-    def : StoreRegImmPat<SDC1, f64>, ISA_MIPS1, FGR_32;
+    def : LoadRegImmPat<LDC1, f64, load>, ISA_MIPS2, FGR_32;
+    def : StoreRegImmPat<SDC1, f64>, ISA_MIPS2, FGR_32;
   }
 }
diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
index 8c60824a42a26..7276c139d27af 100644
--- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
@@ -297,6 +297,33 @@ bool MipsSEDAGToDAGISel::selectAddrFrameIndexOffset(
 
       Offset = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr),
                                          ValTy);
+      if (Base.getOpcode() == ISD::ADD &&
+          (Subtarget->hasMips1() && !Subtarget->hasMips2())) {
+        // Instead of:
+        //  lui $2, %hi($CPI1_0)
+        //  addiu $2, $2, %lo($CPI1_0)
+        //  lwc1 $f0, 4($2)
+        // Generate:
+        //  lui $2, %hi($CPI1_0)
+        //  lwc1 $f0, %lo($CPI1_0+4)($2)
+        if (Base.getOperand(1).getOpcode() == MipsISD::Lo ||
+            Base.getOperand(1).getOpcode() == MipsISD::GPRel) {
+          SDValue Opnd0 = Base.getOperand(1).getOperand(0);
+          if (isa<ConstantPoolSDNode>(Opnd0) ||
+              isa<GlobalAddressSDNode>(Opnd0) || isa<JumpTableSDNode>(Opnd0)) {
+            Base = Base.getOperand(0);
+            if (GlobalAddressSDNode *GA =
+                    dyn_cast<GlobalAddressSDNode>(Opnd0)) {
+              const GlobalValue *GV = GA->getGlobal();
+              int64_t GAOffset = GA->getOffset();
+              Offset = CurDAG->getTargetGlobalAddress(
+                  GV, SDLoc(Addr), MVT::i32, GAOffset + CN->getZExtValue(),
+                  MipsII::MO_ABS_LO);
+              return true;
+            }
+          }
+        }
+      }
       return true;
     }
   }
diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
index d5941fc8e0b33..d4cf259313a1d 100644
--- a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
@@ -248,7 +248,7 @@ MipsSETargetLowering::MipsSETargetLowering(const MipsTargetMachine &TM,
     setOperationAction(ISD::BITCAST, MVT::i64, Custom);
   }
 
-  if (NoDPLoadStore) {
+  if (NoDPLoadStore || (Subtarget.hasMips1() && !Subtarget.hasMips2())) {
     setOperationAction(ISD::LOAD, MVT::f64, Custom);
     setOperationAction(ISD::STORE, MVT::f64, Custom);
   }
@@ -1357,28 +1357,34 @@ getOpndList(SmallVectorImpl<SDValue> &Ops,
 SDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {
   LoadSDNode &Nd = *cast<LoadSDNode>(Op);
 
-  if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
+  if (Nd.getMemoryVT() != MVT::f64 || (!NoDPLoadStore && Subtarget.hasMips2()))
     return MipsTargetLowering::lowerLOAD(Op, DAG);
 
   // Replace a double precision load with two i32 loads and a buildpair64.
   SDLoc DL(Op);
   SDValue Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
   EVT PtrVT = Ptr.getValueType();
+  EVT VT = Subtarget.hasMips2() ? MVT::i32 : MVT::f32;
 
   // i32 load from lower address.
-  SDValue Lo = DAG.getLoad(MVT::i32, DL, Chain, Ptr, MachinePointerInfo(),
+  SDValue Lo = DAG.getLoad(VT, DL, Chain, Ptr, MachinePointerInfo(),
                            Nd.getAlign(), Nd.getMemOperand()->getFlags());
 
   // i32 load from higher address.
   Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, DL, PtrVT));
-  SDValue Hi = DAG.getLoad(
-      MVT::i32, DL, Lo.getValue(1), Ptr, MachinePointerInfo(),
-      commonAlignment(Nd.getAlign(), 4), Nd.getMemOperand()->getFlags());
+  SDValue Hi = DAG.getLoad(VT, DL, Lo.getValue(1), Ptr, MachinePointerInfo(),
+                           commonAlignment(Nd.getAlign(), 4),
+                           Nd.getMemOperand()->getFlags());
 
   if (!Subtarget.isLittle())
     std::swap(Lo, Hi);
 
-  SDValue BP = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
+  SDValue BP;
+  if (Subtarget.hasMips2())
+    BP = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
+  else
+    BP = DAG.getNode(MipsISD::BuildPairF64_FPR, DL, MVT::f64, Hi, Lo);
+
   SDValue Ops[2] = {BP, Hi.getValue(1)};
   return DAG.getMergeValues(Ops, DL);
 }
@@ -1386,17 +1392,21 @@ SDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {
 SDValue MipsSETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {
   StoreSDNode &Nd = *cast<StoreSDNode>(Op);
 
-  if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore)
+  if (Nd.getMemoryVT() != MVT::f64 || (!NoDPLoadStore && Subtarget.hasMips2()))
     return MipsTargetLowering::lowerSTORE(Op, DAG);
 
   // Replace a double precision store with two extractelement64s and i32 stores.
   SDLoc DL(Op);
   SDValue Val = Nd.getValue(), Ptr = Nd.getBasePtr(), Chain = Nd.getChain();
   EVT PtrVT = Ptr.getValueType();
-  SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
-                           Val, DAG.getConstant(0, DL, MVT::i32));
-  SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,
-                           Val, DAG.getConstant(1, DL, MVT::i32));
+  EVT VT = Subtarget.hasMips2() ? MVT::i32 : MVT::f32;
+
+  unsigned ExtractOp = Subtarget.hasMips2() ? MipsISD::ExtractElementF64
+                                            : MipsISD::ExtractElementF64_FPR;
+  SDValue Lo =
+      DAG.getNode(ExtractOp, DL, VT, Val, DAG.getConstant(0, DL, MVT::i32));
+  SDValue Hi =
+      DAG.getNode(ExtractOp, DL, VT, Val, DAG.getConstant(1, DL, MVT::i32));
 
   if (!Subtarget.isLittle())
     std::swap(Lo, Hi);
diff --git a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
index 6c59975a1b501..e31f5f5009200 100644
--- a/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsSEInstrInfo.cpp
@@ -526,9 +526,13 @@ bool MipsSEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
   case Mips::BuildPairF64:
     expandBuildPairF64(MBB, MI, isMicroMips, false);
     break;
+  case Mips::BuildPairF64_FPR:
+    MI.eraseFromParent();
+    return true;
   case Mips::BuildPairF64_64:
     expandBuildPairF64(MBB, MI, isMicroMips, true);
     break;
+  case Mips::ExtractElementF64_FPR:
   case Mips::ExtractElementF64:
     expandExtractElementF64(MBB, MI, isMicroMips, false);
     break;
diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td
index d7b9a002dbc5f..233311c97d392 100644
--- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td
+++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td
@@ -870,7 +870,8 @@ def : InstRW<[GenericWriteFPUMoveGPRFPU], (instrs BuildPairF64,
                                            ExtractElementF64_64, CFC1, CTC1,
                                            MFC1, MFC1_D64, MFHC1_D32,
                                            MFHC1_D64, MTC1, MTC1_D64,
-                                           MTHC1_D32, MTHC1_D64)>;
+                                           MTHC1_D32, MTHC1_D64,
+                                           BuildPairF64_FPR, ExtractElementF64_FPR)>;
 
 // swc1, swxc1
 def : InstRW<[GenericWriteFPUStore], (instrs SDC1, SDC164, SDXC1, SDXC164,
diff --git a/llvm/lib/Target/Mips/MipsScheduleP5600.td b/llvm/lib/Target/Mips/MipsScheduleP5600.td
index e8b646a37932c..342d2fa6fdb8b 100644
--- a/llvm/lib/Target/Mips/MipsScheduleP5600.td
+++ b/llvm/lib/Target/Mips/MipsScheduleP5600.td
@@ -563,7 +563,7 @@ def P5600WriteLoadFPU : WriteSequence<[P5600WriteLoadToOtherUnits,
 // ctc1, mtc1, mthc1
 def : InstRW<[P5600WriteMoveGPRToFPU], (instrs CTC1, MTC1, MTC1_D64, MTHC1_D32,
                                         MTHC1_D64, BuildPairF64,
-                                        BuildPairF64_64)>;
+                                        BuildPairF64_64, BuildPairF64_FPR)>;
 
 // copy.[su]_[bhwd]
 def : InstRW<[P5600WriteMoveFPUToGPR], (instregex "^COPY_U_[BHW]$")>;
@@ -573,7 +573,7 @@ def : InstRW<[P5600WriteMoveFPUToGPR], (instregex "^COPY_S_[BHWD]$")>;
 def : InstRW<[P5600WriteMoveFPUToGPR], (instrs BC1F, BC1FL, BC1T, BC1TL, CFC1,
                                         MFC1, MFC1_D64, MFHC1_D32, MFHC1_D64,
                                         MOVF_I, MOVT_I, ExtractElementF64,
-                                        ExtractElementF64_64)>;
+                                        ExtractElementF64_64, ExtractElementF64_FPR)>;
 
 // swc1, swxc1, st.[bhwd]
 def : InstRW<[P5600WriteStoreFPUS], (instrs SDC1, SDC164, SDXC1, SDXC164,
diff --git a/llvm/test/CodeGen/Mips/llvm-ir/load.ll b/llvm/test/CodeGen/Mips/llvm-ir/load.ll
index 834880f1ad74e..9e47978da8c37 100644
--- a/llvm/test/CodeGen/Mips/llvm-ir/load.ll
+++ b/llvm/test/CodeGen/Mips/llvm-ir/load.ll
@@ -1664,12 +1664,20 @@ define double @f9() {
 ; MIPS1-PSX-NEXT:    lui $1, %hi(f) # <MCInst #[[#MCINST1]] LUi
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
 ; MIPS1-PSX-NEXT:    # <MCOperand Expr:%hi(f)>>
-; MIPS1-PSX-NEXT:    jr $ra # <MCInst #[[#MCINST2]] JR
-; MIPS1-PSX-NEXT:    # <MCOperand Reg:RA>>
-; MIPS1-PSX-NEXT:    ldc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST30:]] LDC1
-; MIPS1-PSX-NEXT:    # <MCOperand Reg:D0>
+; MIPS1-PSX-NEXT:    lwc1 $f0, %lo(f)($1) # <MCInst #[[#MCINST28:]] LWC1
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:F0>
 ; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
 ; MIPS1-PSX-NEXT:    # <MCOperand Expr:%lo(f)>>
+; MIPS1-PSX-NEXT:    lwc1 $f1, %lo(f+4)($1) # <MCInst #[[#MCINST28:]] LWC1
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:F1>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:AT>
+; MIPS1-PSX-NEXT:    # <MCOperand Expr:%lo(f+4)>>
+; MIPS1-PSX-NEXT:    jr	$ra # <MCInst [[#MCINST2]] JR
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:RA>>
+; MIPS1-PSX-NEXT:    nop # <MCInst #[[#MCINST13]] SLL
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Reg:ZERO>
+; MIPS1-PSX-NEXT:    # <MCOperand Imm:0>>
 entry:
   %0 = load double, ptr @f
   ret double %0
diff --git a/llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll b/llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll
index f39be636e09d4..ca91fa18ecd2c 100644
--- a/llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll
+++ b/llvm/test/CodeGen/Mips/llvm-ir/select-dbl.ll
@@ -139,7 +139,8 @@ define double @tst_select_i1_double(i1 signext %s, double %x, double %y) {
 ; MIPS1-PSX-NEXT:    bnez $1, $BB0_2
 ; MIPS1-PSX-NEXT:    nop
 ; MIPS1-PSX-NEXT:  # %bb.1: # %entry
-; MIPS1-PSX-NEXT:    ldc1 $f0, 16($sp)
+; MIPS1-PSX-NEXT:    lwc1 $f0, 16($sp)
+; MIPS1-PSX-NEXT:    lwc1 $f1, 20($sp)
 ; MIPS1-PSX-NEXT:    jr $ra
 ; MIPS1-PSX-NEXT:    nop
 ; MIPS1-PSX-NEXT:  $BB0_2:
diff --git a/llvm/test/CodeGen/Mips/mips1-load-in-delay-slot.ll b/llvm/test/CodeGen/Mips/mips1-load-in-delay-slot.ll
index 4499dc6123fd1..d0cb5601cfd86 100644
--- a/llvm/test/CodeGen/Mips/mips1-load-in-delay-slot.ll
+++ b/llvm/test/CodeGen/Mips/mips1-load-in-delay-slot.ll
@@ -11,8 +11,7 @@ define internal fastcc void @test() unnamed_addr #0 {
 ; MIPS1-PSX-NEXT:    addu $1, $2, $25
 ; MIPS1-PSX-NEXT:    lw $2, %got(data)($1)
 ; MIPS1-PSX-NEXT:    nop
-; MIPS1-PSX-NEXT:    addiu $1, $2, %lo(data)
-; MIPS1-PSX-NEXT:    lbu $1, 2($1)
+; MIPS1-PSX-NEXT:    lbu $1, %lo(data+2)($2)
 ; MIPS1-PSX-NEXT:    addiu $3, $zero, 2
 ; MIPS1-PSX-NEXT:    bne $1, $3, $BB0_2
 ; MIPS1-PSX-NEXT:    nop
diff --git a/llvm/test/CodeGen/Mips/mips1-not-support-ldc1-sdc1.ll b/llvm/test/CodeGen/Mips/mips1-not-support-ldc1-sdc1.ll
new file mode 100644
index 0000000000000..1942805530222
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/mips1-not-support-ldc1-sdc1.ll
@@ -0,0 +1,49 @@
+; RUN: llc -march=mipsel -mcpu=mips1 < %s | FileCheck %s -check-prefix=MIPS1-LE
+; RUN: llc -march=mips -mcpu=mips1 < %s | FileCheck %s -check-prefix=MIPS1-BE
+
+ at test = global double 1.000000e+00, align 8
+
+define double @test_lwc1() {
+; MIPS1-LE-LABEL: test_lwc1:
+; MIPS1-LE:       # %bb.0: # %entry
+; MIPS1-LE-NEXT:    lui	$1, %hi(test)
+; MIPS1-LE-NEXT:    lwc1 $f0, %lo(test)($1)
+; MIPS1-LE-NEXT:    lwc1 $f1, %lo(test+4)($1)
+; MIPS1-LE-NEXT:    jr $ra
+; MIPS1-LE-NEXT:    nop
+
+; MIPS1-BE-LABEL: test_lwc1:
+; MIPS1-BE:       # %bb.0: # %entry
+; MIPS1-BE-NEXT:    lui	$1, %hi(test)
+; MIPS1-BE-NEXT:    lwc1 $f0, %lo(test+4)($1)
+; MIPS1-BE-NEXT:    lwc1 $f1, %lo(test)($1)
+; MIPS1-BE-NEXT:    jr $ra
+; MIPS1-BE-NEXT:    nop
+entry:
+  %0 = load double, ptr @test, align 8
+  ret double %0
+}
+
+define void @test_swc1(double %a) #0 {
+; MIPS1-LE-LABEL: test_swc1:
+; MIPS1-LE:       # %bb.0: # %entry
+; MIPS1-LE-NEXT:    mfc1 $f0, $f13
+; MIPS1-LE-NEXT:    lui	$1, %hi(test)
+; MIPS1-LE-NEXT:    swc1 $f0, %lo(test+4)($1)
+; MIPS1-LE-NEXT:    mfc1 $f0, $f12
+; MIPS1-LE-NEXT:    jr $ra
+; MIPS1-LE-NEXT:    swc1 $f0, %lo(test)($1)
+
+; MIPS1-BE-LABEL: test_swc1:
+; MIPS1-BE:       # %bb.0: # %entry
+; MIPS1-BE-NEXT:    mfc1 $f0, $f12
+; MIPS1-BE-NEXT:    lui	$1, %hi(test)
+; MIPS1-BE-NEXT:    swc1 $f0, %lo(test+4)($1)
+; MIPS1-BE-NEXT:    mfc1 $f0, $f13
+; MIPS1-BE-NEXT:    jr $ra
+; MIPS1-BE-NEXT:    swc1 $f0, %lo(test)($1)
+entry:
+  store double %a, ptr @test, align 8
+  ret void
+}
+

``````````

</details>


https://github.com/llvm/llvm-project/pull/209362


More information about the llvm-commits mailing list