1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -mattr=+neon | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOFP --check-prefix=CHECK-NOFP-SD 3; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -mattr=+neon,+fullfp16 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-FP --check-prefix=CHECK-FP-SD 4; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -mattr=+neon -global-isel -global-isel-abort=2 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOFP --check-prefix=CHECK-NOFP-GI 5; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -mattr=+neon,+fullfp16 -global-isel -global-isel-abort=2 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-FP --check-prefix=CHECK-FP-GI 6 7; CHECK-NOFP-GI: warning: Instruction selection used fallback path for test_v11f16 8; CHECK-NOFP-GI-NEXT: warning: Instruction selection used fallback path for test_v11f16_ninf 9; CHECK-NOFP-GI-NEXT: warning: Instruction selection used fallback path for test_v3f32 10; CHECK-NOFP-GI-NEXT: warning: Instruction selection used fallback path for test_v3f32_ninf 11; CHECK-NOFP-GI-NEXT: warning: Instruction selection used fallback path for test_v2f128 12; 13; CHECK-FP-GI: warning: Instruction selection used fallback path for test_v11f16 14; CHECK-FP-GI-NEXT: warning: Instruction selection used fallback path for test_v11f16_ninf 15; CHECK-FP-GI-NEXT: warning: Instruction selection used fallback path for test_v3f32 16; CHECK-FP-GI-NEXT: warning: Instruction selection used fallback path for test_v3f32_ninf 17; CHECK-FP-GI-NEXT: warning: Instruction selection used fallback path for test_v2f128 18 19declare half @llvm.vector.reduce.fmax.v1f16(<1 x half> %a) 20declare float @llvm.vector.reduce.fmax.v1f32(<1 x float> %a) 21declare double @llvm.vector.reduce.fmax.v1f64(<1 x double> %a) 22declare fp128 @llvm.vector.reduce.fmax.v1f128(<1 x fp128> %a) 23 24declare half @llvm.vector.reduce.fmax.v4f16(<4 x half> %a) 25declare half @llvm.vector.reduce.fmax.v8f16(<8 x half> %a) 26declare half @llvm.vector.reduce.fmax.v16f16(<16 x half> %a) 27declare float @llvm.vector.reduce.fmax.v2f32(<2 x float> %a) 28declare float @llvm.vector.reduce.fmax.v4f32(<4 x float> %a) 29declare float @llvm.vector.reduce.fmax.v8f32(<8 x float> %a) 30declare float @llvm.vector.reduce.fmax.v16f32(<16 x float> %a) 31declare double @llvm.vector.reduce.fmax.v2f64(<2 x double> %a) 32declare double @llvm.vector.reduce.fmax.v4f64(<4 x double> %a) 33 34declare half @llvm.vector.reduce.fmax.v11f16(<11 x half> %a) 35declare float @llvm.vector.reduce.fmax.v3f32(<3 x float> %a) 36declare fp128 @llvm.vector.reduce.fmax.v2f128(<2 x fp128> %a) 37 38define half @test_v1f16(<1 x half> %a) nounwind { 39; CHECK-LABEL: test_v1f16: 40; CHECK: // %bb.0: 41; CHECK-NEXT: ret 42 %b = call nnan half @llvm.vector.reduce.fmax.v1f16(<1 x half> %a) 43 ret half %b 44} 45 46define float @test_v1f32(<1 x float> %a) nounwind { 47; CHECK-NOFP-SD-LABEL: test_v1f32: 48; CHECK-NOFP-SD: // %bb.0: 49; CHECK-NOFP-SD-NEXT: // kill: def $d0 killed $d0 def $q0 50; CHECK-NOFP-SD-NEXT: // kill: def $s0 killed $s0 killed $q0 51; CHECK-NOFP-SD-NEXT: ret 52; 53; CHECK-FP-SD-LABEL: test_v1f32: 54; CHECK-FP-SD: // %bb.0: 55; CHECK-FP-SD-NEXT: // kill: def $d0 killed $d0 def $q0 56; CHECK-FP-SD-NEXT: // kill: def $s0 killed $s0 killed $q0 57; CHECK-FP-SD-NEXT: ret 58; 59; CHECK-NOFP-GI-LABEL: test_v1f32: 60; CHECK-NOFP-GI: // %bb.0: 61; CHECK-NOFP-GI-NEXT: // kill: def $s0 killed $s0 killed $d0 62; CHECK-NOFP-GI-NEXT: ret 63; 64; CHECK-FP-GI-LABEL: test_v1f32: 65; CHECK-FP-GI: // %bb.0: 66; CHECK-FP-GI-NEXT: // kill: def $s0 killed $s0 killed $d0 67; CHECK-FP-GI-NEXT: ret 68 %b = call nnan float @llvm.vector.reduce.fmax.v1f32(<1 x float> %a) 69 ret float %b 70} 71 72define double @test_v1f64(<1 x double> %a) nounwind { 73; CHECK-LABEL: test_v1f64: 74; CHECK: // %bb.0: 75; CHECK-NEXT: ret 76 %b = call nnan double @llvm.vector.reduce.fmax.v1f64(<1 x double> %a) 77 ret double %b 78} 79 80define fp128 @test_v1f128(<1 x fp128> %a) nounwind { 81; CHECK-LABEL: test_v1f128: 82; CHECK: // %bb.0: 83; CHECK-NEXT: ret 84 %b = call nnan fp128 @llvm.vector.reduce.fmax.v1f128(<1 x fp128> %a) 85 ret fp128 %b 86} 87 88define half @test_v4f16(<4 x half> %a) nounwind { 89; CHECK-NOFP-SD-LABEL: test_v4f16: 90; CHECK-NOFP-SD: // %bb.0: 91; CHECK-NOFP-SD-NEXT: // kill: def $d0 killed $d0 def $q0 92; CHECK-NOFP-SD-NEXT: mov h1, v0.h[1] 93; CHECK-NOFP-SD-NEXT: fcvt s2, h0 94; CHECK-NOFP-SD-NEXT: fcvt s1, h1 95; CHECK-NOFP-SD-NEXT: fmaxnm s1, s2, s1 96; CHECK-NOFP-SD-NEXT: mov h2, v0.h[2] 97; CHECK-NOFP-SD-NEXT: mov h0, v0.h[3] 98; CHECK-NOFP-SD-NEXT: fcvt h1, s1 99; CHECK-NOFP-SD-NEXT: fcvt s2, h2 100; CHECK-NOFP-SD-NEXT: fcvt s0, h0 101; CHECK-NOFP-SD-NEXT: fcvt s1, h1 102; CHECK-NOFP-SD-NEXT: fmaxnm s1, s1, s2 103; CHECK-NOFP-SD-NEXT: fcvt h1, s1 104; CHECK-NOFP-SD-NEXT: fcvt s1, h1 105; CHECK-NOFP-SD-NEXT: fmaxnm s0, s1, s0 106; CHECK-NOFP-SD-NEXT: fcvt h0, s0 107; CHECK-NOFP-SD-NEXT: ret 108; 109; CHECK-FP-LABEL: test_v4f16: 110; CHECK-FP: // %bb.0: 111; CHECK-FP-NEXT: fmaxnmv h0, v0.4h 112; CHECK-FP-NEXT: ret 113; 114; CHECK-NOFP-GI-LABEL: test_v4f16: 115; CHECK-NOFP-GI: // %bb.0: 116; CHECK-NOFP-GI-NEXT: fcvtl v0.4s, v0.4h 117; CHECK-NOFP-GI-NEXT: fmaxnmv s0, v0.4s 118; CHECK-NOFP-GI-NEXT: fcvt h0, s0 119; CHECK-NOFP-GI-NEXT: ret 120 %b = call nnan half @llvm.vector.reduce.fmax.v4f16(<4 x half> %a) 121 ret half %b 122} 123 124define half @test_v4f16_ninf(<4 x half> %a) nounwind { 125; CHECK-NOFP-SD-LABEL: test_v4f16_ninf: 126; CHECK-NOFP-SD: // %bb.0: 127; CHECK-NOFP-SD-NEXT: // kill: def $d0 killed $d0 def $q0 128; CHECK-NOFP-SD-NEXT: mov h1, v0.h[1] 129; CHECK-NOFP-SD-NEXT: fcvt s2, h0 130; CHECK-NOFP-SD-NEXT: fcvt s1, h1 131; CHECK-NOFP-SD-NEXT: fmaxnm s1, s2, s1 132; CHECK-NOFP-SD-NEXT: mov h2, v0.h[2] 133; CHECK-NOFP-SD-NEXT: mov h0, v0.h[3] 134; CHECK-NOFP-SD-NEXT: fcvt h1, s1 135; CHECK-NOFP-SD-NEXT: fcvt s2, h2 136; CHECK-NOFP-SD-NEXT: fcvt s0, h0 137; CHECK-NOFP-SD-NEXT: fcvt s1, h1 138; CHECK-NOFP-SD-NEXT: fmaxnm s1, s1, s2 139; CHECK-NOFP-SD-NEXT: fcvt h1, s1 140; CHECK-NOFP-SD-NEXT: fcvt s1, h1 141; CHECK-NOFP-SD-NEXT: fmaxnm s0, s1, s0 142; CHECK-NOFP-SD-NEXT: fcvt h0, s0 143; CHECK-NOFP-SD-NEXT: ret 144; 145; CHECK-FP-LABEL: test_v4f16_ninf: 146; CHECK-FP: // %bb.0: 147; CHECK-FP-NEXT: fmaxnmv h0, v0.4h 148; CHECK-FP-NEXT: ret 149; 150; CHECK-NOFP-GI-LABEL: test_v4f16_ninf: 151; CHECK-NOFP-GI: // %bb.0: 152; CHECK-NOFP-GI-NEXT: fcvtl v0.4s, v0.4h 153; CHECK-NOFP-GI-NEXT: fmaxnmv s0, v0.4s 154; CHECK-NOFP-GI-NEXT: fcvt h0, s0 155; CHECK-NOFP-GI-NEXT: ret 156 %b = call nnan ninf half @llvm.vector.reduce.fmax.v4f16(<4 x half> %a) 157 ret half %b 158} 159 160define half @test_v8f16(<8 x half> %a) nounwind { 161; CHECK-NOFP-SD-LABEL: test_v8f16: 162; CHECK-NOFP-SD: // %bb.0: 163; CHECK-NOFP-SD-NEXT: mov h1, v0.h[1] 164; CHECK-NOFP-SD-NEXT: fcvt s2, h0 165; CHECK-NOFP-SD-NEXT: fcvt s1, h1 166; CHECK-NOFP-SD-NEXT: fmaxnm s1, s2, s1 167; CHECK-NOFP-SD-NEXT: mov h2, v0.h[2] 168; CHECK-NOFP-SD-NEXT: fcvt h1, s1 169; CHECK-NOFP-SD-NEXT: fcvt s2, h2 170; CHECK-NOFP-SD-NEXT: fcvt s1, h1 171; CHECK-NOFP-SD-NEXT: fmaxnm s1, s1, s2 172; CHECK-NOFP-SD-NEXT: mov h2, v0.h[3] 173; CHECK-NOFP-SD-NEXT: fcvt h1, s1 174; CHECK-NOFP-SD-NEXT: fcvt s2, h2 175; CHECK-NOFP-SD-NEXT: fcvt s1, h1 176; CHECK-NOFP-SD-NEXT: fmaxnm s1, s1, s2 177; CHECK-NOFP-SD-NEXT: mov h2, v0.h[4] 178; CHECK-NOFP-SD-NEXT: fcvt h1, s1 179; CHECK-NOFP-SD-NEXT: fcvt s2, h2 180; CHECK-NOFP-SD-NEXT: fcvt s1, h1 181; CHECK-NOFP-SD-NEXT: fmaxnm s1, s1, s2 182; CHECK-NOFP-SD-NEXT: mov h2, v0.h[5] 183; CHECK-NOFP-SD-NEXT: fcvt h1, s1 184; CHECK-NOFP-SD-NEXT: fcvt s2, h2 185; CHECK-NOFP-SD-NEXT: fcvt s1, h1 186; CHECK-NOFP-SD-NEXT: fmaxnm s1, s1, s2 187; CHECK-NOFP-SD-NEXT: mov h2, v0.h[6] 188; CHECK-NOFP-SD-NEXT: mov h0, v0.h[7] 189; CHECK-NOFP-SD-NEXT: fcvt h1, s1 190; CHECK-NOFP-SD-NEXT: fcvt s2, h2 191; CHECK-NOFP-SD-NEXT: fcvt s0, h0 192; CHECK-NOFP-SD-NEXT: fcvt s1, h1 193; CHECK-NOFP-SD-NEXT: fmaxnm s1, s1, s2 194; CHECK-NOFP-SD-NEXT: fcvt h1, s1 195; CHECK-NOFP-SD-NEXT: fcvt s1, h1 196; CHECK-NOFP-SD-NEXT: fmaxnm s0, s1, s0 197; CHECK-NOFP-SD-NEXT: fcvt h0, s0 198; CHECK-NOFP-SD-NEXT: ret 199; 200; CHECK-FP-LABEL: test_v8f16: 201; CHECK-FP: // %bb.0: 202; CHECK-FP-NEXT: fmaxnmv h0, v0.8h 203; CHECK-FP-NEXT: ret 204; 205; CHECK-NOFP-GI-LABEL: test_v8f16: 206; CHECK-NOFP-GI: // %bb.0: 207; CHECK-NOFP-GI-NEXT: fcvtl v1.4s, v0.4h 208; CHECK-NOFP-GI-NEXT: fcvtl2 v0.4s, v0.8h 209; CHECK-NOFP-GI-NEXT: fmaxnm v0.4s, v1.4s, v0.4s 210; CHECK-NOFP-GI-NEXT: fmaxnmv s0, v0.4s 211; CHECK-NOFP-GI-NEXT: fcvt h0, s0 212; CHECK-NOFP-GI-NEXT: ret 213 %b = call nnan half @llvm.vector.reduce.fmax.v8f16(<8 x half> %a) 214 ret half %b 215} 216 217define half @test_v16f16(<16 x half> %a) nounwind { 218; CHECK-NOFP-SD-LABEL: test_v16f16: 219; CHECK-NOFP-SD: // %bb.0: 220; CHECK-NOFP-SD-NEXT: mov h2, v1.h[1] 221; CHECK-NOFP-SD-NEXT: mov h3, v0.h[1] 222; CHECK-NOFP-SD-NEXT: fcvt s4, h1 223; CHECK-NOFP-SD-NEXT: fcvt s5, h0 224; CHECK-NOFP-SD-NEXT: fcvt s2, h2 225; CHECK-NOFP-SD-NEXT: fcvt s3, h3 226; CHECK-NOFP-SD-NEXT: fmaxnm s4, s5, s4 227; CHECK-NOFP-SD-NEXT: mov h5, v0.h[2] 228; CHECK-NOFP-SD-NEXT: fmaxnm s2, s3, s2 229; CHECK-NOFP-SD-NEXT: mov h3, v1.h[2] 230; CHECK-NOFP-SD-NEXT: fcvt h4, s4 231; CHECK-NOFP-SD-NEXT: fcvt s5, h5 232; CHECK-NOFP-SD-NEXT: fcvt h2, s2 233; CHECK-NOFP-SD-NEXT: fcvt s3, h3 234; CHECK-NOFP-SD-NEXT: fcvt s4, h4 235; CHECK-NOFP-SD-NEXT: fcvt s2, h2 236; CHECK-NOFP-SD-NEXT: fmaxnm s3, s5, s3 237; CHECK-NOFP-SD-NEXT: mov h5, v0.h[3] 238; CHECK-NOFP-SD-NEXT: fmaxnm s2, s4, s2 239; CHECK-NOFP-SD-NEXT: mov h4, v1.h[3] 240; CHECK-NOFP-SD-NEXT: fcvt h3, s3 241; CHECK-NOFP-SD-NEXT: fcvt s5, h5 242; CHECK-NOFP-SD-NEXT: fcvt h2, s2 243; CHECK-NOFP-SD-NEXT: fcvt s4, h4 244; CHECK-NOFP-SD-NEXT: fcvt s3, h3 245; CHECK-NOFP-SD-NEXT: fcvt s2, h2 246; CHECK-NOFP-SD-NEXT: fmaxnm s4, s5, s4 247; CHECK-NOFP-SD-NEXT: mov h5, v0.h[4] 248; CHECK-NOFP-SD-NEXT: fmaxnm s2, s2, s3 249; CHECK-NOFP-SD-NEXT: mov h3, v1.h[4] 250; CHECK-NOFP-SD-NEXT: fcvt h4, s4 251; CHECK-NOFP-SD-NEXT: fcvt s5, h5 252; CHECK-NOFP-SD-NEXT: fcvt h2, s2 253; CHECK-NOFP-SD-NEXT: fcvt s3, h3 254; CHECK-NOFP-SD-NEXT: fcvt s4, h4 255; CHECK-NOFP-SD-NEXT: fcvt s2, h2 256; CHECK-NOFP-SD-NEXT: fmaxnm s3, s5, s3 257; CHECK-NOFP-SD-NEXT: mov h5, v0.h[5] 258; CHECK-NOFP-SD-NEXT: fmaxnm s2, s2, s4 259; CHECK-NOFP-SD-NEXT: mov h4, v1.h[5] 260; CHECK-NOFP-SD-NEXT: fcvt h3, s3 261; CHECK-NOFP-SD-NEXT: fcvt s5, h5 262; CHECK-NOFP-SD-NEXT: fcvt h2, s2 263; CHECK-NOFP-SD-NEXT: fcvt s4, h4 264; CHECK-NOFP-SD-NEXT: fcvt s3, h3 265; CHECK-NOFP-SD-NEXT: fcvt s2, h2 266; CHECK-NOFP-SD-NEXT: fmaxnm s4, s5, s4 267; CHECK-NOFP-SD-NEXT: mov h5, v0.h[6] 268; CHECK-NOFP-SD-NEXT: mov h0, v0.h[7] 269; CHECK-NOFP-SD-NEXT: fmaxnm s2, s2, s3 270; CHECK-NOFP-SD-NEXT: fcvt h3, s4 271; CHECK-NOFP-SD-NEXT: mov h4, v1.h[6] 272; CHECK-NOFP-SD-NEXT: fcvt s5, h5 273; CHECK-NOFP-SD-NEXT: mov h1, v1.h[7] 274; CHECK-NOFP-SD-NEXT: fcvt s0, h0 275; CHECK-NOFP-SD-NEXT: fcvt h2, s2 276; CHECK-NOFP-SD-NEXT: fcvt s3, h3 277; CHECK-NOFP-SD-NEXT: fcvt s4, h4 278; CHECK-NOFP-SD-NEXT: fcvt s1, h1 279; CHECK-NOFP-SD-NEXT: fcvt s2, h2 280; CHECK-NOFP-SD-NEXT: fmaxnm s0, s0, s1 281; CHECK-NOFP-SD-NEXT: fmaxnm s2, s2, s3 282; CHECK-NOFP-SD-NEXT: fmaxnm s3, s5, s4 283; CHECK-NOFP-SD-NEXT: fcvt h0, s0 284; CHECK-NOFP-SD-NEXT: fcvt h2, s2 285; CHECK-NOFP-SD-NEXT: fcvt h3, s3 286; CHECK-NOFP-SD-NEXT: fcvt s0, h0 287; CHECK-NOFP-SD-NEXT: fcvt s2, h2 288; CHECK-NOFP-SD-NEXT: fcvt s3, h3 289; CHECK-NOFP-SD-NEXT: fmaxnm s2, s2, s3 290; CHECK-NOFP-SD-NEXT: fcvt h1, s2 291; CHECK-NOFP-SD-NEXT: fcvt s1, h1 292; CHECK-NOFP-SD-NEXT: fmaxnm s0, s1, s0 293; CHECK-NOFP-SD-NEXT: fcvt h0, s0 294; CHECK-NOFP-SD-NEXT: ret 295; 296; CHECK-FP-LABEL: test_v16f16: 297; CHECK-FP: // %bb.0: 298; CHECK-FP-NEXT: fmaxnm v0.8h, v0.8h, v1.8h 299; CHECK-FP-NEXT: fmaxnmv h0, v0.8h 300; CHECK-FP-NEXT: ret 301; 302; CHECK-NOFP-GI-LABEL: test_v16f16: 303; CHECK-NOFP-GI: // %bb.0: 304; CHECK-NOFP-GI-NEXT: fcvtl v2.4s, v0.4h 305; CHECK-NOFP-GI-NEXT: fcvtl2 v0.4s, v0.8h 306; CHECK-NOFP-GI-NEXT: fcvtl v3.4s, v1.4h 307; CHECK-NOFP-GI-NEXT: fcvtl2 v1.4s, v1.8h 308; CHECK-NOFP-GI-NEXT: fmaxnm v0.4s, v2.4s, v0.4s 309; CHECK-NOFP-GI-NEXT: fmaxnm v1.4s, v3.4s, v1.4s 310; CHECK-NOFP-GI-NEXT: fmaxnm v0.4s, v0.4s, v1.4s 311; CHECK-NOFP-GI-NEXT: fmaxnmv s0, v0.4s 312; CHECK-NOFP-GI-NEXT: fcvt h0, s0 313; CHECK-NOFP-GI-NEXT: ret 314 %b = call nnan half @llvm.vector.reduce.fmax.v16f16(<16 x half> %a) 315 ret half %b 316} 317 318define float @test_v2f32(<2 x float> %a) nounwind { 319; CHECK-LABEL: test_v2f32: 320; CHECK: // %bb.0: 321; CHECK-NEXT: fmaxnmp s0, v0.2s 322; CHECK-NEXT: ret 323 %b = call nnan float @llvm.vector.reduce.fmax.v2f32(<2 x float> %a) 324 ret float %b 325} 326 327define float @test_v4f32(<4 x float> %a) nounwind { 328; CHECK-LABEL: test_v4f32: 329; CHECK: // %bb.0: 330; CHECK-NEXT: fmaxnmv s0, v0.4s 331; CHECK-NEXT: ret 332 %b = call nnan float @llvm.vector.reduce.fmax.v4f32(<4 x float> %a) 333 ret float %b 334} 335 336define float @test_v8f32(<8 x float> %a) nounwind { 337; CHECK-LABEL: test_v8f32: 338; CHECK: // %bb.0: 339; CHECK-NEXT: fmaxnm v0.4s, v0.4s, v1.4s 340; CHECK-NEXT: fmaxnmv s0, v0.4s 341; CHECK-NEXT: ret 342 %b = call nnan float @llvm.vector.reduce.fmax.v8f32(<8 x float> %a) 343 ret float %b 344} 345 346define float @test_v16f32(<16 x float> %a) nounwind { 347; CHECK-NOFP-SD-LABEL: test_v16f32: 348; CHECK-NOFP-SD: // %bb.0: 349; CHECK-NOFP-SD-NEXT: fmaxnm v1.4s, v1.4s, v3.4s 350; CHECK-NOFP-SD-NEXT: fmaxnm v0.4s, v0.4s, v2.4s 351; CHECK-NOFP-SD-NEXT: fmaxnm v0.4s, v0.4s, v1.4s 352; CHECK-NOFP-SD-NEXT: fmaxnmv s0, v0.4s 353; CHECK-NOFP-SD-NEXT: ret 354; 355; CHECK-FP-SD-LABEL: test_v16f32: 356; CHECK-FP-SD: // %bb.0: 357; CHECK-FP-SD-NEXT: fmaxnm v1.4s, v1.4s, v3.4s 358; CHECK-FP-SD-NEXT: fmaxnm v0.4s, v0.4s, v2.4s 359; CHECK-FP-SD-NEXT: fmaxnm v0.4s, v0.4s, v1.4s 360; CHECK-FP-SD-NEXT: fmaxnmv s0, v0.4s 361; CHECK-FP-SD-NEXT: ret 362; 363; CHECK-NOFP-GI-LABEL: test_v16f32: 364; CHECK-NOFP-GI: // %bb.0: 365; CHECK-NOFP-GI-NEXT: fmaxnm v0.4s, v0.4s, v1.4s 366; CHECK-NOFP-GI-NEXT: fmaxnm v1.4s, v2.4s, v3.4s 367; CHECK-NOFP-GI-NEXT: fmaxnm v0.4s, v0.4s, v1.4s 368; CHECK-NOFP-GI-NEXT: fmaxnmv s0, v0.4s 369; CHECK-NOFP-GI-NEXT: ret 370; 371; CHECK-FP-GI-LABEL: test_v16f32: 372; CHECK-FP-GI: // %bb.0: 373; CHECK-FP-GI-NEXT: fmaxnm v0.4s, v0.4s, v1.4s 374; CHECK-FP-GI-NEXT: fmaxnm v1.4s, v2.4s, v3.4s 375; CHECK-FP-GI-NEXT: fmaxnm v0.4s, v0.4s, v1.4s 376; CHECK-FP-GI-NEXT: fmaxnmv s0, v0.4s 377; CHECK-FP-GI-NEXT: ret 378 %b = call nnan float @llvm.vector.reduce.fmax.v16f32(<16 x float> %a) 379 ret float %b 380} 381 382define double @test_v2f64(<2 x double> %a) nounwind { 383; CHECK-LABEL: test_v2f64: 384; CHECK: // %bb.0: 385; CHECK-NEXT: fmaxnmp d0, v0.2d 386; CHECK-NEXT: ret 387 %b = call double @llvm.vector.reduce.fmax.v2f64(<2 x double> %a) 388 ret double %b 389} 390 391define double @test_v4f64(<4 x double> %a) nounwind { 392; CHECK-LABEL: test_v4f64: 393; CHECK: // %bb.0: 394; CHECK-NEXT: fmaxnm v0.2d, v0.2d, v1.2d 395; CHECK-NEXT: fmaxnmp d0, v0.2d 396; CHECK-NEXT: ret 397 %b = call double @llvm.vector.reduce.fmax.v4f64(<4 x double> %a) 398 ret double %b 399} 400 401define half @test_v11f16(<11 x half> %a) nounwind { 402; CHECK-NOFP-LABEL: test_v11f16: 403; CHECK-NOFP: // %bb.0: 404; CHECK-NOFP-NEXT: ldr h16, [sp, #8] 405; CHECK-NOFP-NEXT: ldr h17, [sp] 406; CHECK-NOFP-NEXT: fcvt s1, h1 407; CHECK-NOFP-NEXT: fcvt s0, h0 408; CHECK-NOFP-NEXT: fcvt s2, h2 409; CHECK-NOFP-NEXT: fcvt s16, h16 410; CHECK-NOFP-NEXT: fcvt s17, h17 411; CHECK-NOFP-NEXT: fmaxnm s1, s1, s16 412; CHECK-NOFP-NEXT: fmaxnm s0, s0, s17 413; CHECK-NOFP-NEXT: ldr h16, [sp, #16] 414; CHECK-NOFP-NEXT: fcvt s16, h16 415; CHECK-NOFP-NEXT: fcvt h1, s1 416; CHECK-NOFP-NEXT: fcvt h0, s0 417; CHECK-NOFP-NEXT: fcvt s1, h1 418; CHECK-NOFP-NEXT: fcvt s0, h0 419; CHECK-NOFP-NEXT: fmaxnm s0, s0, s1 420; CHECK-NOFP-NEXT: fmaxnm s1, s2, s16 421; CHECK-NOFP-NEXT: fcvt h0, s0 422; CHECK-NOFP-NEXT: fcvt h1, s1 423; CHECK-NOFP-NEXT: fcvt s0, h0 424; CHECK-NOFP-NEXT: fcvt s1, h1 425; CHECK-NOFP-NEXT: fmaxnm s0, s0, s1 426; CHECK-NOFP-NEXT: fcvt s1, h3 427; CHECK-NOFP-NEXT: fcvt h0, s0 428; CHECK-NOFP-NEXT: fcvt s0, h0 429; CHECK-NOFP-NEXT: fmaxnm s0, s0, s1 430; CHECK-NOFP-NEXT: fcvt s1, h4 431; CHECK-NOFP-NEXT: fcvt h0, s0 432; CHECK-NOFP-NEXT: fcvt s0, h0 433; CHECK-NOFP-NEXT: fmaxnm s0, s0, s1 434; CHECK-NOFP-NEXT: fcvt s1, h5 435; CHECK-NOFP-NEXT: fcvt h0, s0 436; CHECK-NOFP-NEXT: fcvt s0, h0 437; CHECK-NOFP-NEXT: fmaxnm s0, s0, s1 438; CHECK-NOFP-NEXT: fcvt s1, h6 439; CHECK-NOFP-NEXT: fcvt h0, s0 440; CHECK-NOFP-NEXT: fcvt s0, h0 441; CHECK-NOFP-NEXT: fmaxnm s0, s0, s1 442; CHECK-NOFP-NEXT: fcvt s1, h7 443; CHECK-NOFP-NEXT: fcvt h0, s0 444; CHECK-NOFP-NEXT: fcvt s0, h0 445; CHECK-NOFP-NEXT: fmaxnm s0, s0, s1 446; CHECK-NOFP-NEXT: fcvt h0, s0 447; CHECK-NOFP-NEXT: ret 448; 449; CHECK-FP-LABEL: test_v11f16: 450; CHECK-FP: // %bb.0: 451; CHECK-FP-NEXT: // kill: def $h0 killed $h0 def $q0 452; CHECK-FP-NEXT: // kill: def $h1 killed $h1 def $q1 453; CHECK-FP-NEXT: // kill: def $h2 killed $h2 def $q2 454; CHECK-FP-NEXT: // kill: def $h3 killed $h3 def $q3 455; CHECK-FP-NEXT: // kill: def $h4 killed $h4 def $q4 456; CHECK-FP-NEXT: // kill: def $h5 killed $h5 def $q5 457; CHECK-FP-NEXT: mov x8, sp 458; CHECK-FP-NEXT: // kill: def $h6 killed $h6 def $q6 459; CHECK-FP-NEXT: // kill: def $h7 killed $h7 def $q7 460; CHECK-FP-NEXT: mov v0.h[1], v1.h[0] 461; CHECK-FP-NEXT: movi v1.8h, #252, lsl #8 462; CHECK-FP-NEXT: mov v0.h[2], v2.h[0] 463; CHECK-FP-NEXT: ld1 { v1.h }[0], [x8] 464; CHECK-FP-NEXT: add x8, sp, #8 465; CHECK-FP-NEXT: ld1 { v1.h }[1], [x8] 466; CHECK-FP-NEXT: add x8, sp, #16 467; CHECK-FP-NEXT: mov v0.h[3], v3.h[0] 468; CHECK-FP-NEXT: ld1 { v1.h }[2], [x8] 469; CHECK-FP-NEXT: mov v0.h[4], v4.h[0] 470; CHECK-FP-NEXT: mov v0.h[5], v5.h[0] 471; CHECK-FP-NEXT: mov v0.h[6], v6.h[0] 472; CHECK-FP-NEXT: mov v0.h[7], v7.h[0] 473; CHECK-FP-NEXT: fmaxnm v0.8h, v0.8h, v1.8h 474; CHECK-FP-NEXT: fmaxnmv h0, v0.8h 475; CHECK-FP-NEXT: ret 476 %b = call nnan half @llvm.vector.reduce.fmax.v11f16(<11 x half> %a) 477 ret half %b 478} 479 480define half @test_v11f16_ninf(<11 x half> %a) nounwind { 481; CHECK-NOFP-LABEL: test_v11f16_ninf: 482; CHECK-NOFP: // %bb.0: 483; CHECK-NOFP-NEXT: ldr h16, [sp, #8] 484; CHECK-NOFP-NEXT: ldr h17, [sp] 485; CHECK-NOFP-NEXT: fcvt s1, h1 486; CHECK-NOFP-NEXT: fcvt s0, h0 487; CHECK-NOFP-NEXT: fcvt s2, h2 488; CHECK-NOFP-NEXT: fcvt s16, h16 489; CHECK-NOFP-NEXT: fcvt s17, h17 490; CHECK-NOFP-NEXT: fmaxnm s1, s1, s16 491; CHECK-NOFP-NEXT: fmaxnm s0, s0, s17 492; CHECK-NOFP-NEXT: ldr h16, [sp, #16] 493; CHECK-NOFP-NEXT: fcvt s16, h16 494; CHECK-NOFP-NEXT: fcvt h1, s1 495; CHECK-NOFP-NEXT: fcvt h0, s0 496; CHECK-NOFP-NEXT: fcvt s1, h1 497; CHECK-NOFP-NEXT: fcvt s0, h0 498; CHECK-NOFP-NEXT: fmaxnm s0, s0, s1 499; CHECK-NOFP-NEXT: fmaxnm s1, s2, s16 500; CHECK-NOFP-NEXT: fcvt h0, s0 501; CHECK-NOFP-NEXT: fcvt h1, s1 502; CHECK-NOFP-NEXT: fcvt s0, h0 503; CHECK-NOFP-NEXT: fcvt s1, h1 504; CHECK-NOFP-NEXT: fmaxnm s0, s0, s1 505; CHECK-NOFP-NEXT: fcvt s1, h3 506; CHECK-NOFP-NEXT: fcvt h0, s0 507; CHECK-NOFP-NEXT: fcvt s0, h0 508; CHECK-NOFP-NEXT: fmaxnm s0, s0, s1 509; CHECK-NOFP-NEXT: fcvt s1, h4 510; CHECK-NOFP-NEXT: fcvt h0, s0 511; CHECK-NOFP-NEXT: fcvt s0, h0 512; CHECK-NOFP-NEXT: fmaxnm s0, s0, s1 513; CHECK-NOFP-NEXT: fcvt s1, h5 514; CHECK-NOFP-NEXT: fcvt h0, s0 515; CHECK-NOFP-NEXT: fcvt s0, h0 516; CHECK-NOFP-NEXT: fmaxnm s0, s0, s1 517; CHECK-NOFP-NEXT: fcvt s1, h6 518; CHECK-NOFP-NEXT: fcvt h0, s0 519; CHECK-NOFP-NEXT: fcvt s0, h0 520; CHECK-NOFP-NEXT: fmaxnm s0, s0, s1 521; CHECK-NOFP-NEXT: fcvt s1, h7 522; CHECK-NOFP-NEXT: fcvt h0, s0 523; CHECK-NOFP-NEXT: fcvt s0, h0 524; CHECK-NOFP-NEXT: fmaxnm s0, s0, s1 525; CHECK-NOFP-NEXT: fcvt h0, s0 526; CHECK-NOFP-NEXT: ret 527; 528; CHECK-FP-LABEL: test_v11f16_ninf: 529; CHECK-FP: // %bb.0: 530; CHECK-FP-NEXT: // kill: def $h0 killed $h0 def $q0 531; CHECK-FP-NEXT: // kill: def $h1 killed $h1 def $q1 532; CHECK-FP-NEXT: // kill: def $h2 killed $h2 def $q2 533; CHECK-FP-NEXT: // kill: def $h3 killed $h3 def $q3 534; CHECK-FP-NEXT: // kill: def $h4 killed $h4 def $q4 535; CHECK-FP-NEXT: // kill: def $h5 killed $h5 def $q5 536; CHECK-FP-NEXT: mov x8, sp 537; CHECK-FP-NEXT: // kill: def $h6 killed $h6 def $q6 538; CHECK-FP-NEXT: // kill: def $h7 killed $h7 def $q7 539; CHECK-FP-NEXT: mov v0.h[1], v1.h[0] 540; CHECK-FP-NEXT: mvni v1.8h, #4, lsl #8 541; CHECK-FP-NEXT: ld1 { v1.h }[0], [x8] 542; CHECK-FP-NEXT: add x8, sp, #8 543; CHECK-FP-NEXT: mov v0.h[2], v2.h[0] 544; CHECK-FP-NEXT: ld1 { v1.h }[1], [x8] 545; CHECK-FP-NEXT: add x8, sp, #16 546; CHECK-FP-NEXT: mov v0.h[3], v3.h[0] 547; CHECK-FP-NEXT: ld1 { v1.h }[2], [x8] 548; CHECK-FP-NEXT: mov v0.h[4], v4.h[0] 549; CHECK-FP-NEXT: mov v0.h[5], v5.h[0] 550; CHECK-FP-NEXT: mov v0.h[6], v6.h[0] 551; CHECK-FP-NEXT: mov v0.h[7], v7.h[0] 552; CHECK-FP-NEXT: fmaxnm v0.8h, v0.8h, v1.8h 553; CHECK-FP-NEXT: fmaxnmv h0, v0.8h 554; CHECK-FP-NEXT: ret 555 %b = call nnan ninf half @llvm.vector.reduce.fmax.v11f16(<11 x half> %a) 556 ret half %b 557} 558 559define float @test_v3f32(<3 x float> %a) nounwind { 560; CHECK-LABEL: test_v3f32: 561; CHECK: // %bb.0: 562; CHECK-NEXT: mov w8, #-8388608 // =0xff800000 563; CHECK-NEXT: fmov s1, w8 564; CHECK-NEXT: mov v0.s[3], v1.s[0] 565; CHECK-NEXT: fmaxnmv s0, v0.4s 566; CHECK-NEXT: ret 567 %b = call nnan float @llvm.vector.reduce.fmax.v3f32(<3 x float> %a) 568 ret float %b 569} 570 571define float @test_v3f32_ninf(<3 x float> %a) nounwind { 572; CHECK-LABEL: test_v3f32_ninf: 573; CHECK: // %bb.0: 574; CHECK-NEXT: mov w8, #-8388609 // =0xff7fffff 575; CHECK-NEXT: fmov s1, w8 576; CHECK-NEXT: mov v0.s[3], v1.s[0] 577; CHECK-NEXT: fmaxnmv s0, v0.4s 578; CHECK-NEXT: ret 579 %b = call nnan ninf float @llvm.vector.reduce.fmax.v3f32(<3 x float> %a) 580 ret float %b 581} 582 583define fp128 @test_v2f128(<2 x fp128> %a) nounwind { 584; CHECK-LABEL: test_v2f128: 585; CHECK: // %bb.0: 586; CHECK-NEXT: sub sp, sp, #48 587; CHECK-NEXT: str x30, [sp, #32] // 8-byte Folded Spill 588; CHECK-NEXT: stp q0, q1, [sp] // 32-byte Folded Spill 589; CHECK-NEXT: bl __gttf2 590; CHECK-NEXT: ldr q0, [sp, #16] // 16-byte Folded Reload 591; CHECK-NEXT: cmp w0, #0 592; CHECK-NEXT: b.le .LBB18_2 593; CHECK-NEXT: // %bb.1: 594; CHECK-NEXT: ldr q0, [sp] // 16-byte Folded Reload 595; CHECK-NEXT: .LBB18_2: 596; CHECK-NEXT: ldr x30, [sp, #32] // 8-byte Folded Reload 597; CHECK-NEXT: add sp, sp, #48 598; CHECK-NEXT: ret 599 %b = call nnan fp128 @llvm.vector.reduce.fmax.v2f128(<2 x fp128> %a) 600 ret fp128 %b 601} 602