[llvm] [LoongArch] Modify expanding code sequence for PseudoLA_TLS_LE (PR #119696)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 12 04:50:39 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-loongarch
Author: ZhaoQi (zhaoqi5)
<details>
<summary>Changes</summary>
Before this commit, PseudoLA_TLS_LE for normal/medium code model expand normally to:
```
lu12i.w $rd, %le_hi20(sym)
ori $rd, $rd, %le_lo12(sym)
```
This commit changes the result to:
```
lu12i.w $rd, %le_hi20_r(sym)
add.w/d $rd, $rd, $tp, %le_add_r(sym)
addi.w/d $rd, $rd, %le_lo12_r(sym)
```
This aims to be optimized by linker relaxation in the future.
This commit makes no change to PseudoLA_TLS_LE in large code model.
---
Full diff: https://github.com/llvm/llvm-project/pull/119696.diff
9 Files Affected:
- (modified) llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp (+28-11)
- (modified) llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp (+8-5)
- (modified) llvm/lib/Target/LoongArch/LoongArchISelLowering.h (+2-1)
- (modified) llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp (+4-1)
- (modified) llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp (+9)
- (modified) llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h (+3)
- (modified) llvm/test/CodeGen/LoongArch/machinelicm-address-pseudos.ll (+7-6)
- (modified) llvm/test/CodeGen/LoongArch/mir-target-flags.ll (+3-2)
- (modified) llvm/test/CodeGen/LoongArch/tls-models.ll (+18-18)
``````````diff
diff --git a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
index 30742c79653b52..0218934ea3344a 100644
--- a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
@@ -352,11 +352,13 @@ bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLE(
MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
MachineBasicBlock::iterator &NextMBBI) {
// Code Sequence:
+ // lu12i.w $rd, %le_hi20_r(sym)
+ // add.w/d $rd, $rd, $tp, %le_add_r(sym)
+ // addi.w/d $rd, $rd, %le_lo12_r(sym)
+ //
+ // Code Sequence while using the large code model:
// lu12i.w $rd, %le_hi20(sym)
// ori $rd, $rd, %le_lo12(sym)
- //
- // And additionally if generating code using the large code model:
- //
// lu32i.d $rd, %le64_lo20(sym)
// lu52i.d $rd, $rd, %le64_hi12(sym)
MachineFunction *MF = MBB.getParent();
@@ -366,20 +368,35 @@ bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLE(
bool Large = MF->getTarget().getCodeModel() == CodeModel::Large;
Register DestReg = MI.getOperand(0).getReg();
Register Parts01 =
- Large ? MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass)
- : DestReg;
+ MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass);
Register Part1 =
MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass);
MachineOperand &Symbol = MI.getOperand(1);
- BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU12I_W), Part1)
- .addDisp(Symbol, 0, LoongArchII::MO_LE_HI);
+ if (!Large) {
+ BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU12I_W), Part1)
+ .addDisp(Symbol, 0, LoongArchII::MO_LE_HI_R);
- BuildMI(MBB, MBBI, DL, TII->get(LoongArch::ORI), Parts01)
- .addReg(Part1, RegState::Kill)
- .addDisp(Symbol, 0, LoongArchII::MO_LE_LO);
+ const auto &STI = MF->getSubtarget<LoongArchSubtarget>();
+ unsigned AddOp = STI.is64Bit() ? LoongArch::PseudoAddTPRel_D
+ : LoongArch::PseudoAddTPRel_W;
+ BuildMI(MBB, MBBI, DL, TII->get(AddOp), Parts01)
+ .addReg(Part1, RegState::Kill)
+ .addReg(LoongArch::R2)
+ .addDisp(Symbol, 0, LoongArchII::MO_LE_ADD_R);
+
+ unsigned AddiOp = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
+ BuildMI(MBB, MBBI, DL, TII->get(AddiOp), DestReg)
+ .addReg(Parts01, RegState::Kill)
+ .addDisp(Symbol, 0, LoongArchII::MO_LE_LO_R);
+ } else {
+ BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU12I_W), Part1)
+ .addDisp(Symbol, 0, LoongArchII::MO_LE_HI);
+
+ BuildMI(MBB, MBBI, DL, TII->get(LoongArch::ORI), Parts01)
+ .addReg(Part1, RegState::Kill)
+ .addDisp(Symbol, 0, LoongArchII::MO_LE_LO);
- if (Large) {
Register Parts012 =
MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass);
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 43f76373b7919b..9829be625c8b7b 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -1804,10 +1804,9 @@ SDValue LoongArchTargetLowering::lowerGlobalAddress(SDValue Op,
return getAddr(N, DAG, CM, GV->isDSOLocal());
}
-SDValue LoongArchTargetLowering::getStaticTLSAddr(GlobalAddressSDNode *N,
- SelectionDAG &DAG,
- unsigned Opc, bool UseGOT,
- bool Large) const {
+SDValue LoongArchTargetLowering::getStaticTLSAddr(
+ GlobalAddressSDNode *N, SelectionDAG &DAG, unsigned Opc, bool UseGOT,
+ bool Large, bool IsNormalOrMediumLE) const {
SDLoc DL(N);
EVT Ty = getPointerTy(DAG.getDataLayout());
MVT GRLenVT = Subtarget.getGRLenVT();
@@ -1819,6 +1818,10 @@ SDValue LoongArchTargetLowering::getStaticTLSAddr(GlobalAddressSDNode *N,
SDValue Offset = Large
? SDValue(DAG.getMachineNode(Opc, DL, Ty, Tmp, Addr), 0)
: SDValue(DAG.getMachineNode(Opc, DL, Ty, Addr), 0);
+
+ if (IsNormalOrMediumLE)
+ return Offset;
+
if (UseGOT) {
// Mark the load instruction as invariant to enable hoisting in MachineLICM.
MachineFunction &MF = DAG.getMachineFunction();
@@ -1939,7 +1942,7 @@ LoongArchTargetLowering::lowerGlobalTLSAddress(SDValue Op,
//
// This node doesn't need an extra argument for the large code model.
return getStaticTLSAddr(N, DAG, LoongArch::PseudoLA_TLS_LE,
- /*UseGOT=*/false);
+ /*UseGOT=*/false, /*Large=*/false, !Large);
}
return getTLSDescAddr(N, DAG,
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
index e6de0dc4e361a2..c7e4cb90bb109a 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
@@ -301,7 +301,8 @@ class LoongArchTargetLowering : public TargetLowering {
SDValue getAddr(NodeTy *N, SelectionDAG &DAG, CodeModel::Model M,
bool IsLocal = true) const;
SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
- unsigned Opc, bool UseGOT, bool Large = false) const;
+ unsigned Opc, bool UseGOT, bool Large = false,
+ bool IsNormalOrMediumLE = false) const;
SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
unsigned Opc, bool Large = false) const;
SDValue getTLSDescAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
index 363cacf726c9ce..7d0e4f9d58a16d 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
@@ -651,7 +651,10 @@ LoongArchInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
{MO_DESC_LD, "loongarch-desc-ld"},
{MO_DESC_CALL, "loongarch-desc-call"},
{MO_LD_PC_HI, "loongarch-ld-pc-hi"},
- {MO_GD_PC_HI, "loongarch-gd-pc-hi"}};
+ {MO_GD_PC_HI, "loongarch-gd-pc-hi"},
+ {MO_LE_HI_R, "loongarch-le-hi-r"},
+ {MO_LE_ADD_R, "loongarch-le-add-r"},
+ {MO_LE_LO_R, "loongarch-le-lo-r"}};
return ArrayRef(TargetFlags);
}
diff --git a/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp b/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
index 2bacc1273343ef..d1de0609f24ce2 100644
--- a/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
@@ -114,6 +114,15 @@ static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym,
case LoongArchII::MO_DESC_CALL:
Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC_CALL;
break;
+ case LoongArchII::MO_LE_HI_R:
+ Kind = LoongArchMCExpr::VK_LoongArch_TLS_LE_HI20_R;
+ break;
+ case LoongArchII::MO_LE_ADD_R:
+ Kind = LoongArchMCExpr::VK_LoongArch_TLS_LE_ADD_R;
+ break;
+ case LoongArchII::MO_LE_LO_R:
+ Kind = LoongArchMCExpr::VK_LoongArch_TLS_LE_LO12_R;
+ break;
// TODO: Handle more target-flags.
}
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h
index bd63c5edeabca7..23699043b9926a 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h
@@ -54,6 +54,9 @@ enum {
MO_DESC64_PC_LO,
MO_DESC_LD,
MO_DESC_CALL,
+ MO_LE_HI_R,
+ MO_LE_ADD_R,
+ MO_LE_LO_R,
// TODO: Add more flags.
};
diff --git a/llvm/test/CodeGen/LoongArch/machinelicm-address-pseudos.ll b/llvm/test/CodeGen/LoongArch/machinelicm-address-pseudos.ll
index fc0c7ad1686ee8..e0a93e3051bf88 100644
--- a/llvm/test/CodeGen/LoongArch/machinelicm-address-pseudos.ll
+++ b/llvm/test/CodeGen/LoongArch/machinelicm-address-pseudos.ll
@@ -315,9 +315,9 @@ define void @test_la_tls_le(i32 signext %n) {
; LA32-LABEL: test_la_tls_le:
; LA32: # %bb.0: # %entry
; LA32-NEXT: move $a1, $zero
-; LA32-NEXT: lu12i.w $a2, %le_hi20(le)
-; LA32-NEXT: ori $a2, $a2, %le_lo12(le)
-; LA32-NEXT: add.w $a2, $a2, $tp
+; LA32-NEXT: lu12i.w $a2, %le_hi20_r(le)
+; LA32-NEXT: add.w $a2, $a2, $tp, %le_add_r(le)
+; LA32-NEXT: addi.w $a2, $a2, %le_lo12_r(le)
; LA32-NEXT: .p2align 4, , 16
; LA32-NEXT: .LBB4_1: # %loop
; LA32-NEXT: # =>This Inner Loop Header: Depth=1
@@ -330,12 +330,13 @@ define void @test_la_tls_le(i32 signext %n) {
; LA64-LABEL: test_la_tls_le:
; LA64: # %bb.0: # %entry
; LA64-NEXT: move $a1, $zero
-; LA64-NEXT: lu12i.w $a2, %le_hi20(le)
-; LA64-NEXT: ori $a2, $a2, %le_lo12(le)
+; LA64-NEXT: lu12i.w $a2, %le_hi20_r(le)
+; LA64-NEXT: add.d $a2, $a2, $tp, %le_add_r(le)
+; LA64-NEXT: addi.d $a2, $a2, %le_lo12_r(le)
; LA64-NEXT: .p2align 4, , 16
; LA64-NEXT: .LBB4_1: # %loop
; LA64-NEXT: # =>This Inner Loop Header: Depth=1
-; LA64-NEXT: ldx.w $zero, $a2, $tp
+; LA64-NEXT: ld.w $zero, $a2, 0
; LA64-NEXT: addi.w $a1, $a1, 1
; LA64-NEXT: blt $a1, $a0, .LBB4_1
; LA64-NEXT: # %bb.2: # %ret
diff --git a/llvm/test/CodeGen/LoongArch/mir-target-flags.ll b/llvm/test/CodeGen/LoongArch/mir-target-flags.ll
index f530e3ef237c1b..3bc8a8d3095868 100644
--- a/llvm/test/CodeGen/LoongArch/mir-target-flags.ll
+++ b/llvm/test/CodeGen/LoongArch/mir-target-flags.ll
@@ -28,8 +28,9 @@ define void @caller() nounwind {
; CHECK-NEXT: target-flags(loongarch-got-pc-lo) @t_ld
; CHECK: target-flags(loongarch-ie-pc-hi) @t_ie
; CHECK-NEXT: target-flags(loongarch-ie-pc-lo) @t_ie
-; CHECK: target-flags(loongarch-le-hi) @t_le
-; CHECK-NEXT: target-flags(loongarch-le-lo) @t_le
+; CHECK: target-flags(loongarch-le-hi-r) @t_le
+; CHECK-NEXT: target-flags(loongarch-le-add-r) @t_le
+; CHECK-NEXT: target-flags(loongarch-le-lo-r) @t_le
; CHECK: target-flags(loongarch-call-plt) @callee1
; CHECK: target-flags(loongarch-call) @callee2
%a = load volatile i32, ptr @g_e
diff --git a/llvm/test/CodeGen/LoongArch/tls-models.ll b/llvm/test/CodeGen/LoongArch/tls-models.ll
index dbd7bf6a81269c..e3a8ace3bc7e35 100644
--- a/llvm/test/CodeGen/LoongArch/tls-models.ll
+++ b/llvm/test/CodeGen/LoongArch/tls-models.ll
@@ -330,16 +330,16 @@ entry:
define ptr @f4() nounwind {
; LA32PIC-LABEL: f4:
; LA32PIC: # %bb.0: # %entry
-; LA32PIC-NEXT: lu12i.w $a0, %le_hi20(le)
-; LA32PIC-NEXT: ori $a0, $a0, %le_lo12(le)
-; LA32PIC-NEXT: add.w $a0, $a0, $tp
+; LA32PIC-NEXT: lu12i.w $a0, %le_hi20_r(le)
+; LA32PIC-NEXT: add.w $a0, $a0, $tp, %le_add_r(le)
+; LA32PIC-NEXT: addi.w $a0, $a0, %le_lo12_r(le)
; LA32PIC-NEXT: ret
;
; LA64PIC-LABEL: f4:
; LA64PIC: # %bb.0: # %entry
-; LA64PIC-NEXT: lu12i.w $a0, %le_hi20(le)
-; LA64PIC-NEXT: ori $a0, $a0, %le_lo12(le)
-; LA64PIC-NEXT: add.d $a0, $a0, $tp
+; LA64PIC-NEXT: lu12i.w $a0, %le_hi20_r(le)
+; LA64PIC-NEXT: add.d $a0, $a0, $tp, %le_add_r(le)
+; LA64PIC-NEXT: addi.d $a0, $a0, %le_lo12_r(le)
; LA64PIC-NEXT: ret
;
; LA64LARGEPIC-LABEL: f4:
@@ -353,16 +353,16 @@ define ptr @f4() nounwind {
;
; LA32NOPIC-LABEL: f4:
; LA32NOPIC: # %bb.0: # %entry
-; LA32NOPIC-NEXT: lu12i.w $a0, %le_hi20(le)
-; LA32NOPIC-NEXT: ori $a0, $a0, %le_lo12(le)
-; LA32NOPIC-NEXT: add.w $a0, $a0, $tp
+; LA32NOPIC-NEXT: lu12i.w $a0, %le_hi20_r(le)
+; LA32NOPIC-NEXT: add.w $a0, $a0, $tp, %le_add_r(le)
+; LA32NOPIC-NEXT: addi.w $a0, $a0, %le_lo12_r(le)
; LA32NOPIC-NEXT: ret
;
; LA64NOPIC-LABEL: f4:
; LA64NOPIC: # %bb.0: # %entry
-; LA64NOPIC-NEXT: lu12i.w $a0, %le_hi20(le)
-; LA64NOPIC-NEXT: ori $a0, $a0, %le_lo12(le)
-; LA64NOPIC-NEXT: add.d $a0, $a0, $tp
+; LA64NOPIC-NEXT: lu12i.w $a0, %le_hi20_r(le)
+; LA64NOPIC-NEXT: add.d $a0, $a0, $tp, %le_add_r(le)
+; LA64NOPIC-NEXT: addi.d $a0, $a0, %le_lo12_r(le)
; LA64NOPIC-NEXT: ret
;
; LA64LARGENOPIC-LABEL: f4:
@@ -376,16 +376,16 @@ define ptr @f4() nounwind {
;
; LA32DESC-LABEL: f4:
; LA32DESC: # %bb.0: # %entry
-; LA32DESC-NEXT: lu12i.w $a0, %le_hi20(le)
-; LA32DESC-NEXT: ori $a0, $a0, %le_lo12(le)
-; LA32DESC-NEXT: add.w $a0, $a0, $tp
+; LA32DESC-NEXT: lu12i.w $a0, %le_hi20_r(le)
+; LA32DESC-NEXT: add.w $a0, $a0, $tp, %le_add_r(le)
+; LA32DESC-NEXT: addi.w $a0, $a0, %le_lo12_r(le)
; LA32DESC-NEXT: ret
;
; LA64DESC-LABEL: f4:
; LA64DESC: # %bb.0: # %entry
-; LA64DESC-NEXT: lu12i.w $a0, %le_hi20(le)
-; LA64DESC-NEXT: ori $a0, $a0, %le_lo12(le)
-; LA64DESC-NEXT: add.d $a0, $a0, $tp
+; LA64DESC-NEXT: lu12i.w $a0, %le_hi20_r(le)
+; LA64DESC-NEXT: add.d $a0, $a0, $tp, %le_add_r(le)
+; LA64DESC-NEXT: addi.d $a0, $a0, %le_lo12_r(le)
; LA64DESC-NEXT: ret
;
; DESC64-LABEL: f4:
``````````
</details>
https://github.com/llvm/llvm-project/pull/119696
More information about the llvm-commits
mailing list