@@ -785,6 +785,7 @@ SDValue LoongArchTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
785785 SDLoc DL (N);
786786 EVT Ty = getPointerTy (DAG.getDataLayout ());
787787 SDValue Addr = getTargetNode (N, DL, Ty, DAG, 0 );
788+ SDValue Load;
788789
789790 switch (M) {
790791 default :
@@ -796,33 +797,49 @@ SDValue LoongArchTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
796797 // This is not actually used, but is necessary for successfully matching
797798 // the PseudoLA_*_LARGE nodes.
798799 SDValue Tmp = DAG.getConstant (0 , DL, Ty);
799- if (IsLocal)
800+ if (IsLocal) {
800801 // This generates the pattern (PseudoLA_PCREL_LARGE tmp sym), that
801802 // eventually becomes the desired 5-insn code sequence.
802- return SDValue (DAG.getMachineNode (LoongArch::PseudoLA_PCREL_LARGE, DL, Ty,
803+ Load = SDValue (DAG.getMachineNode (LoongArch::PseudoLA_PCREL_LARGE, DL, Ty,
803804 Tmp, Addr),
804805 0 );
805-
806- // This generates the pattern (PseudoLA_GOT_LARGE tmp sym), that eventually
807- // becomes the desired 5-insn code sequence.
808- return SDValue (
809- DAG.getMachineNode (LoongArch::PseudoLA_GOT_LARGE, DL, Ty, Tmp, Addr),
810- 0 );
806+ } else {
807+ // This generates the pattern (PseudoLA_GOT_LARGE tmp sym), that
808+ // eventually becomes the desired 5-insn code sequence.
809+ Load = SDValue (
810+ DAG.getMachineNode (LoongArch::PseudoLA_GOT_LARGE, DL, Ty, Tmp, Addr),
811+ 0 );
812+ }
813+ break ;
811814 }
812815
813816 case CodeModel::Small:
814817 case CodeModel::Medium:
815- if (IsLocal)
818+ if (IsLocal) {
816819 // This generates the pattern (PseudoLA_PCREL sym), which expands to
817820 // (addi.w/d (pcalau12i %pc_hi20(sym)) %pc_lo12(sym)).
818- return SDValue (
821+ Load = SDValue (
819822 DAG.getMachineNode (LoongArch::PseudoLA_PCREL, DL, Ty, Addr), 0 );
823+ } else {
824+ // This generates the pattern (PseudoLA_GOT sym), which expands to (ld.w/d
825+ // (pcalau12i %got_pc_hi20(sym)) %got_pc_lo12(sym)).
826+ Load =
827+ SDValue (DAG.getMachineNode (LoongArch::PseudoLA_GOT, DL, Ty, Addr), 0 );
828+ }
829+ }
820830
821- // This generates the pattern (PseudoLA_GOT sym), which expands to (ld.w/d
822- // (pcalau12i %got_pc_hi20(sym)) %got_pc_lo12(sym)).
823- return SDValue (DAG.getMachineNode (LoongArch::PseudoLA_GOT, DL, Ty, Addr),
824- 0 );
831+ if (!IsLocal) {
832+ // Mark the load instruction as invariant to enable hoisting in MachineLICM.
833+ MachineFunction &MF = DAG.getMachineFunction ();
834+ MachineMemOperand *MemOp = MF.getMachineMemOperand (
835+ MachinePointerInfo::getGOT (MF),
836+ MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable |
837+ MachineMemOperand::MOInvariant,
838+ LLT (Ty.getSimpleVT ()), Align (Ty.getFixedSizeInBits () / 8 ));
839+ DAG.setNodeMemRefs (cast<MachineSDNode>(Load.getNode ()), {MemOp});
825840 }
841+
842+ return Load;
826843}
827844
828845SDValue LoongArchTargetLowering::lowerBlockAddress (SDValue Op,
@@ -860,7 +877,7 @@ SDValue LoongArchTargetLowering::lowerGlobalAddress(SDValue Op,
860877
861878SDValue LoongArchTargetLowering::getStaticTLSAddr (GlobalAddressSDNode *N,
862879 SelectionDAG &DAG,
863- unsigned Opc,
880+ unsigned Opc, bool UseGOT,
864881 bool Large) const {
865882 SDLoc DL (N);
866883 EVT Ty = getPointerTy (DAG.getDataLayout ());
@@ -873,6 +890,16 @@ SDValue LoongArchTargetLowering::getStaticTLSAddr(GlobalAddressSDNode *N,
873890 SDValue Offset = Large
874891 ? SDValue (DAG.getMachineNode (Opc, DL, Ty, Tmp, Addr), 0 )
875892 : SDValue (DAG.getMachineNode (Opc, DL, Ty, Addr), 0 );
893+ if (UseGOT) {
894+ // Mark the load instruction as invariant to enable hoisting in MachineLICM.
895+ MachineFunction &MF = DAG.getMachineFunction ();
896+ MachineMemOperand *MemOp = MF.getMachineMemOperand (
897+ MachinePointerInfo::getGOT (MF),
898+ MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable |
899+ MachineMemOperand::MOInvariant,
900+ LLT (Ty.getSimpleVT ()), Align (Ty.getFixedSizeInBits () / 8 ));
901+ DAG.setNodeMemRefs (cast<MachineSDNode>(Offset.getNode ()), {MemOp});
902+ }
876903
877904 // Add the thread pointer.
878905 return DAG.getNode (ISD::ADD, DL, Ty, Offset,
@@ -976,13 +1003,14 @@ LoongArchTargetLowering::lowerGlobalTLSAddress(SDValue Op,
9761003 return getStaticTLSAddr (N, DAG,
9771004 Large ? LoongArch::PseudoLA_TLS_IE_LARGE
9781005 : LoongArch::PseudoLA_TLS_IE,
979- Large);
1006+ /* UseGOT= */ true , Large);
9801007 case TLSModel::LocalExec:
9811008 // This model is used when static linking as the TLS offsets are resolved
9821009 // during program linking.
9831010 //
9841011 // This node doesn't need an extra argument for the large code model.
985- return getStaticTLSAddr (N, DAG, LoongArch::PseudoLA_TLS_LE);
1012+ return getStaticTLSAddr (N, DAG, LoongArch::PseudoLA_TLS_LE,
1013+ /* UseGOT=*/ false );
9861014 }
9871015
9881016 return getTLSDescAddr (N, DAG,
0 commit comments