795 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=aarch64 -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD,CHECK-SD-NOFP163; RUN: llc -mtriple=aarch64 -mattr=+fullfp16 -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD,CHECK-SD-FP164; RUN: llc -mtriple=aarch64 -global-isel -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI,CHECK-GI-NOFP165; RUN: llc -mtriple=aarch64 -mattr=+fullfp16 -global-isel -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI,CHECK-GI-FP166 7define float @add_HalfS(<2 x float> %bin.rdx) {8; CHECK-LABEL: add_HalfS:9; CHECK: // %bb.0:10; CHECK-NEXT: faddp s0, v0.2s11; CHECK-NEXT: ret12 %r = call fast float @llvm.vector.reduce.fadd.f32.v2f32(float -0.0, <2 x float> %bin.rdx)13 ret float %r14}15 16define half @add_v2HalfH(<2 x half> %bin.rdx) {17; CHECK-SD-NOFP16-LABEL: add_v2HalfH:18; CHECK-SD-NOFP16: // %bb.0:19; CHECK-SD-NOFP16-NEXT: // kill: def $d0 killed $d0 def $q020; CHECK-SD-NOFP16-NEXT: mov h1, v0.h[1]21; CHECK-SD-NOFP16-NEXT: fcvt s0, h022; CHECK-SD-NOFP16-NEXT: fcvt s1, h123; CHECK-SD-NOFP16-NEXT: fadd s0, s0, s124; CHECK-SD-NOFP16-NEXT: fcvt h0, s025; CHECK-SD-NOFP16-NEXT: ret26;27; CHECK-SD-FP16-LABEL: add_v2HalfH:28; CHECK-SD-FP16: // %bb.0:29; CHECK-SD-FP16-NEXT: // kill: def $d0 killed $d0 def $q030; CHECK-SD-FP16-NEXT: faddp h0, v0.2h31; CHECK-SD-FP16-NEXT: ret32;33; CHECK-GI-NOFP16-LABEL: add_v2HalfH:34; CHECK-GI-NOFP16: // %bb.0:35; CHECK-GI-NOFP16-NEXT: fcvtl v0.4s, v0.4h36; CHECK-GI-NOFP16-NEXT: faddp s0, v0.2s37; CHECK-GI-NOFP16-NEXT: fcvt h0, s038; CHECK-GI-NOFP16-NEXT: ret39;40; CHECK-GI-FP16-LABEL: add_v2HalfH:41; CHECK-GI-FP16: // %bb.0:42; CHECK-GI-FP16-NEXT: // kill: def $d0 killed $d0 def $q043; CHECK-GI-FP16-NEXT: mov h1, v0.h[1]44; CHECK-GI-FP16-NEXT: fadd h0, h0, h145; CHECK-GI-FP16-NEXT: ret46 %r = call fast half @llvm.vector.reduce.fadd.f16.v2f16(half -0.0, <2 x half> %bin.rdx)47 ret half %r48}49 50define half @add_v3HalfH(<3 x half> %bin.rdx) {51; CHECK-SD-NOFP16-LABEL: add_v3HalfH:52; CHECK-SD-NOFP16: // %bb.0:53; CHECK-SD-NOFP16-NEXT: // kill: def $d0 killed $d0 def $q054; CHECK-SD-NOFP16-NEXT: mov h1, v0.h[1]55; CHECK-SD-NOFP16-NEXT: fcvt s2, h056; CHECK-SD-NOFP16-NEXT: mov h0, v0.h[2]57; CHECK-SD-NOFP16-NEXT: fcvt s1, h158; CHECK-SD-NOFP16-NEXT: fcvt s0, h059; CHECK-SD-NOFP16-NEXT: fadd s1, s2, s160; CHECK-SD-NOFP16-NEXT: fadd s0, s1, s061; CHECK-SD-NOFP16-NEXT: fcvt h0, s062; CHECK-SD-NOFP16-NEXT: ret63;64; CHECK-SD-FP16-LABEL: add_v3HalfH:65; CHECK-SD-FP16: // %bb.0:66; CHECK-SD-FP16-NEXT: movi d1, #000000000000000067; CHECK-SD-FP16-NEXT: // kill: def $d0 killed $d0 def $q068; CHECK-SD-FP16-NEXT: mov v0.h[3], v1.h[0]69; CHECK-SD-FP16-NEXT: faddp v0.4h, v0.4h, v0.4h70; CHECK-SD-FP16-NEXT: faddp h0, v0.2h71; CHECK-SD-FP16-NEXT: ret72;73; CHECK-GI-NOFP16-LABEL: add_v3HalfH:74; CHECK-GI-NOFP16: // %bb.0:75; CHECK-GI-NOFP16-NEXT: movi v1.2s, #128, lsl #2476; CHECK-GI-NOFP16-NEXT: fcvtl v0.4s, v0.4h77; CHECK-GI-NOFP16-NEXT: mov v0.s[3], v1.s[0]78; CHECK-GI-NOFP16-NEXT: faddp v0.4s, v0.4s, v0.4s79; CHECK-GI-NOFP16-NEXT: faddp s0, v0.2s80; CHECK-GI-NOFP16-NEXT: fcvt h0, s081; CHECK-GI-NOFP16-NEXT: ret82;83; CHECK-GI-FP16-LABEL: add_v3HalfH:84; CHECK-GI-FP16: // %bb.0:85; CHECK-GI-FP16-NEXT: adrp x8, .LCPI2_086; CHECK-GI-FP16-NEXT: // kill: def $d0 killed $d0 def $q087; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI2_0]88; CHECK-GI-FP16-NEXT: mov v0.h[3], v1.h[0]89; CHECK-GI-FP16-NEXT: faddp v0.4h, v0.4h, v0.4h90; CHECK-GI-FP16-NEXT: faddp h0, v0.2h91; CHECK-GI-FP16-NEXT: ret92 %r = call fast half @llvm.vector.reduce.fadd.f16.v3f16(half -0.0, <3 x half> %bin.rdx)93 ret half %r94}95 96define half @add_HalfH(<4 x half> %bin.rdx) {97; CHECK-SD-NOFP16-LABEL: add_HalfH:98; CHECK-SD-NOFP16: // %bb.0:99; CHECK-SD-NOFP16-NEXT: // kill: def $d0 killed $d0 def $q0100; CHECK-SD-NOFP16-NEXT: mov h1, v0.h[1]101; CHECK-SD-NOFP16-NEXT: mov h2, v0.h[3]102; CHECK-SD-NOFP16-NEXT: mov h3, v0.h[2]103; CHECK-SD-NOFP16-NEXT: fcvt s0, h0104; CHECK-SD-NOFP16-NEXT: fcvt s1, h1105; CHECK-SD-NOFP16-NEXT: fcvt s3, h3106; CHECK-SD-NOFP16-NEXT: fcvt s2, h2107; CHECK-SD-NOFP16-NEXT: fadd s0, s0, s1108; CHECK-SD-NOFP16-NEXT: fadd s1, s3, s2109; CHECK-SD-NOFP16-NEXT: fadd s0, s0, s1110; CHECK-SD-NOFP16-NEXT: fcvt h0, s0111; CHECK-SD-NOFP16-NEXT: ret112;113; CHECK-SD-FP16-LABEL: add_HalfH:114; CHECK-SD-FP16: // %bb.0:115; CHECK-SD-FP16-NEXT: faddp v0.4h, v0.4h, v0.4h116; CHECK-SD-FP16-NEXT: faddp h0, v0.2h117; CHECK-SD-FP16-NEXT: ret118;119; CHECK-GI-NOFP16-LABEL: add_HalfH:120; CHECK-GI-NOFP16: // %bb.0:121; CHECK-GI-NOFP16-NEXT: fcvtl v0.4s, v0.4h122; CHECK-GI-NOFP16-NEXT: faddp v0.4s, v0.4s, v0.4s123; CHECK-GI-NOFP16-NEXT: faddp s0, v0.2s124; CHECK-GI-NOFP16-NEXT: fcvt h0, s0125; CHECK-GI-NOFP16-NEXT: ret126;127; CHECK-GI-FP16-LABEL: add_HalfH:128; CHECK-GI-FP16: // %bb.0:129; CHECK-GI-FP16-NEXT: faddp v0.4h, v0.4h, v0.4h130; CHECK-GI-FP16-NEXT: faddp h0, v0.2h131; CHECK-GI-FP16-NEXT: ret132 %r = call fast half @llvm.vector.reduce.fadd.f16.v4f16(half -0.0, <4 x half> %bin.rdx)133 ret half %r134}135 136 137define half @add_H(<8 x half> %bin.rdx) {138; CHECK-SD-NOFP16-LABEL: add_H:139; CHECK-SD-NOFP16: // %bb.0:140; CHECK-SD-NOFP16-NEXT: mov h1, v0.h[2]141; CHECK-SD-NOFP16-NEXT: mov h2, v0.h[1]142; CHECK-SD-NOFP16-NEXT: mov h3, v0.h[5]143; CHECK-SD-NOFP16-NEXT: mov h4, v0.h[4]144; CHECK-SD-NOFP16-NEXT: mov h5, v0.h[3]145; CHECK-SD-NOFP16-NEXT: mov h6, v0.h[6]146; CHECK-SD-NOFP16-NEXT: fcvt s7, h0147; CHECK-SD-NOFP16-NEXT: mov h0, v0.h[7]148; CHECK-SD-NOFP16-NEXT: fcvt s2, h2149; CHECK-SD-NOFP16-NEXT: fcvt s1, h1150; CHECK-SD-NOFP16-NEXT: fcvt s3, h3151; CHECK-SD-NOFP16-NEXT: fcvt s5, h5152; CHECK-SD-NOFP16-NEXT: fcvt s4, h4153; CHECK-SD-NOFP16-NEXT: fcvt s0, h0154; CHECK-SD-NOFP16-NEXT: fadd s2, s7, s2155; CHECK-SD-NOFP16-NEXT: fadd s1, s1, s5156; CHECK-SD-NOFP16-NEXT: fadd s3, s4, s3157; CHECK-SD-NOFP16-NEXT: fcvt s4, h6158; CHECK-SD-NOFP16-NEXT: fadd s1, s2, s1159; CHECK-SD-NOFP16-NEXT: fadd s2, s3, s4160; CHECK-SD-NOFP16-NEXT: fadd s1, s1, s2161; CHECK-SD-NOFP16-NEXT: fadd s0, s1, s0162; CHECK-SD-NOFP16-NEXT: fcvt h0, s0163; CHECK-SD-NOFP16-NEXT: ret164;165; CHECK-SD-FP16-LABEL: add_H:166; CHECK-SD-FP16: // %bb.0:167; CHECK-SD-FP16-NEXT: faddp v1.8h, v0.8h, v0.8h168; CHECK-SD-FP16-NEXT: faddp v0.8h, v1.8h, v0.8h169; CHECK-SD-FP16-NEXT: faddp h0, v0.2h170; CHECK-SD-FP16-NEXT: ret171;172; CHECK-GI-NOFP16-LABEL: add_H:173; CHECK-GI-NOFP16: // %bb.0:174; CHECK-GI-NOFP16-NEXT: fcvtl v1.4s, v0.4h175; CHECK-GI-NOFP16-NEXT: fcvtl2 v0.4s, v0.8h176; CHECK-GI-NOFP16-NEXT: fadd v0.4s, v1.4s, v0.4s177; CHECK-GI-NOFP16-NEXT: faddp v0.4s, v0.4s, v0.4s178; CHECK-GI-NOFP16-NEXT: faddp s0, v0.2s179; CHECK-GI-NOFP16-NEXT: fcvt h0, s0180; CHECK-GI-NOFP16-NEXT: ret181;182; CHECK-GI-FP16-LABEL: add_H:183; CHECK-GI-FP16: // %bb.0:184; CHECK-GI-FP16-NEXT: faddp v1.8h, v0.8h, v0.8h185; CHECK-GI-FP16-NEXT: faddp v0.8h, v1.8h, v0.8h186; CHECK-GI-FP16-NEXT: faddp h0, v0.2h187; CHECK-GI-FP16-NEXT: ret188 %r = call fast half @llvm.vector.reduce.fadd.f16.v8f16(half -0.0, <8 x half> %bin.rdx)189 ret half %r190}191 192define float @add_S(<4 x float> %bin.rdx) {193; CHECK-LABEL: add_S:194; CHECK: // %bb.0:195; CHECK-NEXT: faddp v0.4s, v0.4s, v0.4s196; CHECK-NEXT: faddp s0, v0.2s197; CHECK-NEXT: ret198 %r = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float -0.0, <4 x float> %bin.rdx)199 ret float %r200}201 202define double @add_D(<2 x double> %bin.rdx) {203; CHECK-LABEL: add_D:204; CHECK: // %bb.0:205; CHECK-NEXT: faddp d0, v0.2d206; CHECK-NEXT: ret207 %r = call fast double @llvm.vector.reduce.fadd.f64.v2f64(double -0.0, <2 x double> %bin.rdx)208 ret double %r209}210 211define double @add_D_pos0(<2 x double> %bin.rdx) {212; CHECK-LABEL: add_D_pos0:213; CHECK: // %bb.0:214; CHECK-NEXT: faddp d0, v0.2d215; CHECK-NEXT: ret216 %r = call fast double @llvm.vector.reduce.fadd.f64.v2f64(double 0.0, <2 x double> %bin.rdx)217 ret double %r218}219 220define half @add_2H(<16 x half> %bin.rdx) {221; CHECK-SD-NOFP16-LABEL: add_2H:222; CHECK-SD-NOFP16: // %bb.0:223; CHECK-SD-NOFP16-NEXT: fcvtl v2.4s, v1.4h224; CHECK-SD-NOFP16-NEXT: fcvtl v3.4s, v0.4h225; CHECK-SD-NOFP16-NEXT: fcvtl2 v1.4s, v1.8h226; CHECK-SD-NOFP16-NEXT: fcvtl2 v0.4s, v0.8h227; CHECK-SD-NOFP16-NEXT: fadd v2.4s, v3.4s, v2.4s228; CHECK-SD-NOFP16-NEXT: fadd v0.4s, v0.4s, v1.4s229; CHECK-SD-NOFP16-NEXT: fcvtn v1.4h, v2.4s230; CHECK-SD-NOFP16-NEXT: fcvtn2 v1.8h, v0.4s231; CHECK-SD-NOFP16-NEXT: mov h0, v1.h[1]232; CHECK-SD-NOFP16-NEXT: mov h2, v1.h[2]233; CHECK-SD-NOFP16-NEXT: mov h3, v1.h[3]234; CHECK-SD-NOFP16-NEXT: mov h4, v1.h[4]235; CHECK-SD-NOFP16-NEXT: mov h5, v1.h[5]236; CHECK-SD-NOFP16-NEXT: fcvt s6, h1237; CHECK-SD-NOFP16-NEXT: mov h7, v1.h[6]238; CHECK-SD-NOFP16-NEXT: mov h1, v1.h[7]239; CHECK-SD-NOFP16-NEXT: fcvt s0, h0240; CHECK-SD-NOFP16-NEXT: fcvt s2, h2241; CHECK-SD-NOFP16-NEXT: fcvt s3, h3242; CHECK-SD-NOFP16-NEXT: fcvt s4, h4243; CHECK-SD-NOFP16-NEXT: fcvt s5, h5244; CHECK-SD-NOFP16-NEXT: fcvt s1, h1245; CHECK-SD-NOFP16-NEXT: fadd s0, s6, s0246; CHECK-SD-NOFP16-NEXT: fadd s2, s2, s3247; CHECK-SD-NOFP16-NEXT: fadd s3, s4, s5248; CHECK-SD-NOFP16-NEXT: fcvt s4, h7249; CHECK-SD-NOFP16-NEXT: fadd s0, s0, s2250; CHECK-SD-NOFP16-NEXT: fadd s2, s3, s4251; CHECK-SD-NOFP16-NEXT: fadd s0, s0, s2252; CHECK-SD-NOFP16-NEXT: fadd s0, s0, s1253; CHECK-SD-NOFP16-NEXT: fcvt h0, s0254; CHECK-SD-NOFP16-NEXT: ret255;256; CHECK-SD-FP16-LABEL: add_2H:257; CHECK-SD-FP16: // %bb.0:258; CHECK-SD-FP16-NEXT: fadd v0.8h, v0.8h, v1.8h259; CHECK-SD-FP16-NEXT: faddp v1.8h, v0.8h, v0.8h260; CHECK-SD-FP16-NEXT: faddp v0.8h, v1.8h, v0.8h261; CHECK-SD-FP16-NEXT: faddp h0, v0.2h262; CHECK-SD-FP16-NEXT: ret263;264; CHECK-GI-NOFP16-LABEL: add_2H:265; CHECK-GI-NOFP16: // %bb.0:266; CHECK-GI-NOFP16-NEXT: fcvtl v2.4s, v0.4h267; CHECK-GI-NOFP16-NEXT: fcvtl2 v0.4s, v0.8h268; CHECK-GI-NOFP16-NEXT: fcvtl v3.4s, v1.4h269; CHECK-GI-NOFP16-NEXT: fcvtl2 v1.4s, v1.8h270; CHECK-GI-NOFP16-NEXT: fadd v0.4s, v2.4s, v0.4s271; CHECK-GI-NOFP16-NEXT: fadd v1.4s, v3.4s, v1.4s272; CHECK-GI-NOFP16-NEXT: fadd v0.4s, v0.4s, v1.4s273; CHECK-GI-NOFP16-NEXT: faddp v0.4s, v0.4s, v0.4s274; CHECK-GI-NOFP16-NEXT: faddp s0, v0.2s275; CHECK-GI-NOFP16-NEXT: fcvt h0, s0276; CHECK-GI-NOFP16-NEXT: ret277;278; CHECK-GI-FP16-LABEL: add_2H:279; CHECK-GI-FP16: // %bb.0:280; CHECK-GI-FP16-NEXT: fadd v0.8h, v0.8h, v1.8h281; CHECK-GI-FP16-NEXT: faddp v1.8h, v0.8h, v0.8h282; CHECK-GI-FP16-NEXT: faddp v0.8h, v1.8h, v0.8h283; CHECK-GI-FP16-NEXT: faddp h0, v0.2h284; CHECK-GI-FP16-NEXT: ret285 %r = call fast half @llvm.vector.reduce.fadd.f16.v16f16(half -0.0, <16 x half> %bin.rdx)286 ret half %r287}288 289define float @add_2S(<8 x float> %bin.rdx) {290; CHECK-LABEL: add_2S:291; CHECK: // %bb.0:292; CHECK-NEXT: fadd v0.4s, v0.4s, v1.4s293; CHECK-NEXT: faddp v0.4s, v0.4s, v0.4s294; CHECK-NEXT: faddp s0, v0.2s295; CHECK-NEXT: ret296 %r = call fast float @llvm.vector.reduce.fadd.f32.v8f32(float -0.0, <8 x float> %bin.rdx)297 ret float %r298}299 300define double @add_2D(<4 x double> %bin.rdx) {301; CHECK-LABEL: add_2D:302; CHECK: // %bb.0:303; CHECK-NEXT: fadd v0.2d, v0.2d, v1.2d304; CHECK-NEXT: faddp d0, v0.2d305; CHECK-NEXT: ret306 %r = call fast double @llvm.vector.reduce.fadd.f64.v4f64(double -0.0, <4 x double> %bin.rdx)307 ret double %r308}309 310; Added at least one test where the start value is not -0.0.311define float @add_S_init_42(<4 x float> %bin.rdx) {312; CHECK-LABEL: add_S_init_42:313; CHECK: // %bb.0:314; CHECK-NEXT: faddp v0.4s, v0.4s, v0.4s315; CHECK-NEXT: mov w8, #1109917696 // =0x42280000316; CHECK-NEXT: fmov s1, w8317; CHECK-NEXT: faddp s0, v0.2s318; CHECK-NEXT: fadd s0, s0, s1319; CHECK-NEXT: ret320 %r = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float 42.0, <4 x float> %bin.rdx)321 ret float %r322}323 324; The faddp.4s in the loop should not use v0.4s as second operand,325; because this introduces an unnecessary cross-iteration dependency.326define float @fadd_reduction_v4f32_in_loop(ptr %ptr.start) {327; CHECK-LABEL: fadd_reduction_v4f32_in_loop:328; CHECK: // %bb.0: // %entry329; CHECK-NEXT: movi d0, #0000000000000000330; CHECK-NEXT: mov x8, xzr331; CHECK-NEXT: .LBB12_1: // %loop332; CHECK-NEXT: // =>This Inner Loop Header: Depth=1333; CHECK-NEXT: ldr q1, [x0, x8]334; CHECK-NEXT: add x8, x8, #16335; CHECK-NEXT: cmp w8, #112336; CHECK-NEXT: faddp v1.4s, v1.4s, v1.4s337; CHECK-NEXT: faddp s1, v1.2s338; CHECK-NEXT: fadd s0, s1, s0339; CHECK-NEXT: b.ne .LBB12_1340; CHECK-NEXT: // %bb.2: // %exit341; CHECK-NEXT: ret342entry:343 br label %loop344 345loop:346 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop ]347 %ptr = phi ptr [ %ptr.start, %entry ], [ %ptr.next, %loop ]348 %red = phi float [ 0.000000e+00, %entry ], [ %red.next, %loop ]349 %lv = load <4 x float>, ptr %ptr, align 4350 %r = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float -0.0, <4 x float> %lv)351 %red.next = fadd fast float %r, %red352 %ec = icmp eq i32 %iv, 7353 %ptr.next = getelementptr inbounds float, ptr %ptr, i64 4354 %iv.next= add nuw nsw i32 %iv, 1355 br i1 %ec, label %exit, label %loop356 357exit:358 ret float %red.next359}360 361; The faddp.4h in the loop should not use v0.4h as second operand,362; because this introduces an unnecessary cross-iteration dependency.363define half @fadd_reduction_v4f16_in_loop(ptr %ptr.start) {364; CHECK-SD-NOFP16-LABEL: fadd_reduction_v4f16_in_loop:365; CHECK-SD-NOFP16: // %bb.0: // %entry366; CHECK-SD-NOFP16-NEXT: movi d0, #0000000000000000367; CHECK-SD-NOFP16-NEXT: mov x8, xzr368; CHECK-SD-NOFP16-NEXT: .LBB13_1: // %loop369; CHECK-SD-NOFP16-NEXT: // =>This Inner Loop Header: Depth=1370; CHECK-SD-NOFP16-NEXT: ldr d1, [x0, x8]371; CHECK-SD-NOFP16-NEXT: fcvt s0, h0372; CHECK-SD-NOFP16-NEXT: add x8, x8, #8373; CHECK-SD-NOFP16-NEXT: cmp w8, #56374; CHECK-SD-NOFP16-NEXT: mov h2, v1.h[1]375; CHECK-SD-NOFP16-NEXT: mov h3, v1.h[3]376; CHECK-SD-NOFP16-NEXT: mov h4, v1.h[2]377; CHECK-SD-NOFP16-NEXT: fcvt s1, h1378; CHECK-SD-NOFP16-NEXT: fcvt s2, h2379; CHECK-SD-NOFP16-NEXT: fcvt s4, h4380; CHECK-SD-NOFP16-NEXT: fcvt s3, h3381; CHECK-SD-NOFP16-NEXT: fadd s1, s1, s2382; CHECK-SD-NOFP16-NEXT: fadd s2, s4, s3383; CHECK-SD-NOFP16-NEXT: fadd s1, s1, s2384; CHECK-SD-NOFP16-NEXT: fadd s0, s1, s0385; CHECK-SD-NOFP16-NEXT: fcvt h0, s0386; CHECK-SD-NOFP16-NEXT: b.ne .LBB13_1387; CHECK-SD-NOFP16-NEXT: // %bb.2: // %exit388; CHECK-SD-NOFP16-NEXT: ret389;390; CHECK-SD-FP16-LABEL: fadd_reduction_v4f16_in_loop:391; CHECK-SD-FP16: // %bb.0: // %entry392; CHECK-SD-FP16-NEXT: movi d0, #0000000000000000393; CHECK-SD-FP16-NEXT: mov x8, xzr394; CHECK-SD-FP16-NEXT: .LBB13_1: // %loop395; CHECK-SD-FP16-NEXT: // =>This Inner Loop Header: Depth=1396; CHECK-SD-FP16-NEXT: ldr d1, [x0, x8]397; CHECK-SD-FP16-NEXT: add x8, x8, #8398; CHECK-SD-FP16-NEXT: cmp w8, #56399; CHECK-SD-FP16-NEXT: faddp v1.4h, v1.4h, v1.4h400; CHECK-SD-FP16-NEXT: faddp h1, v1.2h401; CHECK-SD-FP16-NEXT: fadd h0, h1, h0402; CHECK-SD-FP16-NEXT: b.ne .LBB13_1403; CHECK-SD-FP16-NEXT: // %bb.2: // %exit404; CHECK-SD-FP16-NEXT: ret405;406; CHECK-GI-NOFP16-LABEL: fadd_reduction_v4f16_in_loop:407; CHECK-GI-NOFP16: // %bb.0: // %entry408; CHECK-GI-NOFP16-NEXT: movi d0, #0000000000000000409; CHECK-GI-NOFP16-NEXT: mov x8, xzr410; CHECK-GI-NOFP16-NEXT: .LBB13_1: // %loop411; CHECK-GI-NOFP16-NEXT: // =>This Inner Loop Header: Depth=1412; CHECK-GI-NOFP16-NEXT: ldr d1, [x0, x8]413; CHECK-GI-NOFP16-NEXT: fcvt s0, h0414; CHECK-GI-NOFP16-NEXT: add x8, x8, #8415; CHECK-GI-NOFP16-NEXT: cmp w8, #56416; CHECK-GI-NOFP16-NEXT: fcvtl v1.4s, v1.4h417; CHECK-GI-NOFP16-NEXT: faddp v1.4s, v1.4s, v1.4s418; CHECK-GI-NOFP16-NEXT: faddp s1, v1.2s419; CHECK-GI-NOFP16-NEXT: fcvt h1, s1420; CHECK-GI-NOFP16-NEXT: fcvt s1, h1421; CHECK-GI-NOFP16-NEXT: fadd s0, s1, s0422; CHECK-GI-NOFP16-NEXT: fcvt h0, s0423; CHECK-GI-NOFP16-NEXT: b.ne .LBB13_1424; CHECK-GI-NOFP16-NEXT: // %bb.2: // %exit425; CHECK-GI-NOFP16-NEXT: ret426;427; CHECK-GI-FP16-LABEL: fadd_reduction_v4f16_in_loop:428; CHECK-GI-FP16: // %bb.0: // %entry429; CHECK-GI-FP16-NEXT: movi d0, #0000000000000000430; CHECK-GI-FP16-NEXT: mov x8, xzr431; CHECK-GI-FP16-NEXT: .LBB13_1: // %loop432; CHECK-GI-FP16-NEXT: // =>This Inner Loop Header: Depth=1433; CHECK-GI-FP16-NEXT: ldr d1, [x0, x8]434; CHECK-GI-FP16-NEXT: add x8, x8, #8435; CHECK-GI-FP16-NEXT: cmp w8, #56436; CHECK-GI-FP16-NEXT: faddp v1.4h, v1.4h, v1.4h437; CHECK-GI-FP16-NEXT: faddp h1, v1.2h438; CHECK-GI-FP16-NEXT: fadd h0, h1, h0439; CHECK-GI-FP16-NEXT: b.ne .LBB13_1440; CHECK-GI-FP16-NEXT: // %bb.2: // %exit441; CHECK-GI-FP16-NEXT: ret442entry:443 br label %loop444 445loop:446 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop ]447 %ptr = phi ptr [ %ptr.start, %entry ], [ %ptr.next, %loop ]448 %red = phi half [ 0.000000e+00, %entry ], [ %red.next, %loop ]449 %lv = load <4 x half>, ptr %ptr, align 4450 %r = call fast half @llvm.vector.reduce.fadd.f16.v4f16(half -0.0, <4 x half> %lv)451 %red.next = fadd fast half %r, %red452 %ec = icmp eq i32 %iv, 7453 %ptr.next = getelementptr inbounds half, ptr %ptr, i64 4454 %iv.next= add nuw nsw i32 %iv, 1455 br i1 %ec, label %exit, label %loop456 457exit:458 ret half %red.next459}460 461; The faddp.8h in the loop should not use v0.8h as second operand,462; because this introduces an unnecessary cross-iteration dependency.463define half @fadd_reduction_v8f16_in_loop(ptr %ptr.start) {464; CHECK-SD-NOFP16-LABEL: fadd_reduction_v8f16_in_loop:465; CHECK-SD-NOFP16: // %bb.0: // %entry466; CHECK-SD-NOFP16-NEXT: movi d0, #0000000000000000467; CHECK-SD-NOFP16-NEXT: mov x8, xzr468; CHECK-SD-NOFP16-NEXT: .LBB14_1: // %loop469; CHECK-SD-NOFP16-NEXT: // =>This Inner Loop Header: Depth=1470; CHECK-SD-NOFP16-NEXT: ldr q1, [x0, x8]471; CHECK-SD-NOFP16-NEXT: fcvt s0, h0472; CHECK-SD-NOFP16-NEXT: add x8, x8, #8473; CHECK-SD-NOFP16-NEXT: cmp w8, #56474; CHECK-SD-NOFP16-NEXT: mov h2, v1.h[3]475; CHECK-SD-NOFP16-NEXT: mov h3, v1.h[2]476; CHECK-SD-NOFP16-NEXT: mov h4, v1.h[1]477; CHECK-SD-NOFP16-NEXT: mov h5, v1.h[5]478; CHECK-SD-NOFP16-NEXT: mov h6, v1.h[4]479; CHECK-SD-NOFP16-NEXT: fcvt s7, h1480; CHECK-SD-NOFP16-NEXT: mov h16, v1.h[6]481; CHECK-SD-NOFP16-NEXT: mov h1, v1.h[7]482; CHECK-SD-NOFP16-NEXT: fcvt s4, h4483; CHECK-SD-NOFP16-NEXT: fcvt s3, h3484; CHECK-SD-NOFP16-NEXT: fcvt s2, h2485; CHECK-SD-NOFP16-NEXT: fcvt s6, h6486; CHECK-SD-NOFP16-NEXT: fcvt s5, h5487; CHECK-SD-NOFP16-NEXT: fcvt s1, h1488; CHECK-SD-NOFP16-NEXT: fadd s4, s7, s4489; CHECK-SD-NOFP16-NEXT: fadd s2, s3, s2490; CHECK-SD-NOFP16-NEXT: fcvt s3, h16491; CHECK-SD-NOFP16-NEXT: fadd s5, s6, s5492; CHECK-SD-NOFP16-NEXT: fadd s0, s1, s0493; CHECK-SD-NOFP16-NEXT: fadd s2, s4, s2494; CHECK-SD-NOFP16-NEXT: fadd s3, s5, s3495; CHECK-SD-NOFP16-NEXT: fadd s2, s2, s3496; CHECK-SD-NOFP16-NEXT: fadd s0, s2, s0497; CHECK-SD-NOFP16-NEXT: fcvt h0, s0498; CHECK-SD-NOFP16-NEXT: b.ne .LBB14_1499; CHECK-SD-NOFP16-NEXT: // %bb.2: // %exit500; CHECK-SD-NOFP16-NEXT: ret501;502; CHECK-SD-FP16-LABEL: fadd_reduction_v8f16_in_loop:503; CHECK-SD-FP16: // %bb.0: // %entry504; CHECK-SD-FP16-NEXT: movi d0, #0000000000000000505; CHECK-SD-FP16-NEXT: mov x8, xzr506; CHECK-SD-FP16-NEXT: .LBB14_1: // %loop507; CHECK-SD-FP16-NEXT: // =>This Inner Loop Header: Depth=1508; CHECK-SD-FP16-NEXT: ldr q1, [x0, x8]509; CHECK-SD-FP16-NEXT: add x8, x8, #8510; CHECK-SD-FP16-NEXT: cmp w8, #56511; CHECK-SD-FP16-NEXT: faddp v2.8h, v1.8h, v1.8h512; CHECK-SD-FP16-NEXT: faddp v1.8h, v2.8h, v1.8h513; CHECK-SD-FP16-NEXT: faddp h1, v1.2h514; CHECK-SD-FP16-NEXT: fadd h0, h1, h0515; CHECK-SD-FP16-NEXT: b.ne .LBB14_1516; CHECK-SD-FP16-NEXT: // %bb.2: // %exit517; CHECK-SD-FP16-NEXT: ret518;519; CHECK-GI-NOFP16-LABEL: fadd_reduction_v8f16_in_loop:520; CHECK-GI-NOFP16: // %bb.0: // %entry521; CHECK-GI-NOFP16-NEXT: movi d0, #0000000000000000522; CHECK-GI-NOFP16-NEXT: mov x8, xzr523; CHECK-GI-NOFP16-NEXT: .LBB14_1: // %loop524; CHECK-GI-NOFP16-NEXT: // =>This Inner Loop Header: Depth=1525; CHECK-GI-NOFP16-NEXT: ldr q1, [x0, x8]526; CHECK-GI-NOFP16-NEXT: fcvt s0, h0527; CHECK-GI-NOFP16-NEXT: add x8, x8, #8528; CHECK-GI-NOFP16-NEXT: cmp w8, #56529; CHECK-GI-NOFP16-NEXT: fcvtl v2.4s, v1.4h530; CHECK-GI-NOFP16-NEXT: fcvtl2 v1.4s, v1.8h531; CHECK-GI-NOFP16-NEXT: fadd v1.4s, v2.4s, v1.4s532; CHECK-GI-NOFP16-NEXT: faddp v1.4s, v1.4s, v1.4s533; CHECK-GI-NOFP16-NEXT: faddp s1, v1.2s534; CHECK-GI-NOFP16-NEXT: fcvt h1, s1535; CHECK-GI-NOFP16-NEXT: fcvt s1, h1536; CHECK-GI-NOFP16-NEXT: fadd s0, s1, s0537; CHECK-GI-NOFP16-NEXT: fcvt h0, s0538; CHECK-GI-NOFP16-NEXT: b.ne .LBB14_1539; CHECK-GI-NOFP16-NEXT: // %bb.2: // %exit540; CHECK-GI-NOFP16-NEXT: ret541;542; CHECK-GI-FP16-LABEL: fadd_reduction_v8f16_in_loop:543; CHECK-GI-FP16: // %bb.0: // %entry544; CHECK-GI-FP16-NEXT: movi d0, #0000000000000000545; CHECK-GI-FP16-NEXT: mov x8, xzr546; CHECK-GI-FP16-NEXT: .LBB14_1: // %loop547; CHECK-GI-FP16-NEXT: // =>This Inner Loop Header: Depth=1548; CHECK-GI-FP16-NEXT: ldr q1, [x0, x8]549; CHECK-GI-FP16-NEXT: add x8, x8, #8550; CHECK-GI-FP16-NEXT: cmp w8, #56551; CHECK-GI-FP16-NEXT: faddp v2.8h, v1.8h, v1.8h552; CHECK-GI-FP16-NEXT: faddp v1.8h, v2.8h, v1.8h553; CHECK-GI-FP16-NEXT: faddp h1, v1.2h554; CHECK-GI-FP16-NEXT: fadd h0, h1, h0555; CHECK-GI-FP16-NEXT: b.ne .LBB14_1556; CHECK-GI-FP16-NEXT: // %bb.2: // %exit557; CHECK-GI-FP16-NEXT: ret558entry:559 br label %loop560 561loop:562 %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop ]563 %ptr = phi ptr [ %ptr.start, %entry ], [ %ptr.next, %loop ]564 %red = phi half [ 0.000000e+00, %entry ], [ %red.next, %loop ]565 %lv = load <8 x half>, ptr %ptr, align 4566 %r = call fast half @llvm.vector.reduce.fadd.f16.v8f16(half -0.0, <8 x half> %lv)567 %red.next = fadd fast half %r, %red568 %ec = icmp eq i32 %iv, 7569 %ptr.next = getelementptr inbounds half, ptr %ptr, i64 4570 %iv.next= add nuw nsw i32 %iv, 1571 br i1 %ec, label %exit, label %loop572 573exit:574 ret half %red.next575}576 577 578define half @fadd_reduct_reassoc_v8f16(<8 x half> %a, <8 x half> %b) {579; CHECK-SD-NOFP16-LABEL: fadd_reduct_reassoc_v8f16:580; CHECK-SD-NOFP16: // %bb.0:581; CHECK-SD-NOFP16-NEXT: fcvtl v2.4s, v1.4h582; CHECK-SD-NOFP16-NEXT: fcvtl v3.4s, v0.4h583; CHECK-SD-NOFP16-NEXT: fcvtl2 v1.4s, v1.8h584; CHECK-SD-NOFP16-NEXT: fcvtl2 v0.4s, v0.8h585; CHECK-SD-NOFP16-NEXT: fadd v2.4s, v3.4s, v2.4s586; CHECK-SD-NOFP16-NEXT: fadd v0.4s, v0.4s, v1.4s587; CHECK-SD-NOFP16-NEXT: fcvtn v1.4h, v2.4s588; CHECK-SD-NOFP16-NEXT: fcvtn2 v1.8h, v0.4s589; CHECK-SD-NOFP16-NEXT: mov h0, v1.h[1]590; CHECK-SD-NOFP16-NEXT: mov h2, v1.h[2]591; CHECK-SD-NOFP16-NEXT: mov h3, v1.h[3]592; CHECK-SD-NOFP16-NEXT: mov h4, v1.h[4]593; CHECK-SD-NOFP16-NEXT: mov h5, v1.h[5]594; CHECK-SD-NOFP16-NEXT: fcvt s6, h1595; CHECK-SD-NOFP16-NEXT: mov h7, v1.h[6]596; CHECK-SD-NOFP16-NEXT: mov h1, v1.h[7]597; CHECK-SD-NOFP16-NEXT: fcvt s0, h0598; CHECK-SD-NOFP16-NEXT: fcvt s2, h2599; CHECK-SD-NOFP16-NEXT: fcvt s3, h3600; CHECK-SD-NOFP16-NEXT: fcvt s4, h4601; CHECK-SD-NOFP16-NEXT: fcvt s5, h5602; CHECK-SD-NOFP16-NEXT: fcvt s1, h1603; CHECK-SD-NOFP16-NEXT: fadd s0, s6, s0604; CHECK-SD-NOFP16-NEXT: fadd s2, s2, s3605; CHECK-SD-NOFP16-NEXT: fadd s3, s4, s5606; CHECK-SD-NOFP16-NEXT: fcvt s4, h7607; CHECK-SD-NOFP16-NEXT: fadd s0, s0, s2608; CHECK-SD-NOFP16-NEXT: fadd s2, s3, s4609; CHECK-SD-NOFP16-NEXT: fadd s0, s0, s2610; CHECK-SD-NOFP16-NEXT: fadd s0, s0, s1611; CHECK-SD-NOFP16-NEXT: fcvt h0, s0612; CHECK-SD-NOFP16-NEXT: ret613;614; CHECK-SD-FP16-LABEL: fadd_reduct_reassoc_v8f16:615; CHECK-SD-FP16: // %bb.0:616; CHECK-SD-FP16-NEXT: fadd v0.8h, v0.8h, v1.8h617; CHECK-SD-FP16-NEXT: faddp v1.8h, v0.8h, v0.8h618; CHECK-SD-FP16-NEXT: faddp v0.8h, v1.8h, v0.8h619; CHECK-SD-FP16-NEXT: faddp h0, v0.2h620; CHECK-SD-FP16-NEXT: ret621;622; CHECK-GI-NOFP16-LABEL: fadd_reduct_reassoc_v8f16:623; CHECK-GI-NOFP16: // %bb.0:624; CHECK-GI-NOFP16-NEXT: fcvtl v2.4s, v0.4h625; CHECK-GI-NOFP16-NEXT: fcvtl2 v0.4s, v0.8h626; CHECK-GI-NOFP16-NEXT: fcvtl v3.4s, v1.4h627; CHECK-GI-NOFP16-NEXT: fcvtl2 v1.4s, v1.8h628; CHECK-GI-NOFP16-NEXT: fadd v0.4s, v2.4s, v0.4s629; CHECK-GI-NOFP16-NEXT: fadd v1.4s, v3.4s, v1.4s630; CHECK-GI-NOFP16-NEXT: faddp v0.4s, v0.4s, v0.4s631; CHECK-GI-NOFP16-NEXT: faddp v1.4s, v1.4s, v1.4s632; CHECK-GI-NOFP16-NEXT: faddp s0, v0.2s633; CHECK-GI-NOFP16-NEXT: faddp s1, v1.2s634; CHECK-GI-NOFP16-NEXT: fcvt h0, s0635; CHECK-GI-NOFP16-NEXT: fcvt h1, s1636; CHECK-GI-NOFP16-NEXT: fcvt s0, h0637; CHECK-GI-NOFP16-NEXT: fcvt s1, h1638; CHECK-GI-NOFP16-NEXT: fadd s0, s0, s1639; CHECK-GI-NOFP16-NEXT: fcvt h0, s0640; CHECK-GI-NOFP16-NEXT: ret641;642; CHECK-GI-FP16-LABEL: fadd_reduct_reassoc_v8f16:643; CHECK-GI-FP16: // %bb.0:644; CHECK-GI-FP16-NEXT: faddp v2.8h, v0.8h, v0.8h645; CHECK-GI-FP16-NEXT: faddp v3.8h, v1.8h, v1.8h646; CHECK-GI-FP16-NEXT: faddp v0.8h, v2.8h, v0.8h647; CHECK-GI-FP16-NEXT: faddp v1.8h, v3.8h, v1.8h648; CHECK-GI-FP16-NEXT: faddp h0, v0.2h649; CHECK-GI-FP16-NEXT: faddp h1, v1.2h650; CHECK-GI-FP16-NEXT: fadd h0, h0, h1651; CHECK-GI-FP16-NEXT: ret652 %r1 = call fast half @llvm.vector.reduce.fadd.f16.v8f16(half -0.0, <8 x half> %a)653 %r2 = call fast half @llvm.vector.reduce.fadd.f16.v8f16(half -0.0, <8 x half> %b)654 %r = fadd fast half %r1, %r2655 ret half %r656}657 658define float @fadd_reduct_reassoc_v8f32(<8 x float> %a, <8 x float> %b) {659; CHECK-SD-LABEL: fadd_reduct_reassoc_v8f32:660; CHECK-SD: // %bb.0:661; CHECK-SD-NEXT: fadd v2.4s, v2.4s, v3.4s662; CHECK-SD-NEXT: fadd v0.4s, v0.4s, v1.4s663; CHECK-SD-NEXT: fadd v0.4s, v0.4s, v2.4s664; CHECK-SD-NEXT: faddp v0.4s, v0.4s, v0.4s665; CHECK-SD-NEXT: faddp s0, v0.2s666; CHECK-SD-NEXT: ret667;668; CHECK-GI-LABEL: fadd_reduct_reassoc_v8f32:669; CHECK-GI: // %bb.0:670; CHECK-GI-NEXT: fadd v0.4s, v0.4s, v1.4s671; CHECK-GI-NEXT: fadd v1.4s, v2.4s, v3.4s672; CHECK-GI-NEXT: faddp v0.4s, v0.4s, v0.4s673; CHECK-GI-NEXT: faddp v1.4s, v1.4s, v1.4s674; CHECK-GI-NEXT: faddp s0, v0.2s675; CHECK-GI-NEXT: faddp s1, v1.2s676; CHECK-GI-NEXT: fadd s0, s0, s1677; CHECK-GI-NEXT: ret678 %r1 = call fast float @llvm.vector.reduce.fadd.f32.v8f32(float -0.0, <8 x float> %a)679 %r2 = call fast float @llvm.vector.reduce.fadd.f32.v8f32(float -0.0, <8 x float> %b)680 %r = fadd fast float %r1, %r2681 ret float %r682}683 684define float @fadd_reduct_reassoc_v4f32(<4 x float> %a, <4 x float> %b) {685; CHECK-SD-LABEL: fadd_reduct_reassoc_v4f32:686; CHECK-SD: // %bb.0:687; CHECK-SD-NEXT: fadd v0.4s, v0.4s, v1.4s688; CHECK-SD-NEXT: faddp v0.4s, v0.4s, v0.4s689; CHECK-SD-NEXT: faddp s0, v0.2s690; CHECK-SD-NEXT: ret691;692; CHECK-GI-LABEL: fadd_reduct_reassoc_v4f32:693; CHECK-GI: // %bb.0:694; CHECK-GI-NEXT: faddp v0.4s, v0.4s, v0.4s695; CHECK-GI-NEXT: faddp v1.4s, v1.4s, v1.4s696; CHECK-GI-NEXT: faddp s0, v0.2s697; CHECK-GI-NEXT: faddp s1, v1.2s698; CHECK-GI-NEXT: fadd s0, s0, s1699; CHECK-GI-NEXT: ret700 %r1 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float -0.0, <4 x float> %a)701 %r2 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float -0.0, <4 x float> %b)702 %r = fadd fast float %r1, %r2703 ret float %r704}705 706define float @fadd_reduct_reassoc_v4f32_init(float %i, <4 x float> %a, <4 x float> %b) {707; CHECK-LABEL: fadd_reduct_reassoc_v4f32_init:708; CHECK: // %bb.0:709; CHECK-NEXT: faddp v1.4s, v1.4s, v1.4s710; CHECK-NEXT: faddp v2.4s, v2.4s, v2.4s711; CHECK-NEXT: faddp s1, v1.2s712; CHECK-NEXT: fadd s0, s0, s1713; CHECK-NEXT: faddp s1, v2.2s714; CHECK-NEXT: fadd s0, s0, s1715; CHECK-NEXT: ret716 %r1 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float %i, <4 x float> %a)717 %r2 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float -0.0, <4 x float> %b)718 %r = fadd fast float %r1, %r2719 ret float %r720}721 722define float @fadd_reduct_reassoc_v4v8f32(<4 x float> %a, <8 x float> %b) {723; CHECK-SD-LABEL: fadd_reduct_reassoc_v4v8f32:724; CHECK-SD: // %bb.0:725; CHECK-SD-NEXT: fadd v1.4s, v1.4s, v2.4s726; CHECK-SD-NEXT: fadd v0.4s, v0.4s, v1.4s727; CHECK-SD-NEXT: faddp v0.4s, v0.4s, v0.4s728; CHECK-SD-NEXT: faddp s0, v0.2s729; CHECK-SD-NEXT: ret730;731; CHECK-GI-LABEL: fadd_reduct_reassoc_v4v8f32:732; CHECK-GI: // %bb.0:733; CHECK-GI-NEXT: fadd v1.4s, v1.4s, v2.4s734; CHECK-GI-NEXT: faddp v0.4s, v0.4s, v0.4s735; CHECK-GI-NEXT: faddp v1.4s, v1.4s, v1.4s736; CHECK-GI-NEXT: faddp s0, v0.2s737; CHECK-GI-NEXT: faddp s1, v1.2s738; CHECK-GI-NEXT: fadd s0, s0, s1739; CHECK-GI-NEXT: ret740 %r1 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float -0.0, <4 x float> %a)741 %r2 = call fast float @llvm.vector.reduce.fadd.f32.v8f32(float -0.0, <8 x float> %b)742 %r = fadd fast float %r1, %r2743 ret float %r744}745 746define double @fadd_reduct_reassoc_v4f64(<4 x double> %a, <4 x double> %b) {747; CHECK-SD-LABEL: fadd_reduct_reassoc_v4f64:748; CHECK-SD: // %bb.0:749; CHECK-SD-NEXT: fadd v2.2d, v2.2d, v3.2d750; CHECK-SD-NEXT: fadd v0.2d, v0.2d, v1.2d751; CHECK-SD-NEXT: fadd v0.2d, v0.2d, v2.2d752; CHECK-SD-NEXT: faddp d0, v0.2d753; CHECK-SD-NEXT: ret754;755; CHECK-GI-LABEL: fadd_reduct_reassoc_v4f64:756; CHECK-GI: // %bb.0:757; CHECK-GI-NEXT: fadd v0.2d, v0.2d, v1.2d758; CHECK-GI-NEXT: fadd v1.2d, v2.2d, v3.2d759; CHECK-GI-NEXT: faddp d0, v0.2d760; CHECK-GI-NEXT: faddp d1, v1.2d761; CHECK-GI-NEXT: fadd d0, d0, d1762; CHECK-GI-NEXT: ret763 %r1 = call fast double @llvm.vector.reduce.fadd.f64.v4f64(double -0.0, <4 x double> %a)764 %r2 = call fast double @llvm.vector.reduce.fadd.f64.v4f64(double -0.0, <4 x double> %b)765 %r = fadd fast double %r1, %r2766 ret double %r767}768 769define float @fadd_reduct_reassoc_v4f32_extrause(<4 x float> %a, <4 x float> %b) {770; CHECK-LABEL: fadd_reduct_reassoc_v4f32_extrause:771; CHECK: // %bb.0:772; CHECK-NEXT: faddp v0.4s, v0.4s, v0.4s773; CHECK-NEXT: faddp v1.4s, v1.4s, v1.4s774; CHECK-NEXT: faddp s0, v0.2s775; CHECK-NEXT: faddp s1, v1.2s776; CHECK-NEXT: fadd s1, s0, s1777; CHECK-NEXT: fmul s0, s1, s0778; CHECK-NEXT: ret779 %r1 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float -0.0, <4 x float> %a)780 %r2 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float -0.0, <4 x float> %b)781 %r = fadd fast float %r1, %r2782 %p = fmul float %r, %r1783 ret float %p784}785 786; Function Attrs: nounwind readnone787declare half @llvm.vector.reduce.fadd.f16.v4f16(half, <4 x half>)788declare half @llvm.vector.reduce.fadd.f16.v8f16(half, <8 x half>)789declare half @llvm.vector.reduce.fadd.f16.v16f16(half, <16 x half>)790declare float @llvm.vector.reduce.fadd.f32.v2f32(float, <2 x float>)791declare float @llvm.vector.reduce.fadd.f32.v4f32(float, <4 x float>)792declare float @llvm.vector.reduce.fadd.f32.v8f32(float, <8 x float>)793declare double @llvm.vector.reduce.fadd.f64.v2f64(double, <2 x double>)794declare double @llvm.vector.reduce.fadd.f64.v4f64(double, <4 x double>)795