1; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff \ 2; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s \ 3; RUN: --check-prefix=CHECK64 4; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff \ 5; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s \ 6; RUN: --check-prefix=CHECK32 7; RUN: llc -verify-machineinstrs -mtriple powerpc64le-unknown-linux \ 8; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s \ 9; RUN: --check-prefix=LINUX64LE 10; RUN: llc -verify-machineinstrs -mtriple powerpc64-unknown-linux \ 11; RUN: -ppc-asm-full-reg-names < %s | FileCheck %s \ 12; RUN: --check-prefix=LINUX64BE 13 14@.str = private unnamed_addr constant [47 x i8] c"TLS variable 1, 2 and non-TLS var: %s, %s, %s\0A\00", align 1 15@a = internal thread_local constant [5 x i8] c"tls1\00", align 1 16@b = internal thread_local constant [5 x i8] c"tls2\00", align 1 17@c = internal constant [15 x i8] c"Regular global\00", align 1 18@d = internal constant [10 x i32] [i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10], align 4 19@e = internal constant [4 x float] [float 0x4055F33340000000, float 0x4056333340000000, float 0x40567999A0000000, float 0x4056B33340000000], align 4 20 21declare noundef signext i32 @printf(ptr nocapture noundef readonly, ...) local_unnamed_addr #0 22declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) #1 23declare void @callee(ptr noundef) local_unnamed_addr #3 24declare void @callee2(ptr noundef) local_unnamed_addr #3 25 26define void @print_tls_func() { 27; CHECK64-LABEL: print_tls_func: 28; CHECK64: # %bb.0: # %entry 29; CHECK64-NEXT: mflr r0 30; CHECK64-NEXT: stdu r1, -112(r1) 31; CHECK64-NEXT: ld r3, L..C0(r2) # target-flags(ppc-tlsldm) @"_$TLSML" 32; CHECK64-NEXT: std r0, 128(r1) 33; CHECK64-NEXT: ld r6, L..C1(r2) # @_MergedGlobals 34; CHECK64-NEXT: bla .__tls_get_mod[PR] 35; CHECK64-NEXT: ld r4, L..C2(r2) # target-flags(ppc-tlsld) @a 36; CHECK64-NEXT: ld r5, L..C3(r2) # target-flags(ppc-tlsld) @b 37; CHECK64-NEXT: add r4, r3, r4 38; CHECK64-NEXT: add r5, r3, r5 39; CHECK64-NEXT: addi r3, r6, 72 40; CHECK64-NEXT: bl .printf[PR] 41; CHECK64-NEXT: nop 42; CHECK64-NEXT: addi r1, r1, 112 43; CHECK64-NEXT: ld r0, 16(r1) 44; CHECK64-NEXT: mtlr r0 45; CHECK64-NEXT: blr 46; 47; CHECK32-LABEL: print_tls_func: 48; CHECK32: # %bb.0: # %entry 49; CHECK32-NEXT: mflr r0 50; CHECK32-NEXT: stwu r1, -64(r1) 51; CHECK32-NEXT: lwz r3, L..C0(r2) # target-flags(ppc-tlsldm) @"_$TLSML" 52; CHECK32-NEXT: stw r0, 72(r1) 53; CHECK32-NEXT: lwz r6, L..C1(r2) # @_MergedGlobals 54; CHECK32-NEXT: bla .__tls_get_mod[PR] 55; CHECK32-NEXT: lwz r4, L..C2(r2) # target-flags(ppc-tlsld) @a 56; CHECK32-NEXT: lwz r5, L..C3(r2) # target-flags(ppc-tlsld) @b 57; CHECK32-NEXT: add r4, r3, r4 58; CHECK32-NEXT: add r5, r3, r5 59; CHECK32-NEXT: addi r3, r6, 72 60; CHECK32-NEXT: bl .printf[PR] 61; CHECK32-NEXT: nop 62; CHECK32-NEXT: addi r1, r1, 64 63; CHECK32-NEXT: lwz r0, 8(r1) 64; CHECK32-NEXT: mtlr r0 65; CHECK32-NEXT: blr 66; 67; LINUX64LE-LABEL: print_tls_func: 68; LINUX64LE: # %bb.0: # %entry 69; LINUX64LE-NEXT: mflr r0 70; LINUX64LE-NEXT: stdu r1, -96(r1) 71; LINUX64LE-NEXT: std r0, 112(r1) 72; LINUX64LE-NEXT: .cfi_def_cfa_offset 96 73; LINUX64LE-NEXT: .cfi_offset lr, 16 74; LINUX64LE-NEXT: addis r3, r13, a@tprel@ha 75; LINUX64LE-NEXT: addi r4, r3, a@tprel@l 76; LINUX64LE-NEXT: addis r3, r13, b@tprel@ha 77; LINUX64LE-NEXT: addi r5, r3, b@tprel@l 78; LINUX64LE-NEXT: addis r3, r2, .L_MergedGlobals@toc@ha 79; LINUX64LE-NEXT: addi r6, r3, .L_MergedGlobals@toc@l 80; LINUX64LE-NEXT: addi r3, r6, 72 81; LINUX64LE-NEXT: bl printf 82; LINUX64LE-NEXT: nop 83; LINUX64LE-NEXT: addi r1, r1, 96 84; LINUX64LE-NEXT: ld r0, 16(r1) 85; LINUX64LE-NEXT: mtlr r0 86; LINUX64LE-NEXT: blr 87; 88; LINUX64BE-LABEL: print_tls_func: 89; LINUX64BE: # %bb.0: # %entry 90; LINUX64BE-NEXT: mflr r0 91; LINUX64BE-NEXT: stdu r1, -128(r1) 92; LINUX64BE-NEXT: std r0, 144(r1) 93; LINUX64BE-NEXT: .cfi_def_cfa_offset 128 94; LINUX64BE-NEXT: .cfi_offset lr, 16 95; LINUX64BE-NEXT: .cfi_offset r30, -16 96; LINUX64BE-NEXT: addis r3, r2, a@got@tlsld@ha 97; LINUX64BE-NEXT: std r30, 112(r1) # 8-byte Folded Spill 98; LINUX64BE-NEXT: addi r3, r3, a@got@tlsld@l 99; LINUX64BE-NEXT: bl __tls_get_addr(a@tlsld) 100; LINUX64BE-NEXT: nop 101; LINUX64BE-NEXT: addis r4, r2, b@got@tlsld@ha 102; LINUX64BE-NEXT: addis r3, r3, a@dtprel@ha 103; LINUX64BE-NEXT: addi r30, r3, a@dtprel@l 104; LINUX64BE-NEXT: addi r3, r4, b@got@tlsld@l 105; LINUX64BE-NEXT: bl __tls_get_addr(b@tlsld) 106; LINUX64BE-NEXT: nop 107; LINUX64BE-NEXT: addis r3, r3, b@dtprel@ha 108; LINUX64BE-NEXT: mr r4, r30 109; LINUX64BE-NEXT: addi r5, r3, b@dtprel@l 110; LINUX64BE-NEXT: addis r3, r2, .L_MergedGlobals@toc@ha 111; LINUX64BE-NEXT: addi r6, r3, .L_MergedGlobals@toc@l 112; LINUX64BE-NEXT: addi r3, r6, 72 113; LINUX64BE-NEXT: bl printf 114; LINUX64BE-NEXT: nop 115; LINUX64BE-NEXT: ld r30, 112(r1) # 8-byte Folded Reload 116; LINUX64BE-NEXT: addi r1, r1, 128 117; LINUX64BE-NEXT: ld r0, 16(r1) 118; LINUX64BE-NEXT: mtlr r0 119; LINUX64BE-NEXT: blr 120entry: 121 %0 = tail call align 1 ptr @llvm.threadlocal.address.p0(ptr align 1 @a) 122 %1 = tail call align 1 ptr @llvm.threadlocal.address.p0(ptr align 1 @b) 123 %call = tail call signext i32 (ptr, ...) @printf(ptr noundef nonnull dereferenceable(1) @.str, ptr noundef nonnull %0, ptr noundef nonnull %1, ptr noundef nonnull @c) 124 ret void 125} 126 127define void @test_func() { 128; CHECK64-LABEL: test_func: 129; CHECK64: # %bb.0: # %entry 130; CHECK64-NEXT: mflr r0 131; CHECK64-NEXT: stdu r1, -112(r1) 132; CHECK64-NEXT: ld r3, L..C1(r2) # @_MergedGlobals 133; CHECK64-NEXT: std r0, 128(r1) 134; CHECK64-NEXT: addi r3, r3, 32 135; CHECK64-NEXT: bl .callee[PR] 136; CHECK64-NEXT: nop 137; CHECK64-NEXT: addi r1, r1, 112 138; CHECK64-NEXT: ld r0, 16(r1) 139; CHECK64-NEXT: mtlr r0 140; CHECK64-NEXT: blr 141; 142; CHECK32-LABEL: test_func: 143; CHECK32: # %bb.0: # %entry 144; CHECK32-NEXT: mflr r0 145; CHECK32-NEXT: stwu r1, -64(r1) 146; CHECK32-NEXT: lwz r3, L..C1(r2) # @_MergedGlobals 147; CHECK32-NEXT: stw r0, 72(r1) 148; CHECK32-NEXT: addi r3, r3, 32 149; CHECK32-NEXT: bl .callee[PR] 150; CHECK32-NEXT: nop 151; CHECK32-NEXT: addi r1, r1, 64 152; CHECK32-NEXT: lwz r0, 8(r1) 153; CHECK32-NEXT: mtlr r0 154; CHECK32-NEXT: blr 155 156; LINUX64LE-LABEL: test_func: 157; LINUX64LE: # %bb.0: # %entry 158; LINUX64LE-NEXT: mflr r0 159; LINUX64LE-NEXT: stdu r1, -32(r1) 160; LINUX64LE-NEXT: std r0, 48(r1) 161; LINUX64LE-NEXT: .cfi_def_cfa_offset 32 162; LINUX64LE-NEXT: .cfi_offset lr, 16 163; LINUX64LE-NEXT: addis r3, r2, .L_MergedGlobals@toc@ha 164; LINUX64LE-NEXT: addi r3, r3, .L_MergedGlobals@toc@l 165; LINUX64LE-NEXT: addi r3, r3, 32 166; LINUX64LE-NEXT: bl callee 167; LINUX64LE-NEXT: nop 168; LINUX64LE-NEXT: addi r1, r1, 32 169; LINUX64LE-NEXT: ld r0, 16(r1) 170; LINUX64LE-NEXT: mtlr r0 171; LINUX64LE-NEXT: blr 172; 173; LINUX64BE-LABEL: test_func: 174; LINUX64BE: # %bb.0: # %entry 175; LINUX64BE-NEXT: mflr r0 176; LINUX64BE-NEXT: stdu r1, -112(r1) 177; LINUX64BE-NEXT: std r0, 128(r1) 178; LINUX64BE-NEXT: .cfi_def_cfa_offset 112 179; LINUX64BE-NEXT: .cfi_offset lr, 16 180; LINUX64BE-NEXT: addis r3, r2, .L_MergedGlobals@toc@ha 181; LINUX64BE-NEXT: addi r3, r3, .L_MergedGlobals@toc@l 182; LINUX64BE-NEXT: addi r3, r3, 32 183; LINUX64BE-NEXT: bl callee 184; LINUX64BE-NEXT: nop 185; LINUX64BE-NEXT: addi r1, r1, 112 186; LINUX64BE-NEXT: ld r0, 16(r1) 187; LINUX64BE-NEXT: mtlr r0 188; LINUX64BE-NEXT: blr 189entry: 190 tail call void @callee(ptr noundef nonnull @d) #4 191 ret void 192} 193 194define void @test_func2() { 195; CHECK64-LABEL: test_func2: 196; CHECK64: # %bb.0: # %entry 197; CHECK64-NEXT: mflr r0 198; CHECK64-NEXT: stdu r1, -112(r1) 199; CHECK64-NEXT: ld r3, L..C1(r2) # @_MergedGlobals 200; CHECK64-NEXT: std r0, 128(r1) 201; CHECK64-NEXT: addi r3, r3, 16 202; CHECK64-NEXT: bl .callee2[PR] 203; CHECK64-NEXT: nop 204; CHECK64-NEXT: addi r1, r1, 112 205; CHECK64-NEXT: ld r0, 16(r1) 206; CHECK64-NEXT: mtlr r0 207; CHECK64-NEXT: blr 208; 209; CHECK32-LABEL: test_func2: 210; CHECK32: # %bb.0: # %entry 211; CHECK32-NEXT: mflr r0 212; CHECK32-NEXT: stwu r1, -64(r1) 213; CHECK32-NEXT: lwz r3, L..C1(r2) # @_MergedGlobals 214; CHECK32-NEXT: stw r0, 72(r1) 215; CHECK32-NEXT: addi r3, r3, 16 216; CHECK32-NEXT: bl .callee2[PR] 217; CHECK32-NEXT: nop 218; CHECK32-NEXT: addi r1, r1, 64 219; CHECK32-NEXT: lwz r0, 8(r1) 220; CHECK32-NEXT: mtlr r0 221; CHECK32-NEXT: blr 222; 223; LINUX64LE-LABEL: test_func2: 224; LINUX64LE: # %bb.0: # %entry 225; LINUX64LE-NEXT: mflr r0 226; LINUX64LE-NEXT: stdu r1, -32(r1) 227; LINUX64LE-NEXT: std r0, 48(r1) 228; LINUX64LE-NEXT: .cfi_def_cfa_offset 32 229; LINUX64LE-NEXT: .cfi_offset lr, 16 230; LINUX64LE-NEXT: addis r3, r2, .L_MergedGlobals@toc@ha 231; LINUX64LE-NEXT: addi r3, r3, .L_MergedGlobals@toc@l 232; LINUX64LE-NEXT: addi r3, r3, 16 233; LINUX64LE-NEXT: bl callee2 234; LINUX64LE-NEXT: nop 235; LINUX64LE-NEXT: addi r1, r1, 32 236; LINUX64LE-NEXT: ld r0, 16(r1) 237; LINUX64LE-NEXT: mtlr r0 238; LINUX64LE-NEXT: blr 239; 240; LINUX64BE-LABEL: test_func2: 241; LINUX64BE: # %bb.0: # %entry 242; LINUX64BE-NEXT: mflr r0 243; LINUX64BE-NEXT: stdu r1, -112(r1) 244; LINUX64BE-NEXT: std r0, 128(r1) 245; LINUX64BE-NEXT: .cfi_def_cfa_offset 112 246; LINUX64BE-NEXT: .cfi_offset lr, 16 247; LINUX64BE-NEXT: addis r3, r2, .L_MergedGlobals@toc@ha 248; LINUX64BE-NEXT: addi r3, r3, .L_MergedGlobals@toc@l 249; LINUX64BE-NEXT: addi r3, r3, 16 250; LINUX64BE-NEXT: bl callee2 251; LINUX64BE-NEXT: nop 252; LINUX64BE-NEXT: addi r1, r1, 112 253; LINUX64BE-NEXT: ld r0, 16(r1) 254; LINUX64BE-NEXT: mtlr r0 255; LINUX64BE-NEXT: blr 256entry: 257 tail call void @callee2(ptr noundef nonnull @e) #4 258 ret void 259} 260 261; Check the contents of the TLS data and the _MergedGlobals structure to 262; check that TLS data has been skipped during global merge. 263 264; CHECK64: .csect a[TL],2 265; CHECK64-NEXT: .lglobl a[TL] 266; CHECK64-NEXT: .string "tls1" 267; CHECK64: .csect b[TL],2 268; CHECK64-NEXT: .lglobl b[TL] 269; CHECK64-NEXT: .string "tls2" 270; CHECK64: .csect L.._MergedGlobals[RO],2 271; CHECK64: .align 2 272; CHECK64-LABEL: c: 273; CHECK64: .string "Regular global" 274; CHECK64-LABEL: e: 275; CHECK64: .vbyte 4, 0x42af999a 276; CHECK64-NEXT: .vbyte 4, 0x42b1999a 277; CHECK64-NEXT: .vbyte 4, 0x42b3cccd 278; CHECK64-NEXT: .vbyte 4, 0x42b5999a 279; CHECK64-LABEL: d: 280; CHECK64: .vbyte 4, 1 281; CHECK64-NEXT: .vbyte 4, 2 282; CHECK64-NEXT: .vbyte 4, 3 283; CHECK64-NEXT: .vbyte 4, 4 284; CHECK64-NEXT: .vbyte 4, 5 285; CHECK64-NEXT: .vbyte 4, 6 286; CHECK64-NEXT: .vbyte 4, 7 287; CHECK64-NEXT: .vbyte 4, 8 288; CHECK64-NEXT: .vbyte 4, 9 289; CHECK64-NEXT: .vbyte 4, 10 290; CHECK64-LABEL: L...str 291; CHECK64: .byte 'T,'L,'S,' ,'v,'a,'r,'i,'a,'b,'l,'e,' ,'1,',,' ,'2,' ,'a,'n,'d,' ,'n,'o,'n,'-,'T,'L,'S,' ,'v,'a,'r,':,' ,'%,'s,',,' ,'%,'s,',,' ,'%,'s,0012,0000 292; CHECK64: L..C1: 293; CHECK64-NEXT: .tc L.._MergedGlobals[TC],L.._MergedGlobals[RO] 294; CHECK64: L..C2: 295; CHECK64-NEXT: .tc a[TC],a[TL]@ld 296; CHECK64: L..C3: 297; CHECK64-NEXT: .tc b[TC],b[TL]@ld 298 299; CHECK32: .csect a[TL],2 300; CHECK32-NEXT: .lglobl a[TL] 301; CHECK32-NEXT: .string "tls1" 302; CHECK32: .csect b[TL],2 303; CHECK32-NEXT: .lglobl b[TL] 304; CHECK32-NEXT: .string "tls2" 305; CHECK32: .csect L.._MergedGlobals[RO],2 306; CHECK32: .align 2 307; CHECK32-LABEL: c: 308; CHECK32: .string "Regular global" 309; CHECK32-LABEL: e: 310; CHECK32: .vbyte 4, 0x42af999a 311; CHECK32-NEXT: .vbyte 4, 0x42b1999a 312; CHECK32-NEXT: .vbyte 4, 0x42b3cccd 313; CHECK32-NEXT: .vbyte 4, 0x42b5999a 314; CHECK32-LABEL: d: 315; CHECK32: .vbyte 4, 1 316; CHECK32-NEXT: .vbyte 4, 2 317; CHECK32-NEXT: .vbyte 4, 3 318; CHECK32-NEXT: .vbyte 4, 4 319; CHECK32-NEXT: .vbyte 4, 5 320; CHECK32-NEXT: .vbyte 4, 6 321; CHECK32-NEXT: .vbyte 4, 7 322; CHECK32-NEXT: .vbyte 4, 8 323; CHECK32-NEXT: .vbyte 4, 9 324; CHECK32-NEXT: .vbyte 4, 10 325; CHECK32-LABEL: L...str: 326; CHECK32: .byte 'T,'L,'S,' ,'v,'a,'r,'i,'a,'b,'l,'e,' ,'1,',,' ,'2,' ,'a,'n,'d,' ,'n,'o,'n,'-,'T,'L,'S,' ,'v,'a,'r,':,' ,'%,'s,',,' ,'%,'s,',,' ,'%,'s,0012,0000 327; CHECK32: L..C1: 328; CHECK32-NEXT: .tc L.._MergedGlobals[TC],L.._MergedGlobals[RO] 329; CHECK32: L..C2: 330; CHECK32-NEXT: .tc a[TC],a[TL]@ld 331; CHECK32: L..C3: 332; CHECK32-NEXT: .tc b[TC],b[TL]@ld 333 334; LINUX64LE: a: 335; LINUX64LE-NEXT: .asciz "tls1" 336; LINUX64LE-NEXT: .size a, 5 337; LINUX64LE: b: 338; LINUX64LE-NEXT: .asciz "tls2" 339; LINUX64LE-NEXT: .size b, 5 340; LINUX64LE: .L_MergedGlobals: 341; LINUX64LE-NEXT: .asciz "Regular global" 342; LINUX64LE-NEXT: .space 1 343; LINUX64LE-NEXT: .long 0x42af999a 344; LINUX64LE-NEXT: .long 0x42b1999a 345; LINUX64LE-NEXT: .long 0x42b3cccd 346; LINUX64LE-NEXT: .long 0x42b5999a 347; LINUX64LE-NEXT: .long 1 348; LINUX64LE-NEXT: .long 2 349; LINUX64LE-NEXT: .long 3 350; LINUX64LE-NEXT: .long 4 351; LINUX64LE-NEXT: .long 5 352; LINUX64LE-NEXT: .long 6 353; LINUX64LE-NEXT: .long 7 354; LINUX64LE-NEXT: .long 8 355; LINUX64LE-NEXT: .long 9 356; LINUX64LE-NEXT: .long 10 357; LINUX64LE-NEXT: .asciz "TLS variable 1, 2 and non-TLS var: %s, %s, %s\n" 358 359; LINUX64BE: a: 360; LINUX64BE-NEXT: .asciz "tls1" 361; LINUX64BE-NEXT: .size a, 5 362; LINUX64BE: b: 363; LINUX64BE-NEXT: .asciz "tls2" 364; LINUX64BE-NEXT: .size b, 5 365; LINUX64BE: .L_MergedGlobals: 366; LINUX64BE-NEXT: .asciz "Regular global" 367; LINUX64BE-NEXT: .space 1 368; LINUX64BE-NEXT: .long 0x42af999a 369; LINUX64BE-NEXT: .long 0x42b1999a 370; LINUX64BE-NEXT: .long 0x42b3cccd 371; LINUX64BE-NEXT: .long 0x42b5999a 372; LINUX64BE-NEXT: .long 1 373; LINUX64BE-NEXT: .long 2 374; LINUX64BE-NEXT: .long 3 375; LINUX64BE-NEXT: .long 4 376; LINUX64BE-NEXT: .long 5 377; LINUX64BE-NEXT: .long 6 378; LINUX64BE-NEXT: .long 7 379; LINUX64BE-NEXT: .long 8 380; LINUX64BE-NEXT: .long 9 381; LINUX64BE-NEXT: .long 10 382; LINUX64BE-NEXT: .asciz "TLS variable 1, 2 and non-TLS var: %s, %s, %s\n" 383