• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -relocation-model=pic < %s \
3; RUN:     | FileCheck -check-prefix=RV32-PIC %s
4; RUN: llc -mtriple=riscv64 -relocation-model=pic < %s \
5; RUN:     | FileCheck -check-prefix=RV64-PIC %s
6; RUN: llc -mtriple=riscv32 < %s | FileCheck -check-prefix=RV32-NOPIC %s
7; RUN: llc -mtriple=riscv64 < %s | FileCheck -check-prefix=RV64-NOPIC %s
8
9; Check that TLS symbols are lowered correctly based on the specified
10; model. Make sure they're external to avoid them all being optimised to Local
11; Exec for the executable.
12
13@unspecified = external thread_local global i32
14@ld = external thread_local(localdynamic) global i32
15@ie = external thread_local(initialexec) global i32
16@le = external thread_local(localexec) global i32
17
18
19; No model specified
20
21define i32* @f1() nounwind {
22; RV32-PIC-LABEL: f1:
23; RV32-PIC:       # %bb.0: # %entry
24; RV32-PIC-NEXT:    addi sp, sp, -16
25; RV32-PIC-NEXT:    sw ra, 12(sp)
26; RV32-PIC-NEXT:  .LBB0_1: # %entry
27; RV32-PIC-NEXT:    # Label of block must be emitted
28; RV32-PIC-NEXT:    auipc a0, %tls_gd_pcrel_hi(unspecified)
29; RV32-PIC-NEXT:    addi a0, a0, %pcrel_lo(.LBB0_1)
30; RV32-PIC-NEXT:    call __tls_get_addr@plt
31; RV32-PIC-NEXT:    lw ra, 12(sp)
32; RV32-PIC-NEXT:    addi sp, sp, 16
33; RV32-PIC-NEXT:    ret
34;
35; RV64-PIC-LABEL: f1:
36; RV64-PIC:       # %bb.0: # %entry
37; RV64-PIC-NEXT:    addi sp, sp, -16
38; RV64-PIC-NEXT:    sd ra, 8(sp)
39; RV64-PIC-NEXT:  .LBB0_1: # %entry
40; RV64-PIC-NEXT:    # Label of block must be emitted
41; RV64-PIC-NEXT:    auipc a0, %tls_gd_pcrel_hi(unspecified)
42; RV64-PIC-NEXT:    addi a0, a0, %pcrel_lo(.LBB0_1)
43; RV64-PIC-NEXT:    call __tls_get_addr@plt
44; RV64-PIC-NEXT:    ld ra, 8(sp)
45; RV64-PIC-NEXT:    addi sp, sp, 16
46; RV64-PIC-NEXT:    ret
47;
48; RV32-NOPIC-LABEL: f1:
49; RV32-NOPIC:       # %bb.0: # %entry
50; RV32-NOPIC-NEXT:  .LBB0_1: # %entry
51; RV32-NOPIC-NEXT:    # Label of block must be emitted
52; RV32-NOPIC-NEXT:    auipc a0, %tls_ie_pcrel_hi(unspecified)
53; RV32-NOPIC-NEXT:    lw a0, %pcrel_lo(.LBB0_1)(a0)
54; RV32-NOPIC-NEXT:    add a0, a0, tp
55; RV32-NOPIC-NEXT:    ret
56;
57; RV64-NOPIC-LABEL: f1:
58; RV64-NOPIC:       # %bb.0: # %entry
59; RV64-NOPIC-NEXT:  .LBB0_1: # %entry
60; RV64-NOPIC-NEXT:    # Label of block must be emitted
61; RV64-NOPIC-NEXT:    auipc a0, %tls_ie_pcrel_hi(unspecified)
62; RV64-NOPIC-NEXT:    ld a0, %pcrel_lo(.LBB0_1)(a0)
63; RV64-NOPIC-NEXT:    add a0, a0, tp
64; RV64-NOPIC-NEXT:    ret
65entry:
66  ret i32* @unspecified
67}
68
69
70; localdynamic specified
71
72define i32* @f2() nounwind {
73; RV32-PIC-LABEL: f2:
74; RV32-PIC:       # %bb.0: # %entry
75; RV32-PIC-NEXT:    addi sp, sp, -16
76; RV32-PIC-NEXT:    sw ra, 12(sp)
77; RV32-PIC-NEXT:  .LBB1_1: # %entry
78; RV32-PIC-NEXT:    # Label of block must be emitted
79; RV32-PIC-NEXT:    auipc a0, %tls_gd_pcrel_hi(ld)
80; RV32-PIC-NEXT:    addi a0, a0, %pcrel_lo(.LBB1_1)
81; RV32-PIC-NEXT:    call __tls_get_addr@plt
82; RV32-PIC-NEXT:    lw ra, 12(sp)
83; RV32-PIC-NEXT:    addi sp, sp, 16
84; RV32-PIC-NEXT:    ret
85;
86; RV64-PIC-LABEL: f2:
87; RV64-PIC:       # %bb.0: # %entry
88; RV64-PIC-NEXT:    addi sp, sp, -16
89; RV64-PIC-NEXT:    sd ra, 8(sp)
90; RV64-PIC-NEXT:  .LBB1_1: # %entry
91; RV64-PIC-NEXT:    # Label of block must be emitted
92; RV64-PIC-NEXT:    auipc a0, %tls_gd_pcrel_hi(ld)
93; RV64-PIC-NEXT:    addi a0, a0, %pcrel_lo(.LBB1_1)
94; RV64-PIC-NEXT:    call __tls_get_addr@plt
95; RV64-PIC-NEXT:    ld ra, 8(sp)
96; RV64-PIC-NEXT:    addi sp, sp, 16
97; RV64-PIC-NEXT:    ret
98;
99; RV32-NOPIC-LABEL: f2:
100; RV32-NOPIC:       # %bb.0: # %entry
101; RV32-NOPIC-NEXT:  .LBB1_1: # %entry
102; RV32-NOPIC-NEXT:    # Label of block must be emitted
103; RV32-NOPIC-NEXT:    auipc a0, %tls_ie_pcrel_hi(ld)
104; RV32-NOPIC-NEXT:    lw a0, %pcrel_lo(.LBB1_1)(a0)
105; RV32-NOPIC-NEXT:    add a0, a0, tp
106; RV32-NOPIC-NEXT:    ret
107;
108; RV64-NOPIC-LABEL: f2:
109; RV64-NOPIC:       # %bb.0: # %entry
110; RV64-NOPIC-NEXT:  .LBB1_1: # %entry
111; RV64-NOPIC-NEXT:    # Label of block must be emitted
112; RV64-NOPIC-NEXT:    auipc a0, %tls_ie_pcrel_hi(ld)
113; RV64-NOPIC-NEXT:    ld a0, %pcrel_lo(.LBB1_1)(a0)
114; RV64-NOPIC-NEXT:    add a0, a0, tp
115; RV64-NOPIC-NEXT:    ret
116entry:
117  ret i32* @ld
118}
119
120
121; initialexec specified
122
123define i32* @f3() nounwind {
124; RV32-PIC-LABEL: f3:
125; RV32-PIC:       # %bb.0: # %entry
126; RV32-PIC-NEXT:  .LBB2_1: # %entry
127; RV32-PIC-NEXT:    # Label of block must be emitted
128; RV32-PIC-NEXT:    auipc a0, %tls_ie_pcrel_hi(ie)
129; RV32-PIC-NEXT:    lw a0, %pcrel_lo(.LBB2_1)(a0)
130; RV32-PIC-NEXT:    add a0, a0, tp
131; RV32-PIC-NEXT:    ret
132;
133; RV64-PIC-LABEL: f3:
134; RV64-PIC:       # %bb.0: # %entry
135; RV64-PIC-NEXT:  .LBB2_1: # %entry
136; RV64-PIC-NEXT:    # Label of block must be emitted
137; RV64-PIC-NEXT:    auipc a0, %tls_ie_pcrel_hi(ie)
138; RV64-PIC-NEXT:    ld a0, %pcrel_lo(.LBB2_1)(a0)
139; RV64-PIC-NEXT:    add a0, a0, tp
140; RV64-PIC-NEXT:    ret
141;
142; RV32-NOPIC-LABEL: f3:
143; RV32-NOPIC:       # %bb.0: # %entry
144; RV32-NOPIC-NEXT:  .LBB2_1: # %entry
145; RV32-NOPIC-NEXT:    # Label of block must be emitted
146; RV32-NOPIC-NEXT:    auipc a0, %tls_ie_pcrel_hi(ie)
147; RV32-NOPIC-NEXT:    lw a0, %pcrel_lo(.LBB2_1)(a0)
148; RV32-NOPIC-NEXT:    add a0, a0, tp
149; RV32-NOPIC-NEXT:    ret
150;
151; RV64-NOPIC-LABEL: f3:
152; RV64-NOPIC:       # %bb.0: # %entry
153; RV64-NOPIC-NEXT:  .LBB2_1: # %entry
154; RV64-NOPIC-NEXT:    # Label of block must be emitted
155; RV64-NOPIC-NEXT:    auipc a0, %tls_ie_pcrel_hi(ie)
156; RV64-NOPIC-NEXT:    ld a0, %pcrel_lo(.LBB2_1)(a0)
157; RV64-NOPIC-NEXT:    add a0, a0, tp
158; RV64-NOPIC-NEXT:    ret
159entry:
160  ret i32* @ie
161}
162
163
164; localexec specified
165
166define i32* @f4() nounwind {
167; RV32-PIC-LABEL: f4:
168; RV32-PIC:       # %bb.0: # %entry
169; RV32-PIC-NEXT:    lui a0, %tprel_hi(le)
170; RV32-PIC-NEXT:    add a0, a0, tp, %tprel_add(le)
171; RV32-PIC-NEXT:    addi a0, a0, %tprel_lo(le)
172; RV32-PIC-NEXT:    ret
173;
174; RV64-PIC-LABEL: f4:
175; RV64-PIC:       # %bb.0: # %entry
176; RV64-PIC-NEXT:    lui a0, %tprel_hi(le)
177; RV64-PIC-NEXT:    add a0, a0, tp, %tprel_add(le)
178; RV64-PIC-NEXT:    addi a0, a0, %tprel_lo(le)
179; RV64-PIC-NEXT:    ret
180;
181; RV32-NOPIC-LABEL: f4:
182; RV32-NOPIC:       # %bb.0: # %entry
183; RV32-NOPIC-NEXT:    lui a0, %tprel_hi(le)
184; RV32-NOPIC-NEXT:    add a0, a0, tp, %tprel_add(le)
185; RV32-NOPIC-NEXT:    addi a0, a0, %tprel_lo(le)
186; RV32-NOPIC-NEXT:    ret
187;
188; RV64-NOPIC-LABEL: f4:
189; RV64-NOPIC:       # %bb.0: # %entry
190; RV64-NOPIC-NEXT:    lui a0, %tprel_hi(le)
191; RV64-NOPIC-NEXT:    add a0, a0, tp, %tprel_add(le)
192; RV64-NOPIC-NEXT:    addi a0, a0, %tprel_lo(le)
193; RV64-NOPIC-NEXT:    ret
194entry:
195  ret i32* @le
196}
197