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