1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -ppc-asm-full-reg-names -verify-machineinstrs \ 3; RUN: -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr9 < %s | FileCheck %s 4 5; addresses: 6; 1: base1 + offset 7; 2: + offset 8; 3: + offset 9; 4: + offset 10; 11; chains: 12; 1: base: base1 + offset, offsets: (0, offset) 13; 2: base: base1 + 3*offset, offsets: (0, offset) 14; 15; long long two_chain_same_offset_succ(char *p, long long offset, long long base1, long long n) { 16; long long o1 = base1 + offset; 17; long long o2 = base1 + 2 * offset; 18; long long o3 = base1 + 3 * offset; 19; long long o4 = base1 + 4 * offset; 20; char *p1 = p + o1; 21; char *p2 = p + o2; 22; char *p3 = p + o3; 23; char *p4 = p + o4; 24; long long sum = 0; 25; for (long long i = 0; i < n; ++i) { 26; unsigned long x1 = *(unsigned long *)(p1 + i); 27; unsigned long x2 = *(unsigned long *)(p2 + i); 28; unsigned long x3 = *(unsigned long *)(p3 + i); 29; unsigned long x4 = *(unsigned long *)(p4 + i); 30; sum += x1 * x2 * x3 * x4; 31; } 32; return sum; 33; } 34; 35define i64 @two_chain_same_offset_succ(i8* %p, i64 %offset, i64 %base1, i64 %n) { 36; CHECK-LABEL: two_chain_same_offset_succ: 37; CHECK: # %bb.0: # %entry 38; CHECK-NEXT: cmpdi r6, 1 39; CHECK-NEXT: blt cr0, .LBB0_4 40; CHECK-NEXT: # %bb.1: # %for.body.preheader 41; CHECK-NEXT: sldi r8, r4, 1 42; CHECK-NEXT: mtctr r6 43; CHECK-NEXT: add r5, r3, r5 44; CHECK-NEXT: li r3, 0 45; CHECK-NEXT: sldi r7, r4, 2 46; CHECK-NEXT: add r9, r4, r8 47; CHECK-NEXT: .p2align 4 48; CHECK-NEXT: .LBB0_2: # %for.body 49; CHECK-NEXT: # 50; CHECK-NEXT: ldx r6, r5, r4 51; CHECK-NEXT: ldx r10, r5, r8 52; CHECK-NEXT: ldx r11, r5, r9 53; CHECK-NEXT: ldx r12, r5, r7 54; CHECK-NEXT: addi r5, r5, 1 55; CHECK-NEXT: mulld r6, r10, r6 56; CHECK-NEXT: mulld r6, r6, r11 57; CHECK-NEXT: maddld r3, r6, r12, r3 58; CHECK-NEXT: bdnz .LBB0_2 59; CHECK-NEXT: # %bb.3: # %for.cond.cleanup 60; CHECK-NEXT: blr 61; CHECK-NEXT: .LBB0_4: 62; CHECK-NEXT: li r3, 0 63; CHECK-NEXT: blr 64entry: 65 %mul = shl nsw i64 %offset, 1 66 %mul2 = mul nsw i64 %offset, 3 67 %mul4 = shl nsw i64 %offset, 2 68 %cmp46 = icmp sgt i64 %n, 0 69 br i1 %cmp46, label %for.body, label %for.cond.cleanup 70 71for.cond.cleanup: ; preds = %for.body, %entry 72 %sum.0.lcssa = phi i64 [ 0, %entry ], [ %add16, %for.body ] 73 ret i64 %sum.0.lcssa 74 75for.body: ; preds = %entry, %for.body 76 %sum.048 = phi i64 [ %add16, %for.body ], [ 0, %entry ] 77 %i.047 = phi i64 [ %inc, %for.body ], [ 0, %entry ] 78 %add = add i64 %i.047, %base1 79 %add.ptr9.idx = add i64 %add, %offset 80 %add.ptr9 = getelementptr inbounds i8, i8* %p, i64 %add.ptr9.idx 81 %0 = bitcast i8* %add.ptr9 to i64* 82 %1 = load i64, i64* %0, align 8 83 %add.ptr10.idx = add i64 %add, %mul 84 %add.ptr10 = getelementptr inbounds i8, i8* %p, i64 %add.ptr10.idx 85 %2 = bitcast i8* %add.ptr10 to i64* 86 %3 = load i64, i64* %2, align 8 87 %add.ptr11.idx = add i64 %add, %mul2 88 %add.ptr11 = getelementptr inbounds i8, i8* %p, i64 %add.ptr11.idx 89 %4 = bitcast i8* %add.ptr11 to i64* 90 %5 = load i64, i64* %4, align 8 91 %add.ptr12.idx = add i64 %add, %mul4 92 %add.ptr12 = getelementptr inbounds i8, i8* %p, i64 %add.ptr12.idx 93 %6 = bitcast i8* %add.ptr12 to i64* 94 %7 = load i64, i64* %6, align 8 95 %mul13 = mul i64 %3, %1 96 %mul14 = mul i64 %mul13, %5 97 %mul15 = mul i64 %mul14, %7 98 %add16 = add i64 %mul15, %sum.048 99 %inc = add nuw nsw i64 %i.047, 1 100 %exitcond.not = icmp eq i64 %inc, %n 101 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 102} 103 104; addresses: 105; 1: base1 + offset 106; 2: + offset 107; 3: + offset 108; 4: + offset 109; 5: + offset 110; 111; It can not be commoned to chains because we will need a chain for a single address, 112; which can not make the commoning be profitable. 113; 114; long long not_perfect_chain_all_same_offset_fail(char *p, long long offset, long long base1, long long n) { 115; long long o1 = base1 + offset; 116; long long o2 = base1 + 2 * offset; 117; long long o3 = base1 + 3 * offset; 118; long long o4 = base1 + 4 * offset; 119; long long o5 = base1 + 5 * offset; 120; char *p1 = p + o1; 121; char *p2 = p + o2; 122; char *p3 = p + o3; 123; char *p4 = p + o4; 124; char *p5 = p + o5; 125; long long sum = 0; 126; for (long long i = 0; i < n; ++i) { 127; unsigned long x1 = *(unsigned long *)(p1 + i); 128; unsigned long x2 = *(unsigned long *)(p2 + i); 129; unsigned long x3 = *(unsigned long *)(p3 + i); 130; unsigned long x4 = *(unsigned long *)(p4 + i); 131; unsigned long x5 = *(unsigned long *)(p5 + i); 132; sum += x1 * x2 * x3 * x4 * x5; 133; } 134; return sum; 135; } 136; 137define i64 @not_perfect_chain_all_same_offset_fail(i8* %p, i64 %offset, i64 %base1, i64 %n) { 138; CHECK-LABEL: not_perfect_chain_all_same_offset_fail: 139; CHECK: # %bb.0: # %entry 140; CHECK-NEXT: cmpdi r6, 1 141; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill 142; CHECK-NEXT: blt cr0, .LBB1_4 143; CHECK-NEXT: # %bb.1: # %for.body.preheader 144; CHECK-NEXT: sldi r7, r4, 2 145; CHECK-NEXT: sldi r9, r4, 1 146; CHECK-NEXT: add r5, r3, r5 147; CHECK-NEXT: li r3, 0 148; CHECK-NEXT: add r8, r4, r7 149; CHECK-NEXT: mtctr r6 150; CHECK-NEXT: add r10, r4, r9 151; CHECK-NEXT: .p2align 4 152; CHECK-NEXT: .LBB1_2: # %for.body 153; CHECK-NEXT: # 154; CHECK-NEXT: ldx r6, r5, r4 155; CHECK-NEXT: ldx r11, r5, r9 156; CHECK-NEXT: ldx r12, r5, r10 157; CHECK-NEXT: ldx r0, r5, r7 158; CHECK-NEXT: mulld r6, r11, r6 159; CHECK-NEXT: ldx r30, r5, r8 160; CHECK-NEXT: addi r5, r5, 1 161; CHECK-NEXT: mulld r6, r6, r12 162; CHECK-NEXT: mulld r6, r6, r0 163; CHECK-NEXT: maddld r3, r6, r30, r3 164; CHECK-NEXT: bdnz .LBB1_2 165; CHECK-NEXT: # %bb.3: # %for.cond.cleanup 166; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload 167; CHECK-NEXT: blr 168; CHECK-NEXT: .LBB1_4: 169; CHECK-NEXT: li r3, 0 170; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload 171; CHECK-NEXT: blr 172entry: 173 %mul = shl nsw i64 %offset, 1 174 %mul2 = mul nsw i64 %offset, 3 175 %mul4 = shl nsw i64 %offset, 2 176 %mul6 = mul nsw i64 %offset, 5 177 %cmp58 = icmp sgt i64 %n, 0 178 br i1 %cmp58, label %for.body, label %for.cond.cleanup 179 180for.cond.cleanup: ; preds = %for.body, %entry 181 %sum.0.lcssa = phi i64 [ 0, %entry ], [ %add21, %for.body ] 182 ret i64 %sum.0.lcssa 183 184for.body: ; preds = %entry, %for.body 185 %sum.060 = phi i64 [ %add21, %for.body ], [ 0, %entry ] 186 %i.059 = phi i64 [ %inc, %for.body ], [ 0, %entry ] 187 %add = add i64 %i.059, %base1 188 %add.ptr12.idx = add i64 %add, %offset 189 %add.ptr12 = getelementptr inbounds i8, i8* %p, i64 %add.ptr12.idx 190 %0 = bitcast i8* %add.ptr12 to i64* 191 %1 = load i64, i64* %0, align 8 192 %add.ptr13.idx = add i64 %add, %mul 193 %add.ptr13 = getelementptr inbounds i8, i8* %p, i64 %add.ptr13.idx 194 %2 = bitcast i8* %add.ptr13 to i64* 195 %3 = load i64, i64* %2, align 8 196 %add.ptr14.idx = add i64 %add, %mul2 197 %add.ptr14 = getelementptr inbounds i8, i8* %p, i64 %add.ptr14.idx 198 %4 = bitcast i8* %add.ptr14 to i64* 199 %5 = load i64, i64* %4, align 8 200 %add.ptr15.idx = add i64 %add, %mul4 201 %add.ptr15 = getelementptr inbounds i8, i8* %p, i64 %add.ptr15.idx 202 %6 = bitcast i8* %add.ptr15 to i64* 203 %7 = load i64, i64* %6, align 8 204 %add.ptr16.idx = add i64 %add, %mul6 205 %add.ptr16 = getelementptr inbounds i8, i8* %p, i64 %add.ptr16.idx 206 %8 = bitcast i8* %add.ptr16 to i64* 207 %9 = load i64, i64* %8, align 8 208 %mul17 = mul i64 %3, %1 209 %mul18 = mul i64 %mul17, %5 210 %mul19 = mul i64 %mul18, %7 211 %mul20 = mul i64 %mul19, %9 212 %add21 = add i64 %mul20, %sum.060 213 %inc = add nuw nsw i64 %i.059, 1 214 %exitcond.not = icmp eq i64 %inc, %n 215 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 216} 217 218; addresses: 219; 1: base1 220; 2: + 2*offset 221; 3: + offset 222; 223; We need at least 4 addresses to common 2 chains to reuse at least 1 offset. 224; 225; long long no_enough_elements_fail(char *p, long long offset, long long base1, long long n) { 226; long long o1 = base1; 227; long long o2 = base1 + 2 * offset; 228; long long o3 = base1 + 3 * offset; 229; char *p1 = p + o1; 230; char *p2 = p + o2; 231; char *p3 = p + o3; 232; long long sum = 0; 233; for (long long i = 0; i < n; ++i) { 234; unsigned long x1 = *(unsigned long *)(p1 + i); 235; unsigned long x2 = *(unsigned long *)(p2 + i); 236; unsigned long x3 = *(unsigned long *)(p3 + i); 237; sum += x1 * x2 * x3; 238; } 239; return sum; 240; } 241; 242define i64 @no_enough_elements_fail(i8* %p, i64 %offset, i64 %base1, i64 %n) { 243; CHECK-LABEL: no_enough_elements_fail: 244; CHECK: # %bb.0: # %entry 245; CHECK-NEXT: cmpdi r6, 1 246; CHECK-NEXT: blt cr0, .LBB2_4 247; CHECK-NEXT: # %bb.1: # %for.body.preheader 248; CHECK-NEXT: sldi r7, r4, 1 249; CHECK-NEXT: mtctr r6 250; CHECK-NEXT: add r5, r3, r5 251; CHECK-NEXT: li r3, 0 252; CHECK-NEXT: add r4, r4, r7 253; CHECK-NEXT: .p2align 5 254; CHECK-NEXT: .LBB2_2: # %for.body 255; CHECK-NEXT: # 256; CHECK-NEXT: ld r6, 0(r5) 257; CHECK-NEXT: ldx r8, r5, r7 258; CHECK-NEXT: ldx r9, r5, r4 259; CHECK-NEXT: addi r5, r5, 1 260; CHECK-NEXT: mulld r6, r8, r6 261; CHECK-NEXT: maddld r3, r6, r9, r3 262; CHECK-NEXT: bdnz .LBB2_2 263; CHECK-NEXT: # %bb.3: # %for.cond.cleanup 264; CHECK-NEXT: blr 265; CHECK-NEXT: .LBB2_4: 266; CHECK-NEXT: li r3, 0 267; CHECK-NEXT: blr 268entry: 269 %mul = shl nsw i64 %offset, 1 270 %mul1 = mul nsw i64 %offset, 3 271 %cmp32 = icmp sgt i64 %n, 0 272 br i1 %cmp32, label %for.body, label %for.cond.cleanup 273 274for.cond.cleanup: ; preds = %for.body, %entry 275 %sum.0.lcssa = phi i64 [ 0, %entry ], [ %add10, %for.body ] 276 ret i64 %sum.0.lcssa 277 278for.body: ; preds = %entry, %for.body 279 %sum.034 = phi i64 [ %add10, %for.body ], [ 0, %entry ] 280 %i.033 = phi i64 [ %inc, %for.body ], [ 0, %entry ] 281 %add.ptr5.idx = add i64 %i.033, %base1 282 %add.ptr5 = getelementptr inbounds i8, i8* %p, i64 %add.ptr5.idx 283 %0 = bitcast i8* %add.ptr5 to i64* 284 %1 = load i64, i64* %0, align 8 285 %add.ptr6.idx = add i64 %add.ptr5.idx, %mul 286 %add.ptr6 = getelementptr inbounds i8, i8* %p, i64 %add.ptr6.idx 287 %2 = bitcast i8* %add.ptr6 to i64* 288 %3 = load i64, i64* %2, align 8 289 %add.ptr7.idx = add i64 %add.ptr5.idx, %mul1 290 %add.ptr7 = getelementptr inbounds i8, i8* %p, i64 %add.ptr7.idx 291 %4 = bitcast i8* %add.ptr7 to i64* 292 %5 = load i64, i64* %4, align 8 293 %mul8 = mul i64 %3, %1 294 %mul9 = mul i64 %mul8, %5 295 %add10 = add i64 %mul9, %sum.034 296 %inc = add nuw nsw i64 %i.033, 1 297 %exitcond.not = icmp eq i64 %inc, %n 298 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 299} 300 301; addresses: 302; 1: base1 303; 2: + 2*offset 304; 3: + 2*offset 305; 4: + 3*offset 306; 307; The diff between address 2 and address 1 is offset, and this offset is not reused among other addresses, 308; so we can not common any chains. 309; 310; long long no_reuseable_offset_fail(char *p, long long offset, long long base1, long long n) { 311; long long o1 = base1; 312; long long o2 = base1 + 2 * offset; 313; long long o3 = base1 + 4 * offset; 314; long long o4 = base1 + 7 * offset; 315; char *p1 = p + o1; 316; char *p2 = p + o2; 317; char *p3 = p + o3; 318; char *p4 = p + o4; 319; long long sum = 0; 320; for (long long i = 0; i < n; ++i) { 321; unsigned long x1 = *(unsigned long *)(p1 + i); 322; unsigned long x2 = *(unsigned long *)(p2 + i); 323; unsigned long x3 = *(unsigned long *)(p3 + i); 324; unsigned long x4 = *(unsigned long *)(p4 + i); 325; sum += x1 * x2 * x3 * x4; 326; } 327; return sum; 328; } 329; 330define i64 @no_reuseable_offset_fail(i8* %p, i64 %offset, i64 %base1, i64 %n) { 331; CHECK-LABEL: no_reuseable_offset_fail: 332; CHECK: # %bb.0: # %entry 333; CHECK-NEXT: cmpdi r6, 1 334; CHECK-NEXT: blt cr0, .LBB3_4 335; CHECK-NEXT: # %bb.1: # %for.body.preheader 336; CHECK-NEXT: sldi r7, r4, 3 337; CHECK-NEXT: mtctr r6 338; CHECK-NEXT: add r5, r3, r5 339; CHECK-NEXT: li r3, 0 340; CHECK-NEXT: sldi r8, r4, 2 341; CHECK-NEXT: sub r7, r7, r4 342; CHECK-NEXT: sldi r4, r4, 1 343; CHECK-NEXT: .p2align 4 344; CHECK-NEXT: .LBB3_2: # %for.body 345; CHECK-NEXT: # 346; CHECK-NEXT: ld r6, 0(r5) 347; CHECK-NEXT: ldx r9, r5, r4 348; CHECK-NEXT: ldx r10, r5, r8 349; CHECK-NEXT: ldx r11, r5, r7 350; CHECK-NEXT: addi r5, r5, 1 351; CHECK-NEXT: mulld r6, r9, r6 352; CHECK-NEXT: mulld r6, r6, r10 353; CHECK-NEXT: maddld r3, r6, r11, r3 354; CHECK-NEXT: bdnz .LBB3_2 355; CHECK-NEXT: # %bb.3: # %for.cond.cleanup 356; CHECK-NEXT: blr 357; CHECK-NEXT: .LBB3_4: 358; CHECK-NEXT: li r3, 0 359; CHECK-NEXT: blr 360entry: 361 %mul = shl nsw i64 %offset, 1 362 %mul1 = shl nsw i64 %offset, 2 363 %mul3 = mul nsw i64 %offset, 7 364 %cmp44 = icmp sgt i64 %n, 0 365 br i1 %cmp44, label %for.body, label %for.cond.cleanup 366 367for.cond.cleanup: ; preds = %for.body, %entry 368 %sum.0.lcssa = phi i64 [ 0, %entry ], [ %add15, %for.body ] 369 ret i64 %sum.0.lcssa 370 371for.body: ; preds = %entry, %for.body 372 %sum.046 = phi i64 [ %add15, %for.body ], [ 0, %entry ] 373 %i.045 = phi i64 [ %inc, %for.body ], [ 0, %entry ] 374 %add.ptr8.idx = add i64 %i.045, %base1 375 %add.ptr8 = getelementptr inbounds i8, i8* %p, i64 %add.ptr8.idx 376 %0 = bitcast i8* %add.ptr8 to i64* 377 %1 = load i64, i64* %0, align 8 378 %add.ptr9.idx = add i64 %add.ptr8.idx, %mul 379 %add.ptr9 = getelementptr inbounds i8, i8* %p, i64 %add.ptr9.idx 380 %2 = bitcast i8* %add.ptr9 to i64* 381 %3 = load i64, i64* %2, align 8 382 %add.ptr10.idx = add i64 %add.ptr8.idx, %mul1 383 %add.ptr10 = getelementptr inbounds i8, i8* %p, i64 %add.ptr10.idx 384 %4 = bitcast i8* %add.ptr10 to i64* 385 %5 = load i64, i64* %4, align 8 386 %add.ptr11.idx = add i64 %add.ptr8.idx, %mul3 387 %add.ptr11 = getelementptr inbounds i8, i8* %p, i64 %add.ptr11.idx 388 %6 = bitcast i8* %add.ptr11 to i64* 389 %7 = load i64, i64* %6, align 8 390 %mul12 = mul i64 %3, %1 391 %mul13 = mul i64 %mul12, %5 392 %mul14 = mul i64 %mul13, %7 393 %add15 = add i64 %mul14, %sum.046 394 %inc = add nuw nsw i64 %i.045, 1 395 %exitcond.not = icmp eq i64 %inc, %n 396 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 397} 398 399; addresses: 400; 1: base1 + offset 401; 2: + offset 402; 3: + 3*offset 403; 4: + 2*offset 404; 5: + 1*offset 405; 6: + 2*offset 406; 407; The diff between address 2 and address 1 is offset, and this offset is reused between address 4 and address 5. 408; but the diff between address 3 and address 2 (3*offset) is not the same with the diff between address 6 409; and address 5(2*offset), so we can not common chains for these addresses. 410; 411; long long not_same_offset_fail(char *p, long long offset, long long base1, long long n) { 412; long long o1 = base1 + offset; 413; long long o2 = base1 + 2 * offset; 414; long long o3 = base1 + 5 * offset; 415; long long o4 = base1 + 7 * offset; 416; long long o5 = base1 + 8 * offset; 417; long long o6 = base1 + 10 * offset; 418; char *p1 = p + o1; 419; char *p2 = p + o2; 420; char *p3 = p + o3; 421; char *p4 = p + o4; 422; char *p5 = p + o5; 423; char *p6 = p + o6; 424; long long sum = 0; 425; for (long long i = 0; i < n; ++i) { 426; unsigned long x1 = *(unsigned long *)(p1 + i); 427; unsigned long x2 = *(unsigned long *)(p2 + i); 428; unsigned long x3 = *(unsigned long *)(p3 + i); 429; unsigned long x4 = *(unsigned long *)(p4 + i); 430; unsigned long x5 = *(unsigned long *)(p5 + i); 431; unsigned long x6 = *(unsigned long *)(p6 + i); 432; sum += x1 * x2 * x3 * x4 * x5 * x6; 433; } 434; return sum; 435; } 436; 437define i64 @not_same_offset_fail(i8* %p, i64 %offset, i64 %base1, i64 %n) { 438; CHECK-LABEL: not_same_offset_fail: 439; CHECK: # %bb.0: # %entry 440; CHECK-NEXT: cmpdi r6, 1 441; CHECK-NEXT: std r28, -32(r1) # 8-byte Folded Spill 442; CHECK-NEXT: std r29, -24(r1) # 8-byte Folded Spill 443; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill 444; CHECK-NEXT: blt cr0, .LBB4_3 445; CHECK-NEXT: # %bb.1: # %for.body.preheader 446; CHECK-NEXT: mulli r7, r4, 10 447; CHECK-NEXT: add r5, r3, r5 448; CHECK-NEXT: sldi r8, r4, 3 449; CHECK-NEXT: sub r9, r8, r4 450; CHECK-NEXT: sldi r3, r4, 2 451; CHECK-NEXT: mtctr r6 452; CHECK-NEXT: add r10, r4, r3 453; CHECK-NEXT: sldi r11, r4, 1 454; CHECK-NEXT: li r3, 0 455; CHECK-NEXT: .p2align 4 456; CHECK-NEXT: .LBB4_2: # %for.body 457; CHECK-NEXT: # 458; CHECK-NEXT: ldx r6, r5, r4 459; CHECK-NEXT: ldx r12, r5, r11 460; CHECK-NEXT: ldx r0, r5, r10 461; CHECK-NEXT: ldx r30, r5, r9 462; CHECK-NEXT: mulld r6, r12, r6 463; CHECK-NEXT: ldx r29, r5, r8 464; CHECK-NEXT: ldx r28, r5, r7 465; CHECK-NEXT: addi r5, r5, 1 466; CHECK-NEXT: mulld r6, r6, r0 467; CHECK-NEXT: mulld r6, r6, r30 468; CHECK-NEXT: mulld r6, r6, r29 469; CHECK-NEXT: maddld r3, r6, r28, r3 470; CHECK-NEXT: bdnz .LBB4_2 471; CHECK-NEXT: b .LBB4_4 472; CHECK-NEXT: .LBB4_3: 473; CHECK-NEXT: li r3, 0 474; CHECK-NEXT: .LBB4_4: # %for.cond.cleanup 475; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload 476; CHECK-NEXT: ld r29, -24(r1) # 8-byte Folded Reload 477; CHECK-NEXT: ld r28, -32(r1) # 8-byte Folded Reload 478; CHECK-NEXT: blr 479entry: 480 %mul = shl nsw i64 %offset, 1 481 %mul2 = mul nsw i64 %offset, 5 482 %mul4 = mul nsw i64 %offset, 7 483 %mul6 = shl nsw i64 %offset, 3 484 %mul8 = mul nsw i64 %offset, 10 485 %cmp70 = icmp sgt i64 %n, 0 486 br i1 %cmp70, label %for.body, label %for.cond.cleanup 487 488for.cond.cleanup: ; preds = %for.body, %entry 489 %sum.0.lcssa = phi i64 [ 0, %entry ], [ %add26, %for.body ] 490 ret i64 %sum.0.lcssa 491 492for.body: ; preds = %entry, %for.body 493 %sum.072 = phi i64 [ %add26, %for.body ], [ 0, %entry ] 494 %i.071 = phi i64 [ %inc, %for.body ], [ 0, %entry ] 495 %add = add i64 %i.071, %base1 496 %add.ptr15.idx = add i64 %add, %offset 497 %add.ptr15 = getelementptr inbounds i8, i8* %p, i64 %add.ptr15.idx 498 %0 = bitcast i8* %add.ptr15 to i64* 499 %1 = load i64, i64* %0, align 8 500 %add.ptr16.idx = add i64 %add, %mul 501 %add.ptr16 = getelementptr inbounds i8, i8* %p, i64 %add.ptr16.idx 502 %2 = bitcast i8* %add.ptr16 to i64* 503 %3 = load i64, i64* %2, align 8 504 %add.ptr17.idx = add i64 %add, %mul2 505 %add.ptr17 = getelementptr inbounds i8, i8* %p, i64 %add.ptr17.idx 506 %4 = bitcast i8* %add.ptr17 to i64* 507 %5 = load i64, i64* %4, align 8 508 %add.ptr18.idx = add i64 %add, %mul4 509 %add.ptr18 = getelementptr inbounds i8, i8* %p, i64 %add.ptr18.idx 510 %6 = bitcast i8* %add.ptr18 to i64* 511 %7 = load i64, i64* %6, align 8 512 %add.ptr19.idx = add i64 %add, %mul6 513 %add.ptr19 = getelementptr inbounds i8, i8* %p, i64 %add.ptr19.idx 514 %8 = bitcast i8* %add.ptr19 to i64* 515 %9 = load i64, i64* %8, align 8 516 %add.ptr20.idx = add i64 %add, %mul8 517 %add.ptr20 = getelementptr inbounds i8, i8* %p, i64 %add.ptr20.idx 518 %10 = bitcast i8* %add.ptr20 to i64* 519 %11 = load i64, i64* %10, align 8 520 %mul21 = mul i64 %3, %1 521 %mul22 = mul i64 %mul21, %5 522 %mul23 = mul i64 %mul22, %7 523 %mul24 = mul i64 %mul23, %9 524 %mul25 = mul i64 %mul24, %11 525 %add26 = add i64 %mul25, %sum.072 526 %inc = add nuw nsw i64 %i.071, 1 527 %exitcond.not = icmp eq i64 %inc, %n 528 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 529} 530 531; addresses: 532; 1: base1 + offset 533; 2: + offset 534; 3: + 3*offset 535; 4: + 2*offset 536; 537; chains: 538; 1: base1 + offset, offsets: (0, 2*offset) 539; 2: base1 + 4*offset, offsets: (0, 2*offset) 540; 541; long long two_chain_different_offsets_succ(char *p, long long offset, long long base1, long long n) { 542; long long o1 = base1 + offset; 543; long long o2 = base1 + 3 * offset; 544; long long o3 = base1 + 4 * offset; 545; long long o4 = base1 + 6 * offset; 546; char *p1 = p + o1; 547; char *p2 = p + o2; 548; char *p3 = p + o3; 549; char *p4 = p + o4; 550; long long sum = 0; 551; for (long long i = 0; i < n; ++i) { 552; unsigned long x1 = *(unsigned long *)(p1 + i); 553; unsigned long x2 = *(unsigned long *)(p2 + i); 554; unsigned long x3 = *(unsigned long *)(p3 + i); 555; unsigned long x4 = *(unsigned long *)(p4 + i); 556; sum += x1 * x2 * x3 * x4; 557; } 558; return sum; 559; } 560; 561define i64 @two_chain_different_offsets_succ(i8* %p, i64 %offset, i64 %base1, i64 %n) { 562; CHECK-LABEL: two_chain_different_offsets_succ: 563; CHECK: # %bb.0: # %entry 564; CHECK-NEXT: cmpdi r6, 1 565; CHECK-NEXT: blt cr0, .LBB5_4 566; CHECK-NEXT: # %bb.1: # %for.body.preheader 567; CHECK-NEXT: mulli r7, r4, 6 568; CHECK-NEXT: add r5, r3, r5 569; CHECK-NEXT: sldi r3, r4, 1 570; CHECK-NEXT: add r9, r4, r3 571; CHECK-NEXT: mtctr r6 572; CHECK-NEXT: sldi r8, r4, 2 573; CHECK-NEXT: li r3, 0 574; CHECK-NEXT: .p2align 4 575; CHECK-NEXT: .LBB5_2: # %for.body 576; CHECK-NEXT: # 577; CHECK-NEXT: ldx r6, r5, r4 578; CHECK-NEXT: ldx r10, r5, r9 579; CHECK-NEXT: ldx r11, r5, r8 580; CHECK-NEXT: ldx r12, r5, r7 581; CHECK-NEXT: addi r5, r5, 1 582; CHECK-NEXT: mulld r6, r10, r6 583; CHECK-NEXT: mulld r6, r6, r11 584; CHECK-NEXT: maddld r3, r6, r12, r3 585; CHECK-NEXT: bdnz .LBB5_2 586; CHECK-NEXT: # %bb.3: # %for.cond.cleanup 587; CHECK-NEXT: blr 588; CHECK-NEXT: .LBB5_4: 589; CHECK-NEXT: li r3, 0 590; CHECK-NEXT: blr 591entry: 592 %mul = mul nsw i64 %offset, 3 593 %mul2 = shl nsw i64 %offset, 2 594 %mul4 = mul nsw i64 %offset, 6 595 %cmp46 = icmp sgt i64 %n, 0 596 br i1 %cmp46, label %for.body, label %for.cond.cleanup 597 598for.cond.cleanup: ; preds = %for.body, %entry 599 %sum.0.lcssa = phi i64 [ 0, %entry ], [ %add16, %for.body ] 600 ret i64 %sum.0.lcssa 601 602for.body: ; preds = %entry, %for.body 603 %sum.048 = phi i64 [ %add16, %for.body ], [ 0, %entry ] 604 %i.047 = phi i64 [ %inc, %for.body ], [ 0, %entry ] 605 %add = add i64 %i.047, %base1 606 %add.ptr9.idx = add i64 %add, %offset 607 %add.ptr9 = getelementptr inbounds i8, i8* %p, i64 %add.ptr9.idx 608 %0 = bitcast i8* %add.ptr9 to i64* 609 %1 = load i64, i64* %0, align 8 610 %add.ptr10.idx = add i64 %add, %mul 611 %add.ptr10 = getelementptr inbounds i8, i8* %p, i64 %add.ptr10.idx 612 %2 = bitcast i8* %add.ptr10 to i64* 613 %3 = load i64, i64* %2, align 8 614 %add.ptr11.idx = add i64 %add, %mul2 615 %add.ptr11 = getelementptr inbounds i8, i8* %p, i64 %add.ptr11.idx 616 %4 = bitcast i8* %add.ptr11 to i64* 617 %5 = load i64, i64* %4, align 8 618 %add.ptr12.idx = add i64 %add, %mul4 619 %add.ptr12 = getelementptr inbounds i8, i8* %p, i64 %add.ptr12.idx 620 %6 = bitcast i8* %add.ptr12 to i64* 621 %7 = load i64, i64* %6, align 8 622 %mul13 = mul i64 %3, %1 623 %mul14 = mul i64 %mul13, %5 624 %mul15 = mul i64 %mul14, %7 625 %add16 = add i64 %mul15, %sum.048 626 %inc = add nuw nsw i64 %i.047, 1 627 %exitcond.not = icmp eq i64 %inc, %n 628 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 629} 630 631; addresses: 632; 1: base1 + offset 633; 2: + 2*offset 634; 3: + base2 - base1 - 2*offset 635; 4: + 2*offset 636; 637; chains: 638; 1: base1 + offset, offsets: (0, 2*offset) 639; 2: base2 + offset, offsets: (0, 2*offset) 640; 641; long long two_chain_two_bases_succ(char *p, long long offset, long long base1, long long base2, long long n) { 642; long long o1 = base1 + offset; 643; long long o2 = base1 + 3 * offset; 644; long long o3 = base2 + offset; 645; long long o4 = base2 + 3 * offset; 646; char *p1 = p + o1; 647; char *p2 = p + o2; 648; char *p3 = p + o3; 649; char *p4 = p + o4; 650; long long sum = 0; 651; for (long long i = 0; i < n; ++i) { 652; unsigned long x1 = *(unsigned long *)(p1 + i); 653; unsigned long x2 = *(unsigned long *)(p2 + i); 654; unsigned long x3 = *(unsigned long *)(p3 + i); 655; unsigned long x4 = *(unsigned long *)(p4 + i); 656; sum += x1 * x2 * x3 * x4; 657; } 658; return sum; 659; } 660; 661define i64 @two_chain_two_bases_succ(i8* %p, i64 %offset, i64 %base1, i64 %base2, i64 %n) { 662; CHECK-LABEL: two_chain_two_bases_succ: 663; CHECK: # %bb.0: # %entry 664; CHECK-NEXT: cmpdi r7, 1 665; CHECK-NEXT: blt cr0, .LBB6_4 666; CHECK-NEXT: # %bb.1: # %for.body.preheader 667; CHECK-NEXT: sldi r8, r4, 1 668; CHECK-NEXT: mtctr r7 669; CHECK-NEXT: add r9, r4, r8 670; CHECK-NEXT: add r8, r6, r9 671; CHECK-NEXT: add r6, r6, r4 672; CHECK-NEXT: add r9, r5, r9 673; CHECK-NEXT: add r5, r5, r4 674; CHECK-NEXT: li r4, 0 675; CHECK-NEXT: .p2align 4 676; CHECK-NEXT: .LBB6_2: # %for.body 677; CHECK-NEXT: # 678; CHECK-NEXT: ldx r7, r3, r5 679; CHECK-NEXT: ldx r10, r3, r9 680; CHECK-NEXT: ldx r11, r3, r6 681; CHECK-NEXT: ldx r12, r3, r8 682; CHECK-NEXT: addi r3, r3, 1 683; CHECK-NEXT: mulld r7, r10, r7 684; CHECK-NEXT: mulld r7, r7, r11 685; CHECK-NEXT: maddld r4, r7, r12, r4 686; CHECK-NEXT: bdnz .LBB6_2 687; CHECK-NEXT: # %bb.3: # %for.cond.cleanup 688; CHECK-NEXT: mr r3, r4 689; CHECK-NEXT: blr 690; CHECK-NEXT: .LBB6_4: 691; CHECK-NEXT: li r4, 0 692; CHECK-NEXT: mr r3, r4 693; CHECK-NEXT: blr 694entry: 695 %mul = mul nsw i64 %offset, 3 696 %cmp44 = icmp sgt i64 %n, 0 697 br i1 %cmp44, label %for.body, label %for.cond.cleanup 698 699for.cond.cleanup: ; preds = %for.body, %entry 700 %sum.0.lcssa = phi i64 [ 0, %entry ], [ %add15, %for.body ] 701 ret i64 %sum.0.lcssa 702 703for.body: ; preds = %entry, %for.body 704 %sum.046 = phi i64 [ %add15, %for.body ], [ 0, %entry ] 705 %i.045 = phi i64 [ %inc, %for.body ], [ 0, %entry ] 706 %add = add i64 %i.045, %base1 707 %add.ptr8.idx = add i64 %add, %offset 708 %add.ptr8 = getelementptr inbounds i8, i8* %p, i64 %add.ptr8.idx 709 %0 = bitcast i8* %add.ptr8 to i64* 710 %1 = load i64, i64* %0, align 8 711 %add1 = add i64 %i.045, %mul 712 %add.ptr9.idx = add i64 %add1, %base1 713 %add.ptr9 = getelementptr inbounds i8, i8* %p, i64 %add.ptr9.idx 714 %2 = bitcast i8* %add.ptr9 to i64* 715 %3 = load i64, i64* %2, align 8 716 %add2 = add i64 %i.045, %base2 717 %add.ptr10.idx = add i64 %add2, %offset 718 %add.ptr10 = getelementptr inbounds i8, i8* %p, i64 %add.ptr10.idx 719 %4 = bitcast i8* %add.ptr10 to i64* 720 %5 = load i64, i64* %4, align 8 721 %add.ptr11.idx = add i64 %add2, %mul 722 %add.ptr11 = getelementptr inbounds i8, i8* %p, i64 %add.ptr11.idx 723 %6 = bitcast i8* %add.ptr11 to i64* 724 %7 = load i64, i64* %6, align 8 725 %mul12 = mul i64 %3, %1 726 %mul13 = mul i64 %mul12, %5 727 %mul14 = mul i64 %mul13, %7 728 %add15 = add i64 %mul14, %sum.046 729 %inc = add nuw nsw i64 %i.045, 1 730 %exitcond.not = icmp eq i64 %inc, %n 731 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 732} 733; 734; Check chain commoning can reduce register pressure to save register spill/reload. 735; 736; int spill_reduce_succ(double *input1, double *input2, double *output, long long m, long long inc1, long long inc2, long long inc3, long long inc4, long long inc) { 737; inc = inc4; 738; #pragma unroll 4 739; for (long long i = 0; i < 4 * m; i++) { 740; output[inc + inc1] += input1[inc + inc1] * input2[inc + inc1]; 741; output[inc + inc2] += input1[inc + inc2] * input2[inc + inc2]; 742; output[inc + inc3] += input1[inc + inc3] * input2[inc + inc3]; 743; inc = inc + inc4; 744; } 745; return 0; 746; } 747; 748define signext i32 @spill_reduce_succ(double* %input1, double* %input2, double* %output, i64 %m, i64 %inc1, i64 %inc2, i64 %inc3, i64 %inc4, i64 %inc) { 749; CHECK-LABEL: spill_reduce_succ: 750; CHECK: # %bb.0: # %entry 751; CHECK-NEXT: stdu r1, -336(r1) 752; CHECK-NEXT: .cfi_def_cfa_offset 336 753; CHECK-NEXT: .cfi_offset r14, -144 754; CHECK-NEXT: .cfi_offset r15, -136 755; CHECK-NEXT: .cfi_offset r16, -128 756; CHECK-NEXT: .cfi_offset r17, -120 757; CHECK-NEXT: .cfi_offset r18, -112 758; CHECK-NEXT: .cfi_offset r19, -104 759; CHECK-NEXT: .cfi_offset r20, -96 760; CHECK-NEXT: .cfi_offset r21, -88 761; CHECK-NEXT: .cfi_offset r22, -80 762; CHECK-NEXT: .cfi_offset r23, -72 763; CHECK-NEXT: .cfi_offset r24, -64 764; CHECK-NEXT: .cfi_offset r25, -56 765; CHECK-NEXT: .cfi_offset r26, -48 766; CHECK-NEXT: .cfi_offset r27, -40 767; CHECK-NEXT: .cfi_offset r28, -32 768; CHECK-NEXT: .cfi_offset r29, -24 769; CHECK-NEXT: .cfi_offset r30, -16 770; CHECK-NEXT: .cfi_offset r31, -8 771; CHECK-NEXT: .cfi_offset r2, -152 772; CHECK-NEXT: cmpdi r6, 1 773; CHECK-NEXT: std r14, 192(r1) # 8-byte Folded Spill 774; CHECK-NEXT: std r15, 200(r1) # 8-byte Folded Spill 775; CHECK-NEXT: std r16, 208(r1) # 8-byte Folded Spill 776; CHECK-NEXT: std r17, 216(r1) # 8-byte Folded Spill 777; CHECK-NEXT: std r18, 224(r1) # 8-byte Folded Spill 778; CHECK-NEXT: std r19, 232(r1) # 8-byte Folded Spill 779; CHECK-NEXT: std r20, 240(r1) # 8-byte Folded Spill 780; CHECK-NEXT: std r21, 248(r1) # 8-byte Folded Spill 781; CHECK-NEXT: std r22, 256(r1) # 8-byte Folded Spill 782; CHECK-NEXT: std r23, 264(r1) # 8-byte Folded Spill 783; CHECK-NEXT: std r24, 272(r1) # 8-byte Folded Spill 784; CHECK-NEXT: std r25, 280(r1) # 8-byte Folded Spill 785; CHECK-NEXT: std r26, 288(r1) # 8-byte Folded Spill 786; CHECK-NEXT: std r27, 296(r1) # 8-byte Folded Spill 787; CHECK-NEXT: std r28, 304(r1) # 8-byte Folded Spill 788; CHECK-NEXT: std r29, 312(r1) # 8-byte Folded Spill 789; CHECK-NEXT: std r30, 320(r1) # 8-byte Folded Spill 790; CHECK-NEXT: std r31, 328(r1) # 8-byte Folded Spill 791; CHECK-NEXT: std r2, 184(r1) # 8-byte Folded Spill 792; CHECK-NEXT: std r9, 40(r1) # 8-byte Folded Spill 793; CHECK-NEXT: std r8, 48(r1) # 8-byte Folded Spill 794; CHECK-NEXT: std r7, 64(r1) # 8-byte Folded Spill 795; CHECK-NEXT: std r5, 80(r1) # 8-byte Folded Spill 796; CHECK-NEXT: std r4, 72(r1) # 8-byte Folded Spill 797; CHECK-NEXT: std r3, 56(r1) # 8-byte Folded Spill 798; CHECK-NEXT: blt cr0, .LBB7_7 799; CHECK-NEXT: # %bb.1: # %for.body.preheader 800; CHECK-NEXT: sldi r3, r6, 2 801; CHECK-NEXT: li r4, 1 802; CHECK-NEXT: mr r16, r10 803; CHECK-NEXT: cmpdi r3, 1 804; CHECK-NEXT: iselgt r3, r3, r4 805; CHECK-NEXT: addi r4, r3, -1 806; CHECK-NEXT: clrldi r6, r3, 63 807; CHECK-NEXT: cmpldi r4, 3 808; CHECK-NEXT: blt cr0, .LBB7_4 809; CHECK-NEXT: # %bb.2: # %for.body.preheader.new 810; CHECK-NEXT: ld r30, 40(r1) # 8-byte Folded Reload 811; CHECK-NEXT: sldi r4, r16, 2 812; CHECK-NEXT: ld r19, 80(r1) # 8-byte Folded Reload 813; CHECK-NEXT: ld r21, 72(r1) # 8-byte Folded Reload 814; CHECK-NEXT: ld r22, 56(r1) # 8-byte Folded Reload 815; CHECK-NEXT: ld r27, 48(r1) # 8-byte Folded Reload 816; CHECK-NEXT: ld r18, 64(r1) # 8-byte Folded Reload 817; CHECK-NEXT: add r5, r30, r4 818; CHECK-NEXT: rldicl r0, r3, 62, 2 819; CHECK-NEXT: sldi r5, r5, 3 820; CHECK-NEXT: add r11, r19, r5 821; CHECK-NEXT: add r7, r21, r5 822; CHECK-NEXT: add r5, r22, r5 823; CHECK-NEXT: std r5, 168(r1) # 8-byte Folded Spill 824; CHECK-NEXT: add r5, r27, r4 825; CHECK-NEXT: add r4, r18, r4 826; CHECK-NEXT: std r7, 176(r1) # 8-byte Folded Spill 827; CHECK-NEXT: sldi r5, r5, 3 828; CHECK-NEXT: sldi r4, r4, 3 829; CHECK-NEXT: add r29, r19, r5 830; CHECK-NEXT: add r7, r21, r5 831; CHECK-NEXT: add r5, r22, r5 832; CHECK-NEXT: add r26, r19, r4 833; CHECK-NEXT: std r5, 152(r1) # 8-byte Folded Spill 834; CHECK-NEXT: add r5, r21, r4 835; CHECK-NEXT: add r4, r22, r4 836; CHECK-NEXT: std r7, 160(r1) # 8-byte Folded Spill 837; CHECK-NEXT: std r4, 136(r1) # 8-byte Folded Spill 838; CHECK-NEXT: sldi r4, r16, 1 839; CHECK-NEXT: std r5, 144(r1) # 8-byte Folded Spill 840; CHECK-NEXT: add r10, r16, r4 841; CHECK-NEXT: add r3, r18, r4 842; CHECK-NEXT: add r5, r30, r10 843; CHECK-NEXT: sldi r3, r3, 3 844; CHECK-NEXT: sldi r5, r5, 3 845; CHECK-NEXT: add r23, r19, r5 846; CHECK-NEXT: add r7, r21, r5 847; CHECK-NEXT: add r5, r22, r5 848; CHECK-NEXT: std r5, 120(r1) # 8-byte Folded Spill 849; CHECK-NEXT: add r5, r27, r10 850; CHECK-NEXT: std r7, 128(r1) # 8-byte Folded Spill 851; CHECK-NEXT: sldi r5, r5, 3 852; CHECK-NEXT: add r20, r19, r5 853; CHECK-NEXT: add r7, r21, r5 854; CHECK-NEXT: add r5, r22, r5 855; CHECK-NEXT: std r5, 104(r1) # 8-byte Folded Spill 856; CHECK-NEXT: add r5, r18, r10 857; CHECK-NEXT: std r7, 112(r1) # 8-byte Folded Spill 858; CHECK-NEXT: sub r10, r18, r10 859; CHECK-NEXT: sldi r5, r5, 3 860; CHECK-NEXT: sldi r10, r10, 3 861; CHECK-NEXT: add r17, r19, r5 862; CHECK-NEXT: add r7, r21, r5 863; CHECK-NEXT: add r5, r22, r5 864; CHECK-NEXT: std r5, 88(r1) # 8-byte Folded Spill 865; CHECK-NEXT: add r5, r30, r4 866; CHECK-NEXT: std r7, 96(r1) # 8-byte Folded Spill 867; CHECK-NEXT: add r7, r19, r3 868; CHECK-NEXT: sldi r5, r5, 3 869; CHECK-NEXT: add r14, r19, r5 870; CHECK-NEXT: add r31, r21, r5 871; CHECK-NEXT: add r2, r22, r5 872; CHECK-NEXT: add r5, r27, r4 873; CHECK-NEXT: add r4, r22, r3 874; CHECK-NEXT: sldi r5, r5, 3 875; CHECK-NEXT: add r12, r19, r5 876; CHECK-NEXT: add r8, r21, r5 877; CHECK-NEXT: add r9, r22, r5 878; CHECK-NEXT: add r5, r21, r3 879; CHECK-NEXT: add r3, r16, r30 880; CHECK-NEXT: rldicl r30, r0, 2, 1 881; CHECK-NEXT: addi r0, r30, -4 882; CHECK-NEXT: sldi r28, r3, 3 883; CHECK-NEXT: rldicl r30, r0, 62, 2 884; CHECK-NEXT: add r3, r19, r28 885; CHECK-NEXT: addi r0, r30, 1 886; CHECK-NEXT: add r30, r21, r28 887; CHECK-NEXT: add r28, r22, r28 888; CHECK-NEXT: mtctr r0 889; CHECK-NEXT: add r0, r16, r27 890; CHECK-NEXT: sldi r0, r0, 3 891; CHECK-NEXT: add r25, r21, r0 892; CHECK-NEXT: add r24, r22, r0 893; CHECK-NEXT: add r22, r22, r10 894; CHECK-NEXT: add r21, r21, r10 895; CHECK-NEXT: add r10, r16, r18 896; CHECK-NEXT: add r27, r19, r0 897; CHECK-NEXT: li r0, 0 898; CHECK-NEXT: sldi r18, r16, 5 899; CHECK-NEXT: sldi r10, r10, 3 900; CHECK-NEXT: add r19, r19, r10 901; CHECK-NEXT: mr r10, r16 902; CHECK-NEXT: .p2align 4 903; CHECK-NEXT: .LBB7_3: # %for.body 904; CHECK-NEXT: # 905; CHECK-NEXT: lfdux f0, r21, r18 906; CHECK-NEXT: lfdux f1, r22, r18 907; CHECK-NEXT: ld r15, 88(r1) # 8-byte Folded Reload 908; CHECK-NEXT: add r10, r10, r16 909; CHECK-NEXT: add r10, r10, r16 910; CHECK-NEXT: xsmuldp f0, f1, f0 911; CHECK-NEXT: lfd f1, 0(r19) 912; CHECK-NEXT: add r10, r10, r16 913; CHECK-NEXT: add r10, r10, r16 914; CHECK-NEXT: xsadddp f0, f1, f0 915; CHECK-NEXT: stfd f0, 0(r19) 916; CHECK-NEXT: add r19, r19, r18 917; CHECK-NEXT: lfdx f0, r24, r0 918; CHECK-NEXT: lfdx f1, r25, r0 919; CHECK-NEXT: xsmuldp f0, f0, f1 920; CHECK-NEXT: lfdx f1, r27, r0 921; CHECK-NEXT: xsadddp f0, f1, f0 922; CHECK-NEXT: stfdx f0, r27, r0 923; CHECK-NEXT: lfdx f0, r28, r0 924; CHECK-NEXT: lfdx f1, r30, r0 925; CHECK-NEXT: xsmuldp f0, f0, f1 926; CHECK-NEXT: lfdx f1, r3, r0 927; CHECK-NEXT: xsadddp f0, f1, f0 928; CHECK-NEXT: stfdx f0, r3, r0 929; CHECK-NEXT: lfdx f0, r4, r0 930; CHECK-NEXT: lfdx f1, r5, r0 931; CHECK-NEXT: xsmuldp f0, f0, f1 932; CHECK-NEXT: lfdx f1, r7, r0 933; CHECK-NEXT: xsadddp f0, f1, f0 934; CHECK-NEXT: stfdx f0, r7, r0 935; CHECK-NEXT: lfdx f0, r9, r0 936; CHECK-NEXT: lfdx f1, r8, r0 937; CHECK-NEXT: xsmuldp f0, f0, f1 938; CHECK-NEXT: lfdx f1, r12, r0 939; CHECK-NEXT: xsadddp f0, f1, f0 940; CHECK-NEXT: stfdx f0, r12, r0 941; CHECK-NEXT: lfdx f0, r2, r0 942; CHECK-NEXT: lfdx f1, r31, r0 943; CHECK-NEXT: xsmuldp f0, f0, f1 944; CHECK-NEXT: lfdx f1, r14, r0 945; CHECK-NEXT: xsadddp f0, f1, f0 946; CHECK-NEXT: stfdx f0, r14, r0 947; CHECK-NEXT: lfdx f0, r15, r0 948; CHECK-NEXT: ld r15, 96(r1) # 8-byte Folded Reload 949; CHECK-NEXT: lfdx f1, r15, r0 950; CHECK-NEXT: ld r15, 104(r1) # 8-byte Folded Reload 951; CHECK-NEXT: xsmuldp f0, f0, f1 952; CHECK-NEXT: lfdx f1, r17, r0 953; CHECK-NEXT: xsadddp f0, f1, f0 954; CHECK-NEXT: stfdx f0, r17, r0 955; CHECK-NEXT: lfdx f0, r15, r0 956; CHECK-NEXT: ld r15, 112(r1) # 8-byte Folded Reload 957; CHECK-NEXT: lfdx f1, r15, r0 958; CHECK-NEXT: ld r15, 120(r1) # 8-byte Folded Reload 959; CHECK-NEXT: xsmuldp f0, f0, f1 960; CHECK-NEXT: lfdx f1, r20, r0 961; CHECK-NEXT: xsadddp f0, f1, f0 962; CHECK-NEXT: stfdx f0, r20, r0 963; CHECK-NEXT: lfdx f0, r15, r0 964; CHECK-NEXT: ld r15, 128(r1) # 8-byte Folded Reload 965; CHECK-NEXT: lfdx f1, r15, r0 966; CHECK-NEXT: ld r15, 136(r1) # 8-byte Folded Reload 967; CHECK-NEXT: xsmuldp f0, f0, f1 968; CHECK-NEXT: lfdx f1, r23, r0 969; CHECK-NEXT: xsadddp f0, f1, f0 970; CHECK-NEXT: stfdx f0, r23, r0 971; CHECK-NEXT: lfdx f0, r15, r0 972; CHECK-NEXT: ld r15, 144(r1) # 8-byte Folded Reload 973; CHECK-NEXT: lfdx f1, r15, r0 974; CHECK-NEXT: ld r15, 152(r1) # 8-byte Folded Reload 975; CHECK-NEXT: xsmuldp f0, f0, f1 976; CHECK-NEXT: lfdx f1, r26, r0 977; CHECK-NEXT: xsadddp f0, f1, f0 978; CHECK-NEXT: stfdx f0, r26, r0 979; CHECK-NEXT: lfdx f0, r15, r0 980; CHECK-NEXT: ld r15, 160(r1) # 8-byte Folded Reload 981; CHECK-NEXT: lfdx f1, r15, r0 982; CHECK-NEXT: ld r15, 168(r1) # 8-byte Folded Reload 983; CHECK-NEXT: xsmuldp f0, f0, f1 984; CHECK-NEXT: lfdx f1, r29, r0 985; CHECK-NEXT: xsadddp f0, f1, f0 986; CHECK-NEXT: stfdx f0, r29, r0 987; CHECK-NEXT: lfdx f0, r15, r0 988; CHECK-NEXT: ld r15, 176(r1) # 8-byte Folded Reload 989; CHECK-NEXT: lfdx f1, r15, r0 990; CHECK-NEXT: xsmuldp f0, f0, f1 991; CHECK-NEXT: lfdx f1, r11, r0 992; CHECK-NEXT: xsadddp f0, f1, f0 993; CHECK-NEXT: stfdx f0, r11, r0 994; CHECK-NEXT: add r0, r0, r18 995; CHECK-NEXT: bdnz .LBB7_3 996; CHECK-NEXT: .LBB7_4: # %for.cond.cleanup.loopexit.unr-lcssa 997; CHECK-NEXT: cmpldi r6, 0 998; CHECK-NEXT: beq cr0, .LBB7_7 999; CHECK-NEXT: # %bb.5: # %for.body.epil.preheader 1000; CHECK-NEXT: ld r12, 64(r1) # 8-byte Folded Reload 1001; CHECK-NEXT: ld r3, 40(r1) # 8-byte Folded Reload 1002; CHECK-NEXT: ld r8, 48(r1) # 8-byte Folded Reload 1003; CHECK-NEXT: ld r30, 80(r1) # 8-byte Folded Reload 1004; CHECK-NEXT: sldi r4, r16, 3 1005; CHECK-NEXT: ld r29, 72(r1) # 8-byte Folded Reload 1006; CHECK-NEXT: ld r28, 56(r1) # 8-byte Folded Reload 1007; CHECK-NEXT: add r0, r10, r12 1008; CHECK-NEXT: add r3, r10, r3 1009; CHECK-NEXT: add r8, r10, r8 1010; CHECK-NEXT: sub r10, r0, r16 1011; CHECK-NEXT: sldi r7, r3, 3 1012; CHECK-NEXT: sldi r11, r8, 3 1013; CHECK-NEXT: sldi r0, r0, 3 1014; CHECK-NEXT: sldi r12, r10, 3 1015; CHECK-NEXT: add r3, r30, r7 1016; CHECK-NEXT: add r5, r29, r7 1017; CHECK-NEXT: add r7, r28, r7 1018; CHECK-NEXT: add r8, r30, r11 1019; CHECK-NEXT: add r9, r29, r11 1020; CHECK-NEXT: add r11, r28, r11 1021; CHECK-NEXT: add r30, r30, r0 1022; CHECK-NEXT: li r0, 0 1023; CHECK-NEXT: add r10, r28, r12 1024; CHECK-NEXT: add r12, r29, r12 1025; CHECK-NEXT: .p2align 4 1026; CHECK-NEXT: .LBB7_6: # %for.body.epil 1027; CHECK-NEXT: # 1028; CHECK-NEXT: lfdux f0, r12, r4 1029; CHECK-NEXT: lfdux f1, r10, r4 1030; CHECK-NEXT: addi r6, r6, -1 1031; CHECK-NEXT: cmpldi r6, 0 1032; CHECK-NEXT: xsmuldp f0, f1, f0 1033; CHECK-NEXT: lfd f1, 0(r30) 1034; CHECK-NEXT: xsadddp f0, f1, f0 1035; CHECK-NEXT: stfd f0, 0(r30) 1036; CHECK-NEXT: add r30, r30, r4 1037; CHECK-NEXT: lfdx f0, r11, r0 1038; CHECK-NEXT: lfdx f1, r9, r0 1039; CHECK-NEXT: xsmuldp f0, f0, f1 1040; CHECK-NEXT: lfdx f1, r8, r0 1041; CHECK-NEXT: xsadddp f0, f1, f0 1042; CHECK-NEXT: stfdx f0, r8, r0 1043; CHECK-NEXT: lfdx f0, r7, r0 1044; CHECK-NEXT: lfdx f1, r5, r0 1045; CHECK-NEXT: xsmuldp f0, f0, f1 1046; CHECK-NEXT: lfdx f1, r3, r0 1047; CHECK-NEXT: xsadddp f0, f1, f0 1048; CHECK-NEXT: stfdx f0, r3, r0 1049; CHECK-NEXT: add r0, r0, r4 1050; CHECK-NEXT: bne cr0, .LBB7_6 1051; CHECK-NEXT: .LBB7_7: # %for.cond.cleanup 1052; CHECK-NEXT: ld r2, 184(r1) # 8-byte Folded Reload 1053; CHECK-NEXT: ld r31, 328(r1) # 8-byte Folded Reload 1054; CHECK-NEXT: ld r30, 320(r1) # 8-byte Folded Reload 1055; CHECK-NEXT: ld r29, 312(r1) # 8-byte Folded Reload 1056; CHECK-NEXT: li r3, 0 1057; CHECK-NEXT: ld r28, 304(r1) # 8-byte Folded Reload 1058; CHECK-NEXT: ld r27, 296(r1) # 8-byte Folded Reload 1059; CHECK-NEXT: ld r26, 288(r1) # 8-byte Folded Reload 1060; CHECK-NEXT: ld r25, 280(r1) # 8-byte Folded Reload 1061; CHECK-NEXT: ld r24, 272(r1) # 8-byte Folded Reload 1062; CHECK-NEXT: ld r23, 264(r1) # 8-byte Folded Reload 1063; CHECK-NEXT: ld r22, 256(r1) # 8-byte Folded Reload 1064; CHECK-NEXT: ld r21, 248(r1) # 8-byte Folded Reload 1065; CHECK-NEXT: ld r20, 240(r1) # 8-byte Folded Reload 1066; CHECK-NEXT: ld r19, 232(r1) # 8-byte Folded Reload 1067; CHECK-NEXT: ld r18, 224(r1) # 8-byte Folded Reload 1068; CHECK-NEXT: ld r17, 216(r1) # 8-byte Folded Reload 1069; CHECK-NEXT: ld r16, 208(r1) # 8-byte Folded Reload 1070; CHECK-NEXT: ld r15, 200(r1) # 8-byte Folded Reload 1071; CHECK-NEXT: ld r14, 192(r1) # 8-byte Folded Reload 1072; CHECK-NEXT: addi r1, r1, 336 1073; CHECK-NEXT: blr 1074entry: 1075 %cmp49 = icmp sgt i64 %m, 0 1076 br i1 %cmp49, label %for.body.preheader, label %for.cond.cleanup 1077 1078for.body.preheader: ; preds = %entry 1079 %0 = shl i64 %m, 2 1080 %smax52 = call i64 @llvm.smax.i64(i64 %0, i64 1) 1081 %1 = add nsw i64 %smax52, -1 1082 %xtraiter = and i64 %smax52, 1 1083 %2 = icmp ult i64 %1, 3 1084 br i1 %2, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body.preheader.new 1085 1086for.body.preheader.new: ; preds = %for.body.preheader 1087 %unroll_iter = and i64 %smax52, 9223372036854775804 1088 br label %for.body 1089 1090for.cond.cleanup.loopexit.unr-lcssa: ; preds = %for.body, %for.body.preheader 1091 %inc.addr.050.unr = phi i64 [ %inc4, %for.body.preheader ], [ %add23.3, %for.body ] 1092 %lcmp.mod.not = icmp eq i64 %xtraiter, 0 1093 br i1 %lcmp.mod.not, label %for.cond.cleanup, label %for.body.epil 1094 1095for.body.epil: ; preds = %for.cond.cleanup.loopexit.unr-lcssa, %for.body.epil 1096 %inc.addr.050.epil = phi i64 [ %add23.epil, %for.body.epil ], [ %inc.addr.050.unr, %for.cond.cleanup.loopexit.unr-lcssa ] 1097 %epil.iter = phi i64 [ %epil.iter.sub, %for.body.epil ], [ %xtraiter, %for.cond.cleanup.loopexit.unr-lcssa ] 1098 %add.epil = add nsw i64 %inc.addr.050.epil, %inc1 1099 %arrayidx.epil = getelementptr inbounds double, double* %input1, i64 %add.epil 1100 %3 = load double, double* %arrayidx.epil, align 8 1101 %arrayidx2.epil = getelementptr inbounds double, double* %input2, i64 %add.epil 1102 %4 = load double, double* %arrayidx2.epil, align 8 1103 %mul3.epil = fmul double %3, %4 1104 %arrayidx5.epil = getelementptr inbounds double, double* %output, i64 %add.epil 1105 %5 = load double, double* %arrayidx5.epil, align 8 1106 %add6.epil = fadd double %5, %mul3.epil 1107 store double %add6.epil, double* %arrayidx5.epil, align 8 1108 %add7.epil = add nsw i64 %inc.addr.050.epil, %inc2 1109 %arrayidx8.epil = getelementptr inbounds double, double* %input1, i64 %add7.epil 1110 %6 = load double, double* %arrayidx8.epil, align 8 1111 %arrayidx10.epil = getelementptr inbounds double, double* %input2, i64 %add7.epil 1112 %7 = load double, double* %arrayidx10.epil, align 8 1113 %mul11.epil = fmul double %6, %7 1114 %arrayidx13.epil = getelementptr inbounds double, double* %output, i64 %add7.epil 1115 %8 = load double, double* %arrayidx13.epil, align 8 1116 %add14.epil = fadd double %8, %mul11.epil 1117 store double %add14.epil, double* %arrayidx13.epil, align 8 1118 %add15.epil = add nsw i64 %inc.addr.050.epil, %inc3 1119 %arrayidx16.epil = getelementptr inbounds double, double* %input1, i64 %add15.epil 1120 %9 = load double, double* %arrayidx16.epil, align 8 1121 %arrayidx18.epil = getelementptr inbounds double, double* %input2, i64 %add15.epil 1122 %10 = load double, double* %arrayidx18.epil, align 8 1123 %mul19.epil = fmul double %9, %10 1124 %arrayidx21.epil = getelementptr inbounds double, double* %output, i64 %add15.epil 1125 %11 = load double, double* %arrayidx21.epil, align 8 1126 %add22.epil = fadd double %11, %mul19.epil 1127 store double %add22.epil, double* %arrayidx21.epil, align 8 1128 %add23.epil = add nsw i64 %inc.addr.050.epil, %inc4 1129 %epil.iter.sub = add nsw i64 %epil.iter, -1 1130 %epil.iter.cmp.not = icmp eq i64 %epil.iter.sub, 0 1131 br i1 %epil.iter.cmp.not, label %for.cond.cleanup, label %for.body.epil 1132 1133for.cond.cleanup: ; preds = %for.body.epil, %for.cond.cleanup.loopexit.unr-lcssa, %entry 1134 ret i32 0 1135 1136for.body: ; preds = %for.body, %for.body.preheader.new 1137 %inc.addr.050 = phi i64 [ %inc4, %for.body.preheader.new ], [ %add23.3, %for.body ] 1138 %niter = phi i64 [ %unroll_iter, %for.body.preheader.new ], [ %niter.nsub.3, %for.body ] 1139 %add = add nsw i64 %inc.addr.050, %inc1 1140 %arrayidx = getelementptr inbounds double, double* %input1, i64 %add 1141 %12 = load double, double* %arrayidx, align 8 1142 %arrayidx2 = getelementptr inbounds double, double* %input2, i64 %add 1143 %13 = load double, double* %arrayidx2, align 8 1144 %mul3 = fmul double %12, %13 1145 %arrayidx5 = getelementptr inbounds double, double* %output, i64 %add 1146 %14 = load double, double* %arrayidx5, align 8 1147 %add6 = fadd double %14, %mul3 1148 store double %add6, double* %arrayidx5, align 8 1149 %add7 = add nsw i64 %inc.addr.050, %inc2 1150 %arrayidx8 = getelementptr inbounds double, double* %input1, i64 %add7 1151 %15 = load double, double* %arrayidx8, align 8 1152 %arrayidx10 = getelementptr inbounds double, double* %input2, i64 %add7 1153 %16 = load double, double* %arrayidx10, align 8 1154 %mul11 = fmul double %15, %16 1155 %arrayidx13 = getelementptr inbounds double, double* %output, i64 %add7 1156 %17 = load double, double* %arrayidx13, align 8 1157 %add14 = fadd double %17, %mul11 1158 store double %add14, double* %arrayidx13, align 8 1159 %add15 = add nsw i64 %inc.addr.050, %inc3 1160 %arrayidx16 = getelementptr inbounds double, double* %input1, i64 %add15 1161 %18 = load double, double* %arrayidx16, align 8 1162 %arrayidx18 = getelementptr inbounds double, double* %input2, i64 %add15 1163 %19 = load double, double* %arrayidx18, align 8 1164 %mul19 = fmul double %18, %19 1165 %arrayidx21 = getelementptr inbounds double, double* %output, i64 %add15 1166 %20 = load double, double* %arrayidx21, align 8 1167 %add22 = fadd double %20, %mul19 1168 store double %add22, double* %arrayidx21, align 8 1169 %add23 = add nsw i64 %inc.addr.050, %inc4 1170 %add.1 = add nsw i64 %add23, %inc1 1171 %arrayidx.1 = getelementptr inbounds double, double* %input1, i64 %add.1 1172 %21 = load double, double* %arrayidx.1, align 8 1173 %arrayidx2.1 = getelementptr inbounds double, double* %input2, i64 %add.1 1174 %22 = load double, double* %arrayidx2.1, align 8 1175 %mul3.1 = fmul double %21, %22 1176 %arrayidx5.1 = getelementptr inbounds double, double* %output, i64 %add.1 1177 %23 = load double, double* %arrayidx5.1, align 8 1178 %add6.1 = fadd double %23, %mul3.1 1179 store double %add6.1, double* %arrayidx5.1, align 8 1180 %add7.1 = add nsw i64 %add23, %inc2 1181 %arrayidx8.1 = getelementptr inbounds double, double* %input1, i64 %add7.1 1182 %24 = load double, double* %arrayidx8.1, align 8 1183 %arrayidx10.1 = getelementptr inbounds double, double* %input2, i64 %add7.1 1184 %25 = load double, double* %arrayidx10.1, align 8 1185 %mul11.1 = fmul double %24, %25 1186 %arrayidx13.1 = getelementptr inbounds double, double* %output, i64 %add7.1 1187 %26 = load double, double* %arrayidx13.1, align 8 1188 %add14.1 = fadd double %26, %mul11.1 1189 store double %add14.1, double* %arrayidx13.1, align 8 1190 %add15.1 = add nsw i64 %add23, %inc3 1191 %arrayidx16.1 = getelementptr inbounds double, double* %input1, i64 %add15.1 1192 %27 = load double, double* %arrayidx16.1, align 8 1193 %arrayidx18.1 = getelementptr inbounds double, double* %input2, i64 %add15.1 1194 %28 = load double, double* %arrayidx18.1, align 8 1195 %mul19.1 = fmul double %27, %28 1196 %arrayidx21.1 = getelementptr inbounds double, double* %output, i64 %add15.1 1197 %29 = load double, double* %arrayidx21.1, align 8 1198 %add22.1 = fadd double %29, %mul19.1 1199 store double %add22.1, double* %arrayidx21.1, align 8 1200 %add23.1 = add nsw i64 %add23, %inc4 1201 %add.2 = add nsw i64 %add23.1, %inc1 1202 %arrayidx.2 = getelementptr inbounds double, double* %input1, i64 %add.2 1203 %30 = load double, double* %arrayidx.2, align 8 1204 %arrayidx2.2 = getelementptr inbounds double, double* %input2, i64 %add.2 1205 %31 = load double, double* %arrayidx2.2, align 8 1206 %mul3.2 = fmul double %30, %31 1207 %arrayidx5.2 = getelementptr inbounds double, double* %output, i64 %add.2 1208 %32 = load double, double* %arrayidx5.2, align 8 1209 %add6.2 = fadd double %32, %mul3.2 1210 store double %add6.2, double* %arrayidx5.2, align 8 1211 %add7.2 = add nsw i64 %add23.1, %inc2 1212 %arrayidx8.2 = getelementptr inbounds double, double* %input1, i64 %add7.2 1213 %33 = load double, double* %arrayidx8.2, align 8 1214 %arrayidx10.2 = getelementptr inbounds double, double* %input2, i64 %add7.2 1215 %34 = load double, double* %arrayidx10.2, align 8 1216 %mul11.2 = fmul double %33, %34 1217 %arrayidx13.2 = getelementptr inbounds double, double* %output, i64 %add7.2 1218 %35 = load double, double* %arrayidx13.2, align 8 1219 %add14.2 = fadd double %35, %mul11.2 1220 store double %add14.2, double* %arrayidx13.2, align 8 1221 %add15.2 = add nsw i64 %add23.1, %inc3 1222 %arrayidx16.2 = getelementptr inbounds double, double* %input1, i64 %add15.2 1223 %36 = load double, double* %arrayidx16.2, align 8 1224 %arrayidx18.2 = getelementptr inbounds double, double* %input2, i64 %add15.2 1225 %37 = load double, double* %arrayidx18.2, align 8 1226 %mul19.2 = fmul double %36, %37 1227 %arrayidx21.2 = getelementptr inbounds double, double* %output, i64 %add15.2 1228 %38 = load double, double* %arrayidx21.2, align 8 1229 %add22.2 = fadd double %38, %mul19.2 1230 store double %add22.2, double* %arrayidx21.2, align 8 1231 %add23.2 = add nsw i64 %add23.1, %inc4 1232 %add.3 = add nsw i64 %add23.2, %inc1 1233 %arrayidx.3 = getelementptr inbounds double, double* %input1, i64 %add.3 1234 %39 = load double, double* %arrayidx.3, align 8 1235 %arrayidx2.3 = getelementptr inbounds double, double* %input2, i64 %add.3 1236 %40 = load double, double* %arrayidx2.3, align 8 1237 %mul3.3 = fmul double %39, %40 1238 %arrayidx5.3 = getelementptr inbounds double, double* %output, i64 %add.3 1239 %41 = load double, double* %arrayidx5.3, align 8 1240 %add6.3 = fadd double %41, %mul3.3 1241 store double %add6.3, double* %arrayidx5.3, align 8 1242 %add7.3 = add nsw i64 %add23.2, %inc2 1243 %arrayidx8.3 = getelementptr inbounds double, double* %input1, i64 %add7.3 1244 %42 = load double, double* %arrayidx8.3, align 8 1245 %arrayidx10.3 = getelementptr inbounds double, double* %input2, i64 %add7.3 1246 %43 = load double, double* %arrayidx10.3, align 8 1247 %mul11.3 = fmul double %42, %43 1248 %arrayidx13.3 = getelementptr inbounds double, double* %output, i64 %add7.3 1249 %44 = load double, double* %arrayidx13.3, align 8 1250 %add14.3 = fadd double %44, %mul11.3 1251 store double %add14.3, double* %arrayidx13.3, align 8 1252 %add15.3 = add nsw i64 %add23.2, %inc3 1253 %arrayidx16.3 = getelementptr inbounds double, double* %input1, i64 %add15.3 1254 %45 = load double, double* %arrayidx16.3, align 8 1255 %arrayidx18.3 = getelementptr inbounds double, double* %input2, i64 %add15.3 1256 %46 = load double, double* %arrayidx18.3, align 8 1257 %mul19.3 = fmul double %45, %46 1258 %arrayidx21.3 = getelementptr inbounds double, double* %output, i64 %add15.3 1259 %47 = load double, double* %arrayidx21.3, align 8 1260 %add22.3 = fadd double %47, %mul19.3 1261 store double %add22.3, double* %arrayidx21.3, align 8 1262 %add23.3 = add nsw i64 %add23.2, %inc4 1263 %niter.nsub.3 = add i64 %niter, -4 1264 %niter.ncmp.3.not = icmp eq i64 %niter.nsub.3, 0 1265 br i1 %niter.ncmp.3.not, label %for.cond.cleanup.loopexit.unr-lcssa, label %for.body 1266} 1267 1268declare i64 @llvm.smax.i64(i64, i64) 1269 1270