Skip to content

Commit 16094cb

Browse files
authored
[llvm][LoongArch] Support per-global code model attribute for LoongArch (llvm#72079)
This patch gets the code model from global variable attribute if it has, otherwise the target's will be used. --------- Signed-off-by: WANG Rui <[email protected]>
1 parent 241e4c7 commit 16094cb

File tree

3 files changed

+63
-6
lines changed

3 files changed

+63
-6
lines changed

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -762,12 +762,13 @@ static SDValue getTargetNode(JumpTableSDNode *N, SDLoc DL, EVT Ty,
762762

763763
template <class NodeTy>
764764
SDValue LoongArchTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
765+
CodeModel::Model M,
765766
bool IsLocal) const {
766767
SDLoc DL(N);
767768
EVT Ty = getPointerTy(DAG.getDataLayout());
768769
SDValue Addr = getTargetNode(N, DL, Ty, DAG, 0);
769770

770-
switch (DAG.getTarget().getCodeModel()) {
771+
switch (M) {
771772
default:
772773
report_fatal_error("Unsupported code model");
773774

@@ -808,24 +809,35 @@ SDValue LoongArchTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
808809

809810
SDValue LoongArchTargetLowering::lowerBlockAddress(SDValue Op,
810811
SelectionDAG &DAG) const {
811-
return getAddr(cast<BlockAddressSDNode>(Op), DAG);
812+
return getAddr(cast<BlockAddressSDNode>(Op), DAG,
813+
DAG.getTarget().getCodeModel());
812814
}
813815

814816
SDValue LoongArchTargetLowering::lowerJumpTable(SDValue Op,
815817
SelectionDAG &DAG) const {
816-
return getAddr(cast<JumpTableSDNode>(Op), DAG);
818+
return getAddr(cast<JumpTableSDNode>(Op), DAG,
819+
DAG.getTarget().getCodeModel());
817820
}
818821

819822
SDValue LoongArchTargetLowering::lowerConstantPool(SDValue Op,
820823
SelectionDAG &DAG) const {
821-
return getAddr(cast<ConstantPoolSDNode>(Op), DAG);
824+
return getAddr(cast<ConstantPoolSDNode>(Op), DAG,
825+
DAG.getTarget().getCodeModel());
822826
}
823827

824828
SDValue LoongArchTargetLowering::lowerGlobalAddress(SDValue Op,
825829
SelectionDAG &DAG) const {
826830
GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
827831
assert(N->getOffset() == 0 && "unexpected offset in global node");
828-
return getAddr(N, DAG, N->getGlobal()->isDSOLocal());
832+
auto CM = DAG.getTarget().getCodeModel();
833+
const GlobalValue *GV = N->getGlobal();
834+
835+
if (GV->isDSOLocal() && isa<GlobalVariable>(GV)) {
836+
if (auto GCM = dyn_cast<GlobalVariable>(GV)->getCodeModel())
837+
CM = *GCM;
838+
}
839+
840+
return getAddr(N, DAG, CM, GV->isDSOLocal());
829841
}
830842

831843
SDValue LoongArchTargetLowering::getStaticTLSAddr(GlobalAddressSDNode *N,

llvm/lib/Target/LoongArch/LoongArchISelLowering.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,8 @@ class LoongArchTargetLowering : public TargetLowering {
254254
LoongArchCCAssignFn Fn) const;
255255

256256
template <class NodeTy>
257-
SDValue getAddr(NodeTy *N, SelectionDAG &DAG, bool IsLocal = true) const;
257+
SDValue getAddr(NodeTy *N, SelectionDAG &DAG, CodeModel::Model M,
258+
bool IsLocal = true) const;
258259
SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
259260
unsigned Opc, bool Large = false) const;
260261
SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s
3+
4+
@a= external dso_local global i32, code_model "small", align 4
5+
6+
define dso_local signext i32 @local_small() #0 {
7+
; CHECK-LABEL: local_small:
8+
; CHECK: # %bb.0:
9+
; CHECK-NEXT: pcalau12i $a0, %pc_hi20(a)
10+
; CHECK-NEXT: addi.d $a0, $a0, %pc_lo12(a)
11+
; CHECK-NEXT: ld.w $a0, $a0, 0
12+
; CHECK-NEXT: ret
13+
%1 = load i32, ptr @a, align 4
14+
ret i32 %1
15+
}
16+
17+
@b= external dso_local global i32, code_model "large", align 4
18+
19+
define dso_local signext i32 @local_large() #0 {
20+
; CHECK-LABEL: local_large:
21+
; CHECK: # %bb.0:
22+
; CHECK-NEXT: pcalau12i $a0, %pc_hi20(b)
23+
; CHECK-NEXT: addi.d $t8, $zero, %pc_lo12(b)
24+
; CHECK-NEXT: lu32i.d $t8, %pc64_lo20(b)
25+
; CHECK-NEXT: lu52i.d $t8, $t8, %pc64_hi12(b)
26+
; CHECK-NEXT: add.d $a0, $t8, $a0
27+
; CHECK-NEXT: ld.w $a0, $a0, 0
28+
; CHECK-NEXT: ret
29+
%1 = load i32, ptr @b, align 4
30+
ret i32 %1
31+
}
32+
33+
@c= external global i32, code_model "large", align 4
34+
35+
define dso_local signext i32 @non_local_large() #0 {
36+
; CHECK-LABEL: non_local_large:
37+
; CHECK: # %bb.0:
38+
; CHECK-NEXT: pcalau12i $a0, %got_pc_hi20(c)
39+
; CHECK-NEXT: ld.d $a0, $a0, %got_pc_lo12(c)
40+
; CHECK-NEXT: ld.w $a0, $a0, 0
41+
; CHECK-NEXT: ret
42+
%1 = load i32, ptr @c, align 4
43+
ret i32 %1
44+
}

0 commit comments

Comments
 (0)