1; RUN: llc -mcpu=ppc -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs < %s \ 2; RUN: -stop-before=ppc-vsx-copy | FileCheck %s --check-prefix CHECK32 3; RUN: llc -mcpu=ppc -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs < %s \ 4; RUN: -stop-before=ppc-vsx-copy | FileCheck %s --check-prefix CHECK64 5; RUN: llc -mcpu=ppc -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs < %s | FileCheck %s --check-prefix TEST32 6; RUN: llc -mcpu=ppc -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs < %s | FileCheck %s --check-prefix TEST64 7 8; RUN: llc -mcpu=ppc -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs < %s \ 9; RUN: -stop-before=ppc-vsx-copy -O0 | FileCheck %s --check-prefix CHECK32 10; RUN: llc -mcpu=ppc -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs < %s \ 11; RUN: -stop-before=ppc-vsx-copy -O0 | FileCheck %s --check-prefix CHECK64-NOOPT 12; RUN: llc -mcpu=ppc -mtriple powerpc-ibm-aix-xcoff -verify-machineinstrs -O0 < %s | FileCheck %s --check-prefix TEST32 13; RUN: llc -mcpu=ppc -mtriple powerpc64-ibm-aix-xcoff -verify-machineinstrs -O0 < %s | FileCheck %s --check-prefix TEST64 14 15; RUN: llc -mcpu=ppc -mtriple powerpc-ibm-aix-xcoff -code-model=large -verify-machineinstrs < %s \ 16; RUN: -stop-before=ppc-vsx-copy | FileCheck %s --check-prefix CHECK32LARGE 17; RUN: llc -mcpu=ppc -mtriple powerpc-ibm-aix-xcoff -code-model=large -verify-machineinstrs < %s | FileCheck %s --check-prefix TEST32LARGE 18 19; RUN: llc -mcpu=ppc -mtriple powerpc64-ibm-aix-xcoff -code-model=large -verify-machineinstrs < %s \ 20; RUN: -stop-before=ppc-vsx-copy | FileCheck %s --check-prefix CHECK64LARGE 21; RUN: llc -mcpu=ppc -mtriple powerpc64-ibm-aix-xcoff -code-model=large -verify-machineinstrs < %s | FileCheck %s --check-prefix TEST64LARGE 22 23; Global variables i and f have the toc-data attribute. 24; In the following functions, those writing to or reading from 25; variables i and f should use the toc-data access pattern. 26; All remaining variables should use the regular toc access sequence. 27@i = dso_local global i32 0, align 4 #0 28@d = dso_local local_unnamed_addr global double 3.141590e+00, align 8 29@f = dso_local local_unnamed_addr global float 0x4005BE76C0000000, align 4 #0 30@ll = dso_local local_unnamed_addr global i64 55, align 8 31@ilocal = internal global i32 0, align 4 32 33define dso_local void @write_int(i32 signext %in) { 34 entry: 35 store i32 %in, ptr @i, align 4 36 ret void 37} 38; CHECK32: name: write_int 39; CHECK32: %[[SCRATCH:[0-9]+]]:gprc_and_gprc_nor0 = ADDItoc $r2, @i 40; CHECK32-NEXT: STW %{{[0-9]+}}, 0, killed %[[SCRATCH]] :: (store (s32) into @i) 41 42; TEST32: .write_int: 43; TEST32: la 4, i[TD](2) 44; TEST32-NEXT: stw 3, 0(4) 45 46; CHECK64: name: write_int 47; CHECK64: %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItoc8 $x2, @i 48; CHECK64-NEXT: STW8 %{{[0-9]+}}, 0, killed %[[SCRATCH]] :: (store (s32) into @i) 49 50; CHECK64-NOOPT: name: write_int 51; CHECK64-NOOPT: %[[SUBREG:[0-9]+]]:gprc = COPY %{{[0-9]}}.sub_32 52; CHECK64-NOOPT: %[[ADDR:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItoc8 $x2, @i 53; CHECK64-NOOPT: STW %[[SUBREG]], 0, %[[ADDR]] 54 55; TEST64: .write_int: 56; TEST64: la 4, i[TD](2) 57; TEST64-NEXT: stw 3, 0(4) 58 59; CHECK32LARGE: name: write_int 60; CHECK32LARGE: %[[SCRATCH1:[0-9]+]]:gprc_and_gprc_nor0 = ADDIStocHA $r2, @i 61; CHECK32LARGE-NEXT: %[[SCRATCH2:[0-9]+]]:gprc_and_gprc_nor0 = ADDItocL killed %[[SCRATCH1]], @i 62; CHECK32LARGE-NEXT: STW %{{[0-9]+}}, 0, killed %[[SCRATCH2]] :: (store (s32) into @i) 63 64; FIXME: peephole optimization opportunity for lower part relocation @l to the consuming stw 65; TEST32LARGE: .write_int: 66; TEST32LARGE: addis 4, i[TD]@u(2) 67; TEST32LARGE-NEXT: la 4, i[TD]@l(4) 68; TEST32LARGE-NEXT: stw 3, 0(4) 69 70 71; CHECK64LARGE: name: write_int 72; CHECK64LARGE: %[[SCRATCH1:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @i 73; CHECK64LARGE-NEXT: %[[SCRATCH2:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItocL8 killed %[[SCRATCH1]], @i 74; CHECK64LARGE-NEXT: STW8 %{{[0-9]+}}, 0, killed %[[SCRATCH2]] :: (store (s32) into @i) 75 76; TEST64LARGE: .write_int: 77; TEST64LARGE: addis 4, i[TD]@u(2) 78; TEST64LARGE-NEXT: la 4, i[TD]@l(4) 79; TEST64LARGE-NEXT: stw 3, 0(4) 80 81define dso_local i64 @read_ll() { 82 entry: 83 %0 = load i64, ptr @ll, align 8 84 ret i64 %0 85} 86; CHECK32: name: read_ll 87; CHECK32: LWZtoc @ll, $r2 :: (load (s32) from got) 88 89; TEST32: .read_ll: 90; TEST32: lwz 4, L..C0(2) 91; TEST32-NEXT: lwz 3, 0(4) 92; TEST32-NEXT: lwz 4, 4(4) 93 94; CHECK64: name: read_ll 95; CHECK64: %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = LDtoc @ll, $x2 :: (load (s64) from got) 96; CHECK64: LD 0, killed %[[SCRATCH]] 97 98; CHECK64-NOOPT: name: read_ll 99; CHECK64-NOOPT: %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = LDtoc @ll, $x2 100; CHECK64-NOOPT: LD 0, %[[SCRATCH]] 101 102; TEST64: .read_ll: 103; TEST64: ld 3, L..C0(2) 104; TEST64-NEXT: ld 3, 0(3) 105 106; CHECK32LARGE: name: read_ll 107; CHECK32LARGE: %[[SCRATCH1:[0-9]+]]:gprc_and_gprc_nor0 = ADDIStocHA $r2, @ll 108; CHECK32LARGE: LWZtocL @ll, killed %[[SCRATCH1]] :: (load (s32) from got) 109 110; TEST32LARGE: .read_ll: 111; TEST32LARGE: addis 3, L..C0@u(2) 112; TEST32LARGE-NEXT: lwz 4, L..C0@l(3) 113; TEST32LARGE-NEXT: lwz 3, 0(4) 114; TEST32LARGE-NEXT: lwz 4, 4(4) 115 116; CHECK64LARGE: name: read_ll 117; CHECK64LARGE: %[[SCRATCH1:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @ll 118; CHECK64LARGE: LDtocL @ll, killed %[[SCRATCH1]] :: (load (s64) from got) 119 120; TEST64LARGE: .read_ll: 121; TEST64LARGE: addis 3, L..C0@u(2) 122; TEST64LARGE-NEXT: ld 3, L..C0@l(3) 123; TEST64LARGE-NEXT: ld 3, 0(3) 124 125define dso_local float @read_float() { 126 entry: 127 %0 = load float, ptr @f, align 4 128 ret float %0 129} 130; CHECK32: name: read_float 131; CHECK32: %[[SCRATCH:[0-9]+]]:gprc_and_gprc_nor0 = ADDItoc $r2, @f 132; CHECK32: %{{[0-9]+}}:f4rc = LFS 0, killed %[[SCRATCH]] :: (dereferenceable load (s32) from @f) 133 134; TEST32: .read_float: 135; TEST32: la 3, f[TD](2) 136; TEST32-NEXT: lfs 1, 0(3) 137 138; CHECK64: name: read_float 139; CHECK64: %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItoc8 $x2, @f 140; CHECK64: %{{[0-9]+}}:f4rc = LFS 0, killed %[[SCRATCH]] :: (dereferenceable load (s32) from @f) 141 142; CHECK64-NOOPT: name: read_float 143; CHECK64-NOOPT: %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItoc8 $x2, @f 144; CHECK64-NOOPT: %{{[0-9]+}}:f4rc = LFS 0, %[[SCRATCH]] 145 146; TEST64: .read_float: 147; TEST64: la 3, f[TD](2) 148; TEST64-NEXT: lfs 1, 0(3) 149 150; CHECK32LARGE: name: read_float 151; CHECK32LARGE: %[[SCRATCH1:[0-9]+]]:gprc_and_gprc_nor0 = ADDIStocHA $r2, @f 152; CHECK32LARGE-NEXT: %[[SCRATCH2:[0-9]+]]:gprc_and_gprc_nor0 = ADDItocL killed %[[SCRATCH1]], @f 153; CHECK32LARGE-NEXT: LFS 0, killed %[[SCRATCH2]] :: (dereferenceable load (s32) from @f) 154 155; FIXME: peephole optimization opportunity for lower part relocation @l to the consuming lfs 156; TEST32LARGE: .read_float: 157; TEST32LARGE: addis 3, f[TD]@u(2) 158; TEST32LARGE-NEXT: la 3, f[TD]@l(3) 159; TEST32LARGE-NEXT: lfs 1, 0(3) 160 161 162; CHECK64LARGE: name: read_float 163; CHECK64LARGE: %[[SCRATCH1:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @f 164; CHECK64LARGE-NEXT: %[[SCRATCH2:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItocL8 killed %[[SCRATCH1]], @f 165; CHECK64LARGE-NEXT: LFS 0, killed %[[SCRATCH2]] :: (dereferenceable load (s32) from @f) 166 167 168; TEST64LARGE: .read_float: 169; TEST64LARGE: addis 3, f[TD]@u(2) 170; TEST64LARGE-NEXT: la 3, f[TD]@l(3) 171; TEST64LARGE-NEXT: lfs 1, 0(3) 172 173define dso_local void @write_double(double %in) { 174 entry: 175 store double %in, ptr @d, align 8 176 ret void 177} 178; CHECK32: name: write_double 179; CHECK32: LWZtoc @d, $r2 :: (load (s32) from got) 180 181; TEST32: .write_double 182; TEST32: lwz 3, L..C1(2) 183; TEST32-NEXT: stfd 1, 0(3) 184 185; CHECK64: name: write_double 186; CHECK64: %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = LDtoc @d, $x2 :: (load (s64) from got) 187; CHECK64: STFD %{{[0-9]+}}, 0, killed %[[SCRATCH]] 188 189; CHECK64-NOOPT: name: write_double 190; CHECK64-NOOPT: %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = LDtoc @d, $x2 191; CHECK64-NOOPT STFD %{{[0-9]+}}, 0 %[[SCRATCH]] 192 193; TEST64: .write_double 194; TEST64: ld 3, L..C1(2) 195; TEST64-NEXT: stfd 1, 0(3) 196 197; CHECK32LARGE: name: write_double 198; CHECK32LARGE: %[[SCRATCH1:[0-9]+]]:gprc_and_gprc_nor0 = ADDIStocHA $r2, @d 199; CHECK32LARGE: LWZtocL @d, killed %[[SCRATCH1]] :: (load (s32) from got) 200 201; TEST32LARGE: .write_double: 202; TEST32LARGE: addis 3, L..C1@u(2) 203; TEST32LARGE-NEXT: lwz 3, L..C1@l(3) 204; TEST32LARGE-NEXT: stfd 1, 0(3) 205 206; CHECK64LARGE: name: write_double 207; CHECK64LARGE: %[[SCRATCH1:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @d 208; CHECK64LARGE: LDtocL @d, killed %[[SCRATCH1]] :: (load (s64) from got) 209 210; TEST64LARGE: .write_double: 211; TEST64LARGE: addis 3, L..C1@u(2) 212; TEST64LARGE-NEXT: ld 3, L..C1@l(3) 213; TEST64LARGE-NEXT: stfd 1, 0(3) 214 215define dso_local nonnull ptr @addr() { 216 entry: 217 ret ptr @i 218} 219; CHECK32: name: addr 220; CHECK32: %[[SCRATCH:[0-9]+]]:gprc = ADDItoc $r2, @i 221; CHECK32-NEXT: $r3 = COPY %[[SCRATCH]] 222 223; TEST32: .addr 224; TEST32: la 3, i[TD](2) 225 226; CHECK64: name: addr 227; CHECK64: %[[SCRATCH:[0-9]+]]:g8rc = ADDItoc8 $x2, @i 228; CHECK64-NEXT: $x3 = COPY %[[SCRATCH]] 229 230; CHECK64-NOOPT: name: addr 231; CHECK64-NOOPT: %[[SCRATCH:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDItoc8 $x2, @i 232; CHECK64-NOOPT: $x3 = COPY %[[SCRATCH]] 233 234; TEST64: .addr 235; TEST64: la 3, i[TD](2) 236 237; CHECK32LARGE: name: addr 238; CHECK32LARGE: %[[SCRATCH1:[0-9]+]]:gprc_and_gprc_nor0 = ADDIStocHA $r2, @i 239; CHECK32LARGE-NEXT: %[[SCRATCH2:[0-9]+]]:gprc = ADDItocL killed %[[SCRATCH1]], @i 240; CHECK32LARGE-NEXT: $r3 = COPY %[[SCRATCH2]] 241 242; TEST32LARGE: .addr: 243; TEST32LARGE: addis 3, i[TD]@u(2) 244; TEST32LARGE-NEXT: la 3, i[TD]@l(3) 245 246; TEST32: .toc 247; TEST32: .tc ll[TC],ll[RW] 248; TEST32-NOT: .csect ll[TD] 249; TEST32: .tc d[TC],d[RW] 250; TEST32-NOT: .csect d[TD],2 251; TEST32: .csect i[TD],2 252; TEST32-NEXT: .globl i[TD] 253; TEST32-NEXT: .align 2 254; TEST32-NOT: .tc i[TC],i[RW] 255; TEST32: .csect f[TD],2 256; TEST32-NEXT: .globl f[TD] 257; TEST32-NOT: .tc f[TD],f[RW] 258 259; TEST64: .toc 260; TEST64: .tc ll[TC],ll[RW] 261; TEST64-NOT: .csect ll[TD] 262; TEST64: .tc d[TC],d[RW] 263; TEST64-NOT: .csect d[TD],2 264; TEST64: .csect i[TD],2 265; TEST64-NEXT: .globl i[TD] 266; TEST64-NEXT: .align 2 267; TEST64-NOT: .tc i[TC],i[RW] 268; TEST64: .csect f[TD],2 269; TEST64-NEXT: .globl f[TD] 270; TEST64-NOT: .tc f[TD],f[RW] 271 272; TEST32LARGE: .toc 273; TEST32LARGE: .tc ll[TE],ll[RW] 274; TEST32LARGE-NOT: .csect ll[TD] 275; TEST32LARGE: .tc d[TE],d[RW] 276; TEST32LARGE-NOT: .csect d[TD],2 277; TEST32LARGE: .csect i[TD],2 278; TEST32LARGE-NEXT: .globl i[TD] 279; TEST32LARGE-NEXT: .align 2 280; TEST32LARGE-NOT: .tc i[TE],i[RW] 281; TEST32LARGE: .csect f[TD],2 282; TEST32LARGE-NEXT: .globl f[TD] 283; TEST32LARGE-NOT: .tc f[TE],f[RW] 284 285; CHECK64LARGE: name: addr 286; CHECK64LARGE: %[[SCRATCH1:[0-9]+]]:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, @i 287; CHECK64LARGE-NEXT: %[[SCRATCH2:[0-9]+]]:g8rc = ADDItocL8 killed %[[SCRATCH1]], @i 288; CHECK64LARGE-NEXT: $x3 = COPY %[[SCRATCH2]] 289 290; TEST64LARGE: .addr: 291; TEST64LARGE: addis 3, i[TD]@u(2) 292; TEST64LARGE: la 3, i[TD]@l(3) 293 294; TEST64LARGE: .toc 295; TEST64LARGE: .tc ll[TE],ll[RW] 296; TEST64LARGE-NOT: .csect ll[TD] 297; TEST64LARGE: .tc d[TE],d[RW] 298; TEST64LARGE-NOT: .csect d[TD],2 299; TEST64LARGE: .csect i[TD],2 300; TEST64LARGE-NEXT: .globl i[TD] 301; TEST64LARGE-NEXT: .align 2 302; TEST64LARGE-NOT: .tc i[TE],i[RW] 303; TEST64LARGE: .csect f[TD],2 304; TEST64LARGE-NEXT: .globl f[TD] 305; TEST64LARGE-NOT: .tc f[TE],f[RW] 306 307attributes #0 = { "toc-data" } 308