[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / machine-combiner-copy.ll
blob15a484d11b0a1d05021518885ba5b63df1c168b6
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-linux-gnuabi -mattr=+fullfp16 -O3 | FileCheck %s
4 define void @fma_dup_f16(ptr noalias nocapture noundef readonly %A, half noundef %B, ptr noalias nocapture noundef %C, i32 noundef %n) {
5 ; CHECK-LABEL: fma_dup_f16:
6 ; CHECK:       // %bb.0: // %entry
7 ; CHECK-NEXT:    // kill: def $h0 killed $h0 def $q0
8 ; CHECK-NEXT:    cbz w2, .LBB0_8
9 ; CHECK-NEXT:  // %bb.1: // %for.body.preheader
10 ; CHECK-NEXT:    cmp w2, #15
11 ; CHECK-NEXT:    mov w8, w2
12 ; CHECK-NEXT:    b.hi .LBB0_3
13 ; CHECK-NEXT:  // %bb.2:
14 ; CHECK-NEXT:    mov x9, xzr
15 ; CHECK-NEXT:    b .LBB0_6
16 ; CHECK-NEXT:  .LBB0_3: // %vector.ph
17 ; CHECK-NEXT:    and x9, x8, #0xfffffff0
18 ; CHECK-NEXT:    add x10, x1, #16
19 ; CHECK-NEXT:    add x11, x0, #16
20 ; CHECK-NEXT:    mov x12, x9
21 ; CHECK-NEXT:  .LBB0_4: // %vector.body
22 ; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
23 ; CHECK-NEXT:    ldp q1, q3, [x11, #-16]
24 ; CHECK-NEXT:    subs x12, x12, #16
25 ; CHECK-NEXT:    ldp q2, q4, [x10, #-16]
26 ; CHECK-NEXT:    add x11, x11, #32
27 ; CHECK-NEXT:    fmla v2.8h, v1.8h, v0.h[0]
28 ; CHECK-NEXT:    fmla v4.8h, v3.8h, v0.h[0]
29 ; CHECK-NEXT:    stp q2, q4, [x10, #-16]
30 ; CHECK-NEXT:    add x10, x10, #32
31 ; CHECK-NEXT:    b.ne .LBB0_4
32 ; CHECK-NEXT:  // %bb.5: // %middle.block
33 ; CHECK-NEXT:    cmp x9, x8
34 ; CHECK-NEXT:    b.eq .LBB0_8
35 ; CHECK-NEXT:  .LBB0_6: // %for.body.preheader1
36 ; CHECK-NEXT:    lsl x10, x9, #1
37 ; CHECK-NEXT:    sub x8, x8, x9
38 ; CHECK-NEXT:    add x9, x1, x10
39 ; CHECK-NEXT:    add x10, x0, x10
40 ; CHECK-NEXT:  .LBB0_7: // %for.body
41 ; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
42 ; CHECK-NEXT:    ldr h1, [x10], #2
43 ; CHECK-NEXT:    ldr h2, [x9]
44 ; CHECK-NEXT:    subs x8, x8, #1
45 ; CHECK-NEXT:    fmadd h1, h1, h0, h2
46 ; CHECK-NEXT:    str h1, [x9], #2
47 ; CHECK-NEXT:    b.ne .LBB0_7
48 ; CHECK-NEXT:  .LBB0_8: // %for.cond.cleanup
49 ; CHECK-NEXT:    ret
50 entry:
51   %cmp6.not = icmp eq i32 %n, 0
52   br i1 %cmp6.not, label %for.cond.cleanup, label %for.body.preheader
54 for.body.preheader:                               ; preds = %entry
55   %wide.trip.count = zext i32 %n to i64
56   %min.iters.check = icmp ult i32 %n, 16
57   br i1 %min.iters.check, label %for.body.preheader14, label %vector.ph
59 vector.ph:                                        ; preds = %for.body.preheader
60   %n.vec = and i64 %wide.trip.count, 4294967280
61   %broadcast.splatinsert = insertelement <8 x half> poison, half %B, i64 0
62   %broadcast.splat = shufflevector <8 x half> %broadcast.splatinsert, <8 x half> poison, <8 x i32> zeroinitializer
63   %broadcast.splatinsert10 = insertelement <8 x half> poison, half %B, i64 0
64   %broadcast.splat11 = shufflevector <8 x half> %broadcast.splatinsert10, <8 x half> poison, <8 x i32> zeroinitializer
65   br label %vector.body
67 vector.body:                                      ; preds = %vector.body, %vector.ph
68   %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]
69   %0 = getelementptr inbounds half, ptr %A, i64 %index
70   %wide.load = load <8 x half>, ptr %0, align 2
71   %1 = getelementptr inbounds half, ptr %0, i64 8
72   %wide.load9 = load <8 x half>, ptr %1, align 2
73   %2 = fmul fast <8 x half> %wide.load, %broadcast.splat
74   %3 = fmul fast <8 x half> %wide.load9, %broadcast.splat11
75   %4 = getelementptr inbounds half, ptr %C, i64 %index
76   %wide.load12 = load <8 x half>, ptr %4, align 2
77   %5 = getelementptr inbounds half, ptr %4, i64 8
78   %wide.load13 = load <8 x half>, ptr %5, align 2
79   %6 = fadd fast <8 x half> %wide.load12, %2
80   %7 = fadd fast <8 x half> %wide.load13, %3
81   store <8 x half> %6, ptr %4, align 2
82   store <8 x half> %7, ptr %5, align 2
83   %index.next = add nuw i64 %index, 16
84   %8 = icmp eq i64 %index.next, %n.vec
85   br i1 %8, label %middle.block, label %vector.body
87 middle.block:                                     ; preds = %vector.body
88   %cmp.n = icmp eq i64 %n.vec, %wide.trip.count
89   br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader14
91 for.body.preheader14:                             ; preds = %for.body.preheader, %middle.block
92   %indvars.iv.ph = phi i64 [ 0, %for.body.preheader ], [ %n.vec, %middle.block ]
93   br label %for.body
95 for.cond.cleanup:                                 ; preds = %for.body, %middle.block, %entry
96   ret void
98 for.body:                                         ; preds = %for.body.preheader14, %for.body
99   %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader14 ]
100   %arrayidx = getelementptr inbounds half, ptr %A, i64 %indvars.iv
101   %9 = load half, ptr %arrayidx, align 2
102   %mul = fmul fast half %9, %B
103   %arrayidx2 = getelementptr inbounds half, ptr %C, i64 %indvars.iv
104   %10 = load half, ptr %arrayidx2, align 2
105   %add = fadd fast half %10, %mul
106   store half %add, ptr %arrayidx2, align 2
107   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
108   %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count
109   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body