1; RUN: llc -relocation-model=pic -mcpu=pwr9 -mtriple=powerpc64le-unknown-unknown \ 2; RUN: -enable-ppc-quad-precision -verify-machineinstrs \ 3; RUN: -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names < %s | FileCheck %s 4; RUN: llc -relocation-model=pic -mcpu=pwr9 -mtriple=powerpc64-unknown-unknown \ 5; RUN: -enable-ppc-quad-precision -verify-machineinstrs \ 6; RUN: -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names < %s \ 7; RUN: | FileCheck -check-prefix=CHECK-BE %s 8 9; Testing homogeneous aggregates. 10 11%struct.With9fp128params = type { fp128, fp128, fp128, fp128, fp128, fp128, 12 fp128, fp128, fp128 } 13 14@a1 = common local_unnamed_addr global [3 x fp128] zeroinitializer, align 16 15 16; Function Attrs: norecurse nounwind readonly 17define fp128 @testArray_01(fp128* nocapture readonly %sa) { 18; CHECK-LABEL: testArray_01: 19; CHECK: # %bb.0: # %entry 20; CHECK-NEXT: lxv v2, 32(r3) 21; CHECK-NEXT: blr 22 23; CHECK-BE-LABEL: testArray_01: 24; CHECK-BE: lxv v2, 32(r3) 25; CHECK-BE-NEXT: blr 26entry: 27 %arrayidx = getelementptr inbounds fp128, fp128* %sa, i64 2 28 %0 = load fp128, fp128* %arrayidx, align 16 29 ret fp128 %0 30} 31 32; Function Attrs: norecurse nounwind readonly 33define fp128 @testArray_02() { 34; CHECK-LABEL: testArray_02: 35; CHECK: # %bb.0: # %entry 36; CHECK-NEXT: addis r3, r2, .LC0@toc@ha 37; CHECK-NEXT: ld r3, .LC0@toc@l(r3) 38; CHECK-NEXT: lxv v2, 32(r3) 39; CHECK-NEXT: blr 40 41; CHECK-BE-LABEL: testArray_02: 42; CHECK-BE: lxv v2, 32(r3) 43; CHECK-BE-NEXT: blr 44entry: 45 %0 = load fp128, fp128* getelementptr inbounds ([3 x fp128], [3 x fp128]* @a1, 46 i64 0, i64 2), align 16 47 ret fp128 %0 48} 49 50; Function Attrs: norecurse nounwind readnone 51define fp128 @testStruct_01(fp128 inreg returned %a.coerce) { 52; CHECK-LABEL: testStruct_01: 53; CHECK: # %bb.0: # %entry 54; CHECK-NEXT: blr 55 56; CHECK-BE-LABEL: testStruct_01: 57; CHECK-BE: # %bb.0: # %entry 58; CHECK-BE-NEXT: blr 59entry: 60 ret fp128 %a.coerce 61} 62 63; Function Attrs: norecurse nounwind readnone 64define fp128 @testStruct_02([8 x fp128] %a.coerce) { 65; CHECK-LABEL: testStruct_02: 66; CHECK: # %bb.0: # %entry 67; CHECK-NEXT: vmr v2, v9 68; CHECK-NEXT: blr 69 70; CHECK-BE-LABEL: testStruct_02: 71; CHECK-BE: vmr v2, v9 72; CHECK-BE-NEXT: blr 73entry: 74 %a.coerce.fca.7.extract = extractvalue [8 x fp128] %a.coerce, 7 75 ret fp128 %a.coerce.fca.7.extract 76} 77 78; Since we can only pass a max of 8 float128 value in VSX registers, ensure we 79; store to stack if passing more. 80; Function Attrs: norecurse nounwind readonly 81define fp128 @testStruct_03(%struct.With9fp128params* byval nocapture readonly 82 align 16 %a) { 83; CHECK-LABEL: testStruct_03: 84; CHECK: # %bb.0: # %entry 85; CHECK: lxv v2, 128(r1) 86; CHECK-DAG: std r10, 88(r1) 87; CHECK-DAG: std r9, 80(r1) 88; CHECK-DAG: std r8, 72(r1) 89; CHECK-DAG: std r7, 64(r1) 90; CHECK-DAG: std r6, 56(r1) 91; CHECK-DAG: std r5, 48(r1) 92; CHECK-DAG: std r4, 40(r1) 93; CHECK-DAG: std r3, 32(r1) 94; CHECK-NEXT: blr 95 96; CHECK-BE-LABEL: testStruct_03: 97; CHECK-BE: # %bb.0: # %entry 98; CHECK-BE: lxv v2, 144(r1) 99; CHECK-BE-DAG: std r10, 104(r1) 100; CHECK-BE-DAG: std r9, 96(r1) 101; CHECK-BE-DAG: std r8, 88(r1) 102; CHECK-BE-DAG: std r7, 80(r1) 103; CHECK-BE-DAG: std r6, 72(r1) 104; CHECK-BE-DAG: std r5, 64(r1) 105; CHECK-BE-DAG: std r4, 56(r1) 106; CHECK-BE-DAG: std r3, 48(r1) 107; CHECK-BE-NEXT: blr 108entry: 109 %a7 = getelementptr inbounds %struct.With9fp128params, 110 %struct.With9fp128params* %a, i64 0, i32 6 111 %0 = load fp128, fp128* %a7, align 16 112 ret fp128 %0 113} 114 115; Function Attrs: norecurse nounwind readnone 116define fp128 @testStruct_04([8 x fp128] %a.coerce) { 117; CHECK-LABEL: testStruct_04: 118; CHECK: # %bb.0: # %entry 119; CHECK-NEXT: vmr v2, v5 120; CHECK-NEXT: blr 121 122; CHECK-BE-LABEL: testStruct_04: 123; CHECK-BE: vmr v2, v5 124; CHECK-BE-NEXT: blr 125entry: 126 %a.coerce.fca.3.extract = extractvalue [8 x fp128] %a.coerce, 3 127 ret fp128 %a.coerce.fca.3.extract 128} 129 130; Function Attrs: norecurse nounwind readnone 131define fp128 @testHUnion_01([1 x fp128] %a.coerce) { 132; CHECK-LABEL: testHUnion_01: 133; CHECK: # %bb.0: # %entry 134; CHECK-NEXT: blr 135 136; CHECK-BE-LABEL: testHUnion_01: 137; CHECK-BE: # %bb.0: # %entry 138; CHECK-BE-NEXT: blr 139entry: 140 %a.coerce.fca.0.extract = extractvalue [1 x fp128] %a.coerce, 0 141 ret fp128 %a.coerce.fca.0.extract 142} 143 144; Function Attrs: norecurse nounwind readnone 145define fp128 @testHUnion_02([3 x fp128] %a.coerce) { 146; CHECK-LABEL: testHUnion_02: 147; CHECK: # %bb.0: # %entry 148; CHECK-NEXT: blr 149 150; CHECK-BE-LABEL: testHUnion_02: 151; CHECK-BE: # %bb.0: # %entry 152; CHECK-BE-NEXT: blr 153entry: 154 %a.coerce.fca.0.extract = extractvalue [3 x fp128] %a.coerce, 0 155 ret fp128 %a.coerce.fca.0.extract 156} 157 158; Function Attrs: norecurse nounwind readnone 159define fp128 @testHUnion_03([3 x fp128] %a.coerce) { 160; CHECK-LABEL: testHUnion_03: 161; CHECK: # %bb.0: # %entry 162; CHECK-NEXT: vmr v2, v3 163; CHECK-NEXT: blr 164 165; CHECK-BE-LABEL: testHUnion_03: 166; CHECK-BE: # %bb.0: # %entry 167; CHECK-BE-NEXT: vmr v2, v3 168; CHECK-BE-NEXT: blr 169entry: 170 %a.coerce.fca.1.extract = extractvalue [3 x fp128] %a.coerce, 1 171 ret fp128 %a.coerce.fca.1.extract 172} 173 174; Function Attrs: norecurse nounwind readnone 175define fp128 @testHUnion_04([3 x fp128] %a.coerce) { 176; CHECK-LABEL: testHUnion_04: 177; CHECK: # %bb.0: # %entry 178; CHECK-NEXT: vmr v2, v4 179; CHECK-NEXT: blr 180 181; CHECK-BE-LABEL: testHUnion_04: 182; CHECK-BE: # %bb.0: # %entry 183; CHECK-BE-NEXT: vmr v2, v4 184; CHECK-BE-NEXT: blr 185entry: 186 %a.coerce.fca.2.extract = extractvalue [3 x fp128] %a.coerce, 2 187 ret fp128 %a.coerce.fca.2.extract 188} 189 190; Testing mixed member aggregates. 191 192%struct.MixedC = type { i32, %struct.SA, float, [12 x i8] } 193%struct.SA = type { double, fp128, <4 x float> } 194 195; Function Attrs: norecurse nounwind readnone 196define fp128 @testMixedAggregate([3 x i128] %a.coerce) { 197; CHECK-LABEL: testMixedAggregate: 198; CHECK: # %bb.0: # %entry 199; CHECK-NEXT: mtvsrdd v2, r8, r7 200; CHECK-NEXT: blr 201 202; CHECK-BE-LABEL: testMixedAggregate: 203; CHECK-BE: mtvsrdd v2, r8, r7 204; CHECK-BE-NEXT: blr 205entry: 206 %a.coerce.fca.2.extract = extractvalue [3 x i128] %a.coerce, 2 207 %0 = bitcast i128 %a.coerce.fca.2.extract to fp128 208 ret fp128 %0 209} 210 211; Function Attrs: norecurse nounwind readnone 212define fp128 @testMixedAggregate_02([4 x i128] %a.coerce) { 213; CHECK-LABEL: testMixedAggregate_02: 214; CHECK: # %bb.0: # %entry 215; CHECK-NEXT: mtvsrdd v2, r6, r5 216; CHECK-NEXT: blr 217 218; CHECK-BE-LABEL: testMixedAggregate_02: 219; CHECK-BE: mtvsrdd v2, r6, r5 220; CHECK-BE-NEXT: blr 221entry: 222 %a.coerce.fca.1.extract = extractvalue [4 x i128] %a.coerce, 1 223 %0 = bitcast i128 %a.coerce.fca.1.extract to fp128 224 ret fp128 %0 225} 226 227; Function Attrs: norecurse nounwind readnone 228define fp128 @testMixedAggregate_03([4 x i128] %sa.coerce) { 229; CHECK-LABEL: testMixedAggregate_03: 230; CHECK: # %bb.0: # %entry 231; CHECK: mtvsrwa v2, r3 232; CHECK: xscvsdqp v2, v2 233; CHECK: mtvsrdd v3, r6, r5 234; CHECK: xsaddqp v2, v3, v2 235; CHECK: mtvsrd v[[REG1:[0-9]+]], r10 236; CHECK: xscvsdqp v[[REG:[0-9]+]], v[[REG1]] 237; CHECK: xsaddqp v2, v2, v[[REG]] 238; CHECK-NEXT: blr 239entry: 240 %sa.coerce.fca.0.extract = extractvalue [4 x i128] %sa.coerce, 0 241 %sa.sroa.0.0.extract.trunc = trunc i128 %sa.coerce.fca.0.extract to i32 242 %sa.coerce.fca.1.extract = extractvalue [4 x i128] %sa.coerce, 1 243 %sa.coerce.fca.3.extract = extractvalue [4 x i128] %sa.coerce, 3 244 %sa.sroa.6.48.extract.shift = lshr i128 %sa.coerce.fca.3.extract, 64 245 %sa.sroa.6.48.extract.trunc = trunc i128 %sa.sroa.6.48.extract.shift to i64 246 %conv = sitofp i32 %sa.sroa.0.0.extract.trunc to fp128 247 %0 = bitcast i128 %sa.coerce.fca.1.extract to fp128 248 %add = fadd fp128 %0, %conv 249 %conv2 = sitofp i64 %sa.sroa.6.48.extract.trunc to fp128 250 %add3 = fadd fp128 %add, %conv2 251 ret fp128 %add3 252} 253 254 255; Function Attrs: norecurse nounwind readonly 256define fp128 @testNestedAggregate(%struct.MixedC* byval nocapture readonly align 16 %a) { 257; CHECK-LABEL: testNestedAggregate: 258; CHECK: # %bb.0: # %entry 259; CHECK-DAG: std r8, 72(r1) 260; CHECK-DAG: std r7, 64(r1) 261; CHECK: lxv v2, 64(r1) 262; CHECK-DAG: std r10, 88(r1) 263; CHECK-DAG: std r9, 80(r1) 264; CHECK-DAG: std r6, 56(r1) 265; CHECK-DAG: std r5, 48(r1) 266; CHECK-DAG: std r4, 40(r1) 267; CHECK-DAG: std r3, 32(r1) 268; CHECK-NEXT: blr 269 270; CHECK-BE-LABEL: testNestedAggregate: 271; CHECK-BE: # %bb.0: # %entry 272; CHECK-BE-DAG: std r8, 88(r1) 273; CHECK-BE-DAG: std r7, 80(r1) 274; CHECK-BE-NEXT: lxv v2, 80(r1) 275; CHECK-BE-DAG: std r10, 104(r1) 276; CHECK-BE-DAG: std r9, 96(r1) 277; CHECK-BE-DAG: std r6, 72(r1) 278; CHECK-BE-DAG: std r5, 64(r1) 279; CHECK-BE-DAG: std r4, 56(r1) 280; CHECK-BE-DAG: std r3, 48(r1) 281; CHECK-BE-NEXT: blr 282entry: 283 %c = getelementptr inbounds %struct.MixedC, %struct.MixedC* %a, i64 0, i32 1, i32 1 284 %0 = load fp128, fp128* %c, align 16 285 ret fp128 %0 286} 287 288; Function Attrs: norecurse nounwind readnone 289define fp128 @testUnion_01([1 x i128] %a.coerce) { 290; CHECK-LABEL: testUnion_01: 291; CHECK: # %bb.0: # %entry 292; CHECK-NEXT: mtvsrdd v2, r4, r3 293; CHECK-NEXT: blr 294 295; CHECK-BE-LABEL: testUnion_01: 296; CHECK-BE: mtvsrdd v2, r4, r3 297; CHECK-BE-NEXT: blr 298entry: 299 %a.coerce.fca.0.extract = extractvalue [1 x i128] %a.coerce, 0 300 %0 = bitcast i128 %a.coerce.fca.0.extract to fp128 301 ret fp128 %0 302} 303 304; Function Attrs: norecurse nounwind readnone 305define fp128 @testUnion_02([1 x i128] %a.coerce) { 306; CHECK-LABEL: testUnion_02: 307; CHECK: # %bb.0: # %entry 308; CHECK-NEXT: mtvsrdd v2, r4, r3 309; CHECK-NEXT: blr 310 311; CHECK-BE-LABEL: testUnion_02: 312; CHECK-BE: mtvsrdd v2, r4, r3 313; CHECK-BE-NEXT: blr 314entry: 315 %a.coerce.fca.0.extract = extractvalue [1 x i128] %a.coerce, 0 316 %0 = bitcast i128 %a.coerce.fca.0.extract to fp128 317 ret fp128 %0 318} 319 320; Function Attrs: norecurse nounwind readnone 321define fp128 @testUnion_03([4 x i128] %a.coerce) { 322; CHECK-LABEL: testUnion_03: 323; CHECK: # %bb.0: # %entry 324; CHECK-NEXT: mtvsrdd v2, r8, r7 325; CHECK-NEXT: blr 326 327; CHECK-BE-LABEL: testUnion_03: 328; CHECK-BE: mtvsrdd v2, r8, r7 329; CHECK-BE-NEXT: blr 330entry: 331 %a.coerce.fca.2.extract = extractvalue [4 x i128] %a.coerce, 2 332 %0 = bitcast i128 %a.coerce.fca.2.extract to fp128 333 ret fp128 %0 334} 335 336; Function Attrs: nounwind 337define fp128 @sum_float128(i32 signext %count, ...) { 338; CHECK-LABEL: sum_float128: 339; CHECK: # %bb.0: # %entry 340; CHECK-DAG: std r10, 88(r1) 341; CHECK-DAG: std r9, 80(r1) 342; CHECK-DAG: std r8, 72(r1) 343; CHECK-DAG: std r7, 64(r1) 344; CHECK-DAG: std r6, 56(r1) 345; CHECK-DAG: std r4, 40(r1) 346; CHECK-DAG: cmpwi cr0, r3, 1 347; CHECK-DAG: std r5, 48(r1) 348; CHECK-DAG: addis [[REG:r[0-9]+]], r2, .LCPI17_0@toc@ha 349; CHECK-DAG: addi [[REG1:r[0-9]+]], [[REG]], .LCPI17_0@toc@l 350; CHECK-DAG: lxvx v2, 0, [[REG1]] 351; CHECK-NEXT: bltlr cr0 352; CHECK-NEXT: # %bb.1: # %if.end 353; CHECK-NEXT: addi r3, r1, 40 354; CHECK-NEXT: lxvx v3, 0, r3 355; CHECK-NEXT: xsaddqp v2, v3, v2 356; CHECK-NEXT: addi [[REG2:r[0-9]+]], r1, 72 357; CHECK-NEXT: std [[REG2]], -8(r1) 358; CHECK-NEXT: lxv v3, 16(r3) 359; CHECK-NEXT: xsaddqp v2, v2, v3 360; CHECK-NEXT: blr 361entry: 362 %ap = alloca i8*, align 8 363 %0 = bitcast i8** %ap to i8* 364 call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %0) #2 365 %cmp = icmp slt i32 %count, 1 366 br i1 %cmp, label %cleanup, label %if.end 367 368if.end: ; preds = %entry 369 call void @llvm.va_start(i8* nonnull %0) 370 %argp.cur = load i8*, i8** %ap, align 8 371 %argp.next = getelementptr inbounds i8, i8* %argp.cur, i64 16 372 %1 = bitcast i8* %argp.cur to fp128* 373 %2 = load fp128, fp128* %1, align 8 374 %add = fadd fp128 %2, 0xL00000000000000000000000000000000 375 %argp.next3 = getelementptr inbounds i8, i8* %argp.cur, i64 32 376 store i8* %argp.next3, i8** %ap, align 8 377 %3 = bitcast i8* %argp.next to fp128* 378 %4 = load fp128, fp128* %3, align 8 379 %add4 = fadd fp128 %add, %4 380 call void @llvm.va_end(i8* nonnull %0) 381 br label %cleanup 382 383cleanup: ; preds = %entry, %if.end 384 %retval.0 = phi fp128 [ %add4, %if.end ], [ 0xL00000000000000000000000000000000, %entry ] 385 call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %0) #2 386 ret fp128 %retval.0 387} 388 389declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1 390declare void @llvm.va_start(i8*) #2 391declare void @llvm.va_end(i8*) #2 392declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1 393