1425 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc --mtriple=aarch64-eabi < %s -global-isel=false | FileCheck %s --check-prefixes=CHECK,CHECK-SD3; RUN: llc --mtriple=aarch64-eabi < %s -global-isel=true | FileCheck %s --check-prefixes=CHECK,CHECK-GI4 5define float @add_f32(<8 x float> %a, <4 x float> %b) {6; CHECK-SD-LABEL: add_f32:7; CHECK-SD: // %bb.0:8; CHECK-SD-NEXT: fadd v0.4s, v0.4s, v1.4s9; CHECK-SD-NEXT: fadd v0.4s, v0.4s, v2.4s10; CHECK-SD-NEXT: faddp v0.4s, v0.4s, v0.4s11; CHECK-SD-NEXT: faddp s0, v0.2s12; CHECK-SD-NEXT: ret13;14; CHECK-GI-LABEL: add_f32:15; CHECK-GI: // %bb.0:16; CHECK-GI-NEXT: fadd v0.4s, v0.4s, v1.4s17; CHECK-GI-NEXT: faddp v1.4s, v2.4s, v2.4s18; CHECK-GI-NEXT: faddp v0.4s, v0.4s, v0.4s19; CHECK-GI-NEXT: faddp s1, v1.2s20; CHECK-GI-NEXT: faddp s0, v0.2s21; CHECK-GI-NEXT: fadd s0, s0, s122; CHECK-GI-NEXT: ret23 %r1 = call fast float @llvm.vector.reduce.fadd.f32.v8f32(float -0.0, <8 x float> %a)24 %r2 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float -0.0, <4 x float> %b)25 %r = fadd fast float %r1, %r226 ret float %r27}28 29define float @add_f32_same(<4 x float> %a, <4 x float> %b) {30; CHECK-SD-LABEL: add_f32_same:31; CHECK-SD: // %bb.0:32; CHECK-SD-NEXT: fadd v0.4s, v0.4s, v1.4s33; CHECK-SD-NEXT: faddp v0.4s, v0.4s, v0.4s34; CHECK-SD-NEXT: faddp s0, v0.2s35; CHECK-SD-NEXT: ret36;37; CHECK-GI-LABEL: add_f32_same:38; CHECK-GI: // %bb.0:39; CHECK-GI-NEXT: faddp v0.4s, v0.4s, v0.4s40; CHECK-GI-NEXT: faddp v1.4s, v1.4s, v1.4s41; CHECK-GI-NEXT: faddp s0, v0.2s42; CHECK-GI-NEXT: faddp s1, v1.2s43; CHECK-GI-NEXT: fadd s0, s0, s144; CHECK-GI-NEXT: ret45 %r1 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float -0.0, <4 x float> %a)46 %r2 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float -0.0, <4 x float> %b)47 %r = fadd fast float %r1, %r248 ret float %r49}50 51define float @fmul_f32(<8 x float> %a, <4 x float> %b) {52; CHECK-SD-LABEL: fmul_f32:53; CHECK-SD: // %bb.0:54; CHECK-SD-NEXT: fmul v0.4s, v0.4s, v1.4s55; CHECK-SD-NEXT: fmul v0.4s, v0.4s, v2.4s56; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #857; CHECK-SD-NEXT: fmul v0.2s, v0.2s, v1.2s58; CHECK-SD-NEXT: fmul s0, s0, v0.s[1]59; CHECK-SD-NEXT: ret60;61; CHECK-GI-LABEL: fmul_f32:62; CHECK-GI: // %bb.0:63; CHECK-GI-NEXT: fmul v0.4s, v0.4s, v1.4s64; CHECK-GI-NEXT: mov d3, v2.d[1]65; CHECK-GI-NEXT: mov d1, v0.d[1]66; CHECK-GI-NEXT: fmul v0.2s, v0.2s, v1.2s67; CHECK-GI-NEXT: fmul v1.2s, v2.2s, v3.2s68; CHECK-GI-NEXT: mov s2, v0.s[1]69; CHECK-GI-NEXT: mov s3, v1.s[1]70; CHECK-GI-NEXT: fmul s0, s0, s271; CHECK-GI-NEXT: fmul s1, s1, s372; CHECK-GI-NEXT: fmul s0, s0, s173; CHECK-GI-NEXT: ret74 %r1 = call fast float @llvm.vector.reduce.fmul.f32.v8f32(float 1.0, <8 x float> %a)75 %r2 = call fast float @llvm.vector.reduce.fmul.f32.v4f32(float 1.0, <4 x float> %b)76 %r = fmul fast float %r1, %r277 ret float %r78}79 80define float @fmul_f32_same(<4 x float> %a, <4 x float> %b) {81; CHECK-SD-LABEL: fmul_f32_same:82; CHECK-SD: // %bb.0:83; CHECK-SD-NEXT: fmul v0.4s, v0.4s, v1.4s84; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #885; CHECK-SD-NEXT: fmul v0.2s, v0.2s, v1.2s86; CHECK-SD-NEXT: fmul s0, s0, v0.s[1]87; CHECK-SD-NEXT: ret88;89; CHECK-GI-LABEL: fmul_f32_same:90; CHECK-GI: // %bb.0:91; CHECK-GI-NEXT: mov d2, v0.d[1]92; CHECK-GI-NEXT: mov d3, v1.d[1]93; CHECK-GI-NEXT: fmul v0.2s, v0.2s, v2.2s94; CHECK-GI-NEXT: fmul v1.2s, v1.2s, v3.2s95; CHECK-GI-NEXT: mov s2, v0.s[1]96; CHECK-GI-NEXT: mov s3, v1.s[1]97; CHECK-GI-NEXT: fmul s0, s0, s298; CHECK-GI-NEXT: fmul s1, s1, s399; CHECK-GI-NEXT: fmul s0, s0, s1100; CHECK-GI-NEXT: ret101 %r1 = call fast float @llvm.vector.reduce.fmul.f32.v4f32(float 1.0, <4 x float> %a)102 %r2 = call fast float @llvm.vector.reduce.fmul.f32.v4f32(float 1.0, <4 x float> %b)103 %r = fmul fast float %r1, %r2104 ret float %r105}106 107define float @fmin_f32(<8 x float> %a, <4 x float> %b) {108; CHECK-SD-LABEL: fmin_f32:109; CHECK-SD: // %bb.0:110; CHECK-SD-NEXT: fminnm v0.4s, v0.4s, v1.4s111; CHECK-SD-NEXT: fminnm v0.4s, v0.4s, v2.4s112; CHECK-SD-NEXT: fminnmv s0, v0.4s113; CHECK-SD-NEXT: ret114;115; CHECK-GI-LABEL: fmin_f32:116; CHECK-GI: // %bb.0:117; CHECK-GI-NEXT: fminnm v0.4s, v0.4s, v1.4s118; CHECK-GI-NEXT: fminnmv s1, v2.4s119; CHECK-GI-NEXT: fminnmv s0, v0.4s120; CHECK-GI-NEXT: fminnm s0, s0, s1121; CHECK-GI-NEXT: ret122 %r1 = call float @llvm.vector.reduce.fmin.v8f32(<8 x float> %a)123 %r2 = call float @llvm.vector.reduce.fmin.v4f32(<4 x float> %b)124 %r = call float @llvm.minnum.f32(float %r1, float %r2)125 ret float %r126}127 128define float @fmin_f32_same(<4 x float> %a, <4 x float> %b) {129; CHECK-SD-LABEL: fmin_f32_same:130; CHECK-SD: // %bb.0:131; CHECK-SD-NEXT: fminnm v0.4s, v0.4s, v1.4s132; CHECK-SD-NEXT: fminnmv s0, v0.4s133; CHECK-SD-NEXT: ret134;135; CHECK-GI-LABEL: fmin_f32_same:136; CHECK-GI: // %bb.0:137; CHECK-GI-NEXT: fminnmv s0, v0.4s138; CHECK-GI-NEXT: fminnmv s1, v1.4s139; CHECK-GI-NEXT: fminnm s0, s0, s1140; CHECK-GI-NEXT: ret141 %r1 = call float @llvm.vector.reduce.fmin.v4f32(<4 x float> %a)142 %r2 = call float @llvm.vector.reduce.fmin.v4f32(<4 x float> %b)143 %r = call float @llvm.minnum.f32(float %r1, float %r2)144 ret float %r145}146 147define float @fmax_f32(<8 x float> %a, <4 x float> %b) {148; CHECK-SD-LABEL: fmax_f32:149; CHECK-SD: // %bb.0:150; CHECK-SD-NEXT: fmaxnm v0.4s, v0.4s, v1.4s151; CHECK-SD-NEXT: fmaxnm v0.4s, v0.4s, v2.4s152; CHECK-SD-NEXT: fmaxnmv s0, v0.4s153; CHECK-SD-NEXT: ret154;155; CHECK-GI-LABEL: fmax_f32:156; CHECK-GI: // %bb.0:157; CHECK-GI-NEXT: fmaxnm v0.4s, v0.4s, v1.4s158; CHECK-GI-NEXT: fmaxnmv s1, v2.4s159; CHECK-GI-NEXT: fmaxnmv s0, v0.4s160; CHECK-GI-NEXT: fmaxnm s0, s0, s1161; CHECK-GI-NEXT: ret162 %r1 = call float @llvm.vector.reduce.fmax.v8f32(<8 x float> %a)163 %r2 = call float @llvm.vector.reduce.fmax.v4f32(<4 x float> %b)164 %r = call float @llvm.maxnum.f32(float %r1, float %r2)165 ret float %r166}167 168define float @fmax_f32_same(<4 x float> %a, <4 x float> %b) {169; CHECK-SD-LABEL: fmax_f32_same:170; CHECK-SD: // %bb.0:171; CHECK-SD-NEXT: fmaxnm v0.4s, v0.4s, v1.4s172; CHECK-SD-NEXT: fmaxnmv s0, v0.4s173; CHECK-SD-NEXT: ret174;175; CHECK-GI-LABEL: fmax_f32_same:176; CHECK-GI: // %bb.0:177; CHECK-GI-NEXT: fmaxnmv s0, v0.4s178; CHECK-GI-NEXT: fmaxnmv s1, v1.4s179; CHECK-GI-NEXT: fmaxnm s0, s0, s1180; CHECK-GI-NEXT: ret181 %r1 = call float @llvm.vector.reduce.fmax.v4f32(<4 x float> %a)182 %r2 = call float @llvm.vector.reduce.fmax.v4f32(<4 x float> %b)183 %r = call float @llvm.maxnum.f32(float %r1, float %r2)184 ret float %r185}186 187define float @fminimum_f32(<8 x float> %a, <4 x float> %b) {188; CHECK-SD-LABEL: fminimum_f32:189; CHECK-SD: // %bb.0:190; CHECK-SD-NEXT: fmin v0.4s, v0.4s, v1.4s191; CHECK-SD-NEXT: fmin v0.4s, v0.4s, v2.4s192; CHECK-SD-NEXT: fminv s0, v0.4s193; CHECK-SD-NEXT: ret194;195; CHECK-GI-LABEL: fminimum_f32:196; CHECK-GI: // %bb.0:197; CHECK-GI-NEXT: fmin v0.4s, v0.4s, v1.4s198; CHECK-GI-NEXT: fminv s1, v2.4s199; CHECK-GI-NEXT: fminv s0, v0.4s200; CHECK-GI-NEXT: fmin s0, s0, s1201; CHECK-GI-NEXT: ret202 %r1 = call float @llvm.vector.reduce.fminimum.v8f32(<8 x float> %a)203 %r2 = call float @llvm.vector.reduce.fminimum.v4f32(<4 x float> %b)204 %r = call float @llvm.minimum.f32(float %r1, float %r2)205 ret float %r206}207 208define float @fminimum_f32_same(<4 x float> %a, <4 x float> %b) {209; CHECK-SD-LABEL: fminimum_f32_same:210; CHECK-SD: // %bb.0:211; CHECK-SD-NEXT: fmin v0.4s, v0.4s, v1.4s212; CHECK-SD-NEXT: fminv s0, v0.4s213; CHECK-SD-NEXT: ret214;215; CHECK-GI-LABEL: fminimum_f32_same:216; CHECK-GI: // %bb.0:217; CHECK-GI-NEXT: fminv s0, v0.4s218; CHECK-GI-NEXT: fminv s1, v1.4s219; CHECK-GI-NEXT: fmin s0, s0, s1220; CHECK-GI-NEXT: ret221 %r1 = call float @llvm.vector.reduce.fminimum.v4f32(<4 x float> %a)222 %r2 = call float @llvm.vector.reduce.fminimum.v4f32(<4 x float> %b)223 %r = call float @llvm.minimum.f32(float %r1, float %r2)224 ret float %r225}226 227define float @fmaximum_f32(<8 x float> %a, <4 x float> %b) {228; CHECK-SD-LABEL: fmaximum_f32:229; CHECK-SD: // %bb.0:230; CHECK-SD-NEXT: fmax v0.4s, v0.4s, v1.4s231; CHECK-SD-NEXT: fmax v0.4s, v0.4s, v2.4s232; CHECK-SD-NEXT: fmaxv s0, v0.4s233; CHECK-SD-NEXT: ret234;235; CHECK-GI-LABEL: fmaximum_f32:236; CHECK-GI: // %bb.0:237; CHECK-GI-NEXT: fmax v0.4s, v0.4s, v1.4s238; CHECK-GI-NEXT: fmaxv s1, v2.4s239; CHECK-GI-NEXT: fmaxv s0, v0.4s240; CHECK-GI-NEXT: fmax s0, s0, s1241; CHECK-GI-NEXT: ret242 %r1 = call float @llvm.vector.reduce.fmaximum.v8f32(<8 x float> %a)243 %r2 = call float @llvm.vector.reduce.fmaximum.v4f32(<4 x float> %b)244 %r = call float @llvm.maximum.f32(float %r1, float %r2)245 ret float %r246}247 248define float @fmaximum_f32_same(<4 x float> %a, <4 x float> %b) {249; CHECK-SD-LABEL: fmaximum_f32_same:250; CHECK-SD: // %bb.0:251; CHECK-SD-NEXT: fmax v0.4s, v0.4s, v1.4s252; CHECK-SD-NEXT: fmaxv s0, v0.4s253; CHECK-SD-NEXT: ret254;255; CHECK-GI-LABEL: fmaximum_f32_same:256; CHECK-GI: // %bb.0:257; CHECK-GI-NEXT: fmaxv s0, v0.4s258; CHECK-GI-NEXT: fmaxv s1, v1.4s259; CHECK-GI-NEXT: fmax s0, s0, s1260; CHECK-GI-NEXT: ret261 %r1 = call float @llvm.vector.reduce.fmaximum.v4f32(<4 x float> %a)262 %r2 = call float @llvm.vector.reduce.fmaximum.v4f32(<4 x float> %b)263 %r = call float @llvm.maximum.f32(float %r1, float %r2)264 ret float %r265}266 267; These next two tests have incorrect minnum/minimum combinations268define float @fminimumnum_f32(<4 x float> %a, <4 x float> %b) {269; CHECK-LABEL: fminimumnum_f32:270; CHECK: // %bb.0:271; CHECK-NEXT: fminv s0, v0.4s272; CHECK-NEXT: fminv s1, v1.4s273; CHECK-NEXT: fminnm s0, s0, s1274; CHECK-NEXT: ret275 %r1 = call float @llvm.vector.reduce.fminimum.v4f32(<4 x float> %a)276 %r2 = call float @llvm.vector.reduce.fminimum.v4f32(<4 x float> %b)277 %r = call float @llvm.minnum.f32(float %r1, float %r2)278 ret float %r279}280 281define float @fmaxnumimum_f32(<4 x float> %a, <4 x float> %b) {282; CHECK-LABEL: fmaxnumimum_f32:283; CHECK: // %bb.0:284; CHECK-NEXT: fmaxnmv s0, v0.4s285; CHECK-NEXT: fmaxnmv s1, v1.4s286; CHECK-NEXT: fmax s0, s0, s1287; CHECK-NEXT: ret288 %r1 = call float @llvm.vector.reduce.fmax.v4f32(<4 x float> %a)289 %r2 = call float @llvm.vector.reduce.fmax.v4f32(<4 x float> %b)290 %r = call float @llvm.maximum.f32(float %r1, float %r2)291 ret float %r292}293 294 295define i32 @add_i32(<8 x i32> %a, <4 x i32> %b) {296; CHECK-SD-LABEL: add_i32:297; CHECK-SD: // %bb.0:298; CHECK-SD-NEXT: add v0.4s, v0.4s, v1.4s299; CHECK-SD-NEXT: add v0.4s, v0.4s, v2.4s300; CHECK-SD-NEXT: addv s0, v0.4s301; CHECK-SD-NEXT: fmov w0, s0302; CHECK-SD-NEXT: ret303;304; CHECK-GI-LABEL: add_i32:305; CHECK-GI: // %bb.0:306; CHECK-GI-NEXT: add v0.4s, v0.4s, v1.4s307; CHECK-GI-NEXT: addv s1, v2.4s308; CHECK-GI-NEXT: addv s0, v0.4s309; CHECK-GI-NEXT: fmov w9, s1310; CHECK-GI-NEXT: fmov w8, s0311; CHECK-GI-NEXT: add w0, w8, w9312; CHECK-GI-NEXT: ret313 %r1 = call i32 @llvm.vector.reduce.add.i32.v8i32(<8 x i32> %a)314 %r2 = call i32 @llvm.vector.reduce.add.i32.v4i32(<4 x i32> %b)315 %r = add i32 %r1, %r2316 ret i32 %r317}318 319define i16 @add_ext_i16(<16 x i8> %a, <16 x i8> %b) {320; CHECK-SD-LABEL: add_ext_i16:321; CHECK-SD: // %bb.0:322; CHECK-SD-NEXT: uaddlp v1.8h, v1.16b323; CHECK-SD-NEXT: uadalp v1.8h, v0.16b324; CHECK-SD-NEXT: addv h0, v1.8h325; CHECK-SD-NEXT: fmov w0, s0326; CHECK-SD-NEXT: ret327;328; CHECK-GI-LABEL: add_ext_i16:329; CHECK-GI: // %bb.0:330; CHECK-GI-NEXT: uaddlv h0, v0.16b331; CHECK-GI-NEXT: uaddlv h1, v1.16b332; CHECK-GI-NEXT: fmov w8, s0333; CHECK-GI-NEXT: fmov w9, s1334; CHECK-GI-NEXT: add w0, w8, w9335; CHECK-GI-NEXT: ret336 %ae = zext <16 x i8> %a to <16 x i16>337 %be = zext <16 x i8> %b to <16 x i16>338 %r1 = call i16 @llvm.vector.reduce.add.i16.v16i16(<16 x i16> %ae)339 %r2 = call i16 @llvm.vector.reduce.add.i16.v16i16(<16 x i16> %be)340 %r = add i16 %r1, %r2341 ret i16 %r342}343 344define i16 @add_ext_v32i16(<32 x i8> %a, <16 x i8> %b) {345; CHECK-SD-LABEL: add_ext_v32i16:346; CHECK-SD: // %bb.0:347; CHECK-SD-NEXT: uaddl2 v3.8h, v0.16b, v1.16b348; CHECK-SD-NEXT: uaddl v0.8h, v0.8b, v1.8b349; CHECK-SD-NEXT: add v0.8h, v0.8h, v3.8h350; CHECK-SD-NEXT: uadalp v0.8h, v2.16b351; CHECK-SD-NEXT: addv h0, v0.8h352; CHECK-SD-NEXT: fmov w0, s0353; CHECK-SD-NEXT: ret354;355; CHECK-GI-LABEL: add_ext_v32i16:356; CHECK-GI: // %bb.0:357; CHECK-GI-NEXT: uaddlv h0, v0.16b358; CHECK-GI-NEXT: uaddlv h1, v1.16b359; CHECK-GI-NEXT: uaddlv h2, v2.16b360; CHECK-GI-NEXT: fmov w8, s0361; CHECK-GI-NEXT: fmov w9, s1362; CHECK-GI-NEXT: add w8, w8, w9363; CHECK-GI-NEXT: fmov w9, s2364; CHECK-GI-NEXT: add w0, w8, w9365; CHECK-GI-NEXT: ret366 %ae = zext <32 x i8> %a to <32 x i16>367 %be = zext <16 x i8> %b to <16 x i16>368 %r1 = call i16 @llvm.vector.reduce.add.i16.v32i16(<32 x i16> %ae)369 %r2 = call i16 @llvm.vector.reduce.add.i16.v16i16(<16 x i16> %be)370 %r = add i16 %r1, %r2371 ret i16 %r372}373 374define i32 @mul_i32(<8 x i32> %a, <4 x i32> %b) {375; CHECK-SD-LABEL: mul_i32:376; CHECK-SD: // %bb.0:377; CHECK-SD-NEXT: mul v0.4s, v0.4s, v1.4s378; CHECK-SD-NEXT: mul v0.4s, v0.4s, v2.4s379; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #8380; CHECK-SD-NEXT: mul v0.2s, v0.2s, v1.2s381; CHECK-SD-NEXT: mov w8, v0.s[1]382; CHECK-SD-NEXT: fmov w9, s0383; CHECK-SD-NEXT: mul w0, w9, w8384; CHECK-SD-NEXT: ret385;386; CHECK-GI-LABEL: mul_i32:387; CHECK-GI: // %bb.0:388; CHECK-GI-NEXT: mov d3, v0.d[1]389; CHECK-GI-NEXT: mov d4, v1.d[1]390; CHECK-GI-NEXT: mul v0.2s, v0.2s, v3.2s391; CHECK-GI-NEXT: mul v1.2s, v1.2s, v4.2s392; CHECK-GI-NEXT: mov d3, v2.d[1]393; CHECK-GI-NEXT: mul v0.2s, v0.2s, v1.2s394; CHECK-GI-NEXT: mul v1.2s, v2.2s, v3.2s395; CHECK-GI-NEXT: mov w8, v0.s[1]396; CHECK-GI-NEXT: fmov w10, s0397; CHECK-GI-NEXT: mov w9, v1.s[1]398; CHECK-GI-NEXT: mul w8, w10, w8399; CHECK-GI-NEXT: fmov w10, s1400; CHECK-GI-NEXT: mul w9, w10, w9401; CHECK-GI-NEXT: mul w0, w8, w9402; CHECK-GI-NEXT: ret403 %r1 = call i32 @llvm.vector.reduce.mul.i32.v8i32(<8 x i32> %a)404 %r2 = call i32 @llvm.vector.reduce.mul.i32.v4i32(<4 x i32> %b)405 %r = mul i32 %r1, %r2406 ret i32 %r407}408 409define i32 @mul_i32_same(<4 x i32> %a, <4 x i32> %b) {410; CHECK-SD-LABEL: mul_i32_same:411; CHECK-SD: // %bb.0:412; CHECK-SD-NEXT: mul v0.4s, v0.4s, v1.4s413; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #8414; CHECK-SD-NEXT: mul v0.2s, v0.2s, v1.2s415; CHECK-SD-NEXT: mov w8, v0.s[1]416; CHECK-SD-NEXT: fmov w9, s0417; CHECK-SD-NEXT: mul w0, w9, w8418; CHECK-SD-NEXT: ret419;420; CHECK-GI-LABEL: mul_i32_same:421; CHECK-GI: // %bb.0:422; CHECK-GI-NEXT: mov d2, v0.d[1]423; CHECK-GI-NEXT: mov d3, v1.d[1]424; CHECK-GI-NEXT: mul v0.2s, v0.2s, v2.2s425; CHECK-GI-NEXT: mul v1.2s, v1.2s, v3.2s426; CHECK-GI-NEXT: mov w8, v0.s[1]427; CHECK-GI-NEXT: mov w9, v1.s[1]428; CHECK-GI-NEXT: fmov w10, s0429; CHECK-GI-NEXT: fmov w11, s1430; CHECK-GI-NEXT: mul w8, w10, w8431; CHECK-GI-NEXT: mul w9, w11, w9432; CHECK-GI-NEXT: mul w0, w8, w9433; CHECK-GI-NEXT: ret434 %r1 = call i32 @llvm.vector.reduce.mul.i32.v4i32(<4 x i32> %a)435 %r2 = call i32 @llvm.vector.reduce.mul.i32.v4i32(<4 x i32> %b)436 %r = mul i32 %r1, %r2437 ret i32 %r438}439 440define i32 @and_i32(<8 x i32> %a, <4 x i32> %b) {441; CHECK-SD-LABEL: and_i32:442; CHECK-SD: // %bb.0:443; CHECK-SD-NEXT: and v0.16b, v0.16b, v1.16b444; CHECK-SD-NEXT: and v0.16b, v0.16b, v2.16b445; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #8446; CHECK-SD-NEXT: and v0.8b, v0.8b, v1.8b447; CHECK-SD-NEXT: fmov x8, d0448; CHECK-SD-NEXT: lsr x9, x8, #32449; CHECK-SD-NEXT: and w0, w8, w9450; CHECK-SD-NEXT: ret451;452; CHECK-GI-LABEL: and_i32:453; CHECK-GI: // %bb.0:454; CHECK-GI-NEXT: and v0.16b, v0.16b, v1.16b455; CHECK-GI-NEXT: mov d1, v2.d[1]456; CHECK-GI-NEXT: mov d3, v0.d[1]457; CHECK-GI-NEXT: and v1.8b, v2.8b, v1.8b458; CHECK-GI-NEXT: and v0.8b, v0.8b, v3.8b459; CHECK-GI-NEXT: mov w8, v1.s[1]460; CHECK-GI-NEXT: fmov w10, s1461; CHECK-GI-NEXT: mov w9, v0.s[1]462; CHECK-GI-NEXT: fmov w11, s0463; CHECK-GI-NEXT: and w8, w10, w8464; CHECK-GI-NEXT: and w8, w11, w8465; CHECK-GI-NEXT: and w0, w8, w9466; CHECK-GI-NEXT: ret467 %r1 = call i32 @llvm.vector.reduce.and.i32.v8i32(<8 x i32> %a)468 %r2 = call i32 @llvm.vector.reduce.and.i32.v4i32(<4 x i32> %b)469 %r = and i32 %r1, %r2470 ret i32 %r471}472 473define i32 @and_i32_same(<4 x i32> %a, <4 x i32> %b) {474; CHECK-SD-LABEL: and_i32_same:475; CHECK-SD: // %bb.0:476; CHECK-SD-NEXT: and v0.16b, v0.16b, v1.16b477; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #8478; CHECK-SD-NEXT: and v0.8b, v0.8b, v1.8b479; CHECK-SD-NEXT: fmov x8, d0480; CHECK-SD-NEXT: lsr x9, x8, #32481; CHECK-SD-NEXT: and w0, w8, w9482; CHECK-SD-NEXT: ret483;484; CHECK-GI-LABEL: and_i32_same:485; CHECK-GI: // %bb.0:486; CHECK-GI-NEXT: mov d2, v0.d[1]487; CHECK-GI-NEXT: mov d3, v1.d[1]488; CHECK-GI-NEXT: and v0.8b, v0.8b, v2.8b489; CHECK-GI-NEXT: and v1.8b, v1.8b, v3.8b490; CHECK-GI-NEXT: mov w8, v0.s[1]491; CHECK-GI-NEXT: mov w9, v1.s[1]492; CHECK-GI-NEXT: fmov w10, s0493; CHECK-GI-NEXT: fmov w11, s1494; CHECK-GI-NEXT: and w8, w10, w8495; CHECK-GI-NEXT: and w9, w11, w9496; CHECK-GI-NEXT: and w0, w8, w9497; CHECK-GI-NEXT: ret498 %r1 = call i32 @llvm.vector.reduce.and.i32.v4i32(<4 x i32> %a)499 %r2 = call i32 @llvm.vector.reduce.and.i32.v4i32(<4 x i32> %b)500 %r = and i32 %r1, %r2501 ret i32 %r502}503 504define i32 @or_i32(<8 x i32> %a, <4 x i32> %b) {505; CHECK-SD-LABEL: or_i32:506; CHECK-SD: // %bb.0:507; CHECK-SD-NEXT: orr v0.16b, v0.16b, v1.16b508; CHECK-SD-NEXT: orr v0.16b, v0.16b, v2.16b509; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #8510; CHECK-SD-NEXT: orr v0.8b, v0.8b, v1.8b511; CHECK-SD-NEXT: fmov x8, d0512; CHECK-SD-NEXT: lsr x9, x8, #32513; CHECK-SD-NEXT: orr w0, w8, w9514; CHECK-SD-NEXT: ret515;516; CHECK-GI-LABEL: or_i32:517; CHECK-GI: // %bb.0:518; CHECK-GI-NEXT: orr v0.16b, v0.16b, v1.16b519; CHECK-GI-NEXT: mov d1, v2.d[1]520; CHECK-GI-NEXT: mov d3, v0.d[1]521; CHECK-GI-NEXT: orr v1.8b, v2.8b, v1.8b522; CHECK-GI-NEXT: orr v0.8b, v0.8b, v3.8b523; CHECK-GI-NEXT: mov w8, v1.s[1]524; CHECK-GI-NEXT: fmov w10, s1525; CHECK-GI-NEXT: mov w9, v0.s[1]526; CHECK-GI-NEXT: fmov w11, s0527; CHECK-GI-NEXT: orr w8, w10, w8528; CHECK-GI-NEXT: orr w8, w11, w8529; CHECK-GI-NEXT: orr w0, w8, w9530; CHECK-GI-NEXT: ret531 %r1 = call i32 @llvm.vector.reduce.or.i32.v8i32(<8 x i32> %a)532 %r2 = call i32 @llvm.vector.reduce.or.i32.v4i32(<4 x i32> %b)533 %r = or i32 %r1, %r2534 ret i32 %r535}536 537define i32 @or_i32_same(<4 x i32> %a, <4 x i32> %b) {538; CHECK-SD-LABEL: or_i32_same:539; CHECK-SD: // %bb.0:540; CHECK-SD-NEXT: orr v0.16b, v0.16b, v1.16b541; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #8542; CHECK-SD-NEXT: orr v0.8b, v0.8b, v1.8b543; CHECK-SD-NEXT: fmov x8, d0544; CHECK-SD-NEXT: lsr x9, x8, #32545; CHECK-SD-NEXT: orr w0, w8, w9546; CHECK-SD-NEXT: ret547;548; CHECK-GI-LABEL: or_i32_same:549; CHECK-GI: // %bb.0:550; CHECK-GI-NEXT: mov d2, v0.d[1]551; CHECK-GI-NEXT: mov d3, v1.d[1]552; CHECK-GI-NEXT: orr v0.8b, v0.8b, v2.8b553; CHECK-GI-NEXT: orr v1.8b, v1.8b, v3.8b554; CHECK-GI-NEXT: mov w8, v0.s[1]555; CHECK-GI-NEXT: mov w9, v1.s[1]556; CHECK-GI-NEXT: fmov w10, s0557; CHECK-GI-NEXT: fmov w11, s1558; CHECK-GI-NEXT: orr w8, w10, w8559; CHECK-GI-NEXT: orr w9, w11, w9560; CHECK-GI-NEXT: orr w0, w8, w9561; CHECK-GI-NEXT: ret562 %r1 = call i32 @llvm.vector.reduce.or.i32.v4i32(<4 x i32> %a)563 %r2 = call i32 @llvm.vector.reduce.or.i32.v4i32(<4 x i32> %b)564 %r = or i32 %r1, %r2565 ret i32 %r566}567 568define i32 @xor_i32(<8 x i32> %a, <4 x i32> %b) {569; CHECK-SD-LABEL: xor_i32:570; CHECK-SD: // %bb.0:571; CHECK-SD-NEXT: eor v0.16b, v0.16b, v1.16b572; CHECK-SD-NEXT: eor v0.16b, v0.16b, v2.16b573; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #8574; CHECK-SD-NEXT: eor v0.8b, v0.8b, v1.8b575; CHECK-SD-NEXT: fmov x8, d0576; CHECK-SD-NEXT: lsr x9, x8, #32577; CHECK-SD-NEXT: eor w0, w8, w9578; CHECK-SD-NEXT: ret579;580; CHECK-GI-LABEL: xor_i32:581; CHECK-GI: // %bb.0:582; CHECK-GI-NEXT: eor v0.16b, v0.16b, v1.16b583; CHECK-GI-NEXT: mov d1, v2.d[1]584; CHECK-GI-NEXT: mov d3, v0.d[1]585; CHECK-GI-NEXT: eor v1.8b, v2.8b, v1.8b586; CHECK-GI-NEXT: eor v0.8b, v0.8b, v3.8b587; CHECK-GI-NEXT: mov w8, v1.s[1]588; CHECK-GI-NEXT: fmov w10, s1589; CHECK-GI-NEXT: mov w9, v0.s[1]590; CHECK-GI-NEXT: fmov w11, s0591; CHECK-GI-NEXT: eor w8, w10, w8592; CHECK-GI-NEXT: eor w8, w11, w8593; CHECK-GI-NEXT: eor w0, w8, w9594; CHECK-GI-NEXT: ret595 %r1 = call i32 @llvm.vector.reduce.xor.i32.v8i32(<8 x i32> %a)596 %r2 = call i32 @llvm.vector.reduce.xor.i32.v4i32(<4 x i32> %b)597 %r = xor i32 %r1, %r2598 ret i32 %r599}600 601define i32 @xor_i32_same(<4 x i32> %a, <4 x i32> %b) {602; CHECK-SD-LABEL: xor_i32_same:603; CHECK-SD: // %bb.0:604; CHECK-SD-NEXT: eor v0.16b, v0.16b, v1.16b605; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #8606; CHECK-SD-NEXT: eor v0.8b, v0.8b, v1.8b607; CHECK-SD-NEXT: fmov x8, d0608; CHECK-SD-NEXT: lsr x9, x8, #32609; CHECK-SD-NEXT: eor w0, w8, w9610; CHECK-SD-NEXT: ret611;612; CHECK-GI-LABEL: xor_i32_same:613; CHECK-GI: // %bb.0:614; CHECK-GI-NEXT: mov d2, v0.d[1]615; CHECK-GI-NEXT: mov d3, v1.d[1]616; CHECK-GI-NEXT: eor v0.8b, v0.8b, v2.8b617; CHECK-GI-NEXT: eor v1.8b, v1.8b, v3.8b618; CHECK-GI-NEXT: mov w8, v0.s[1]619; CHECK-GI-NEXT: mov w9, v1.s[1]620; CHECK-GI-NEXT: fmov w10, s0621; CHECK-GI-NEXT: fmov w11, s1622; CHECK-GI-NEXT: eor w8, w10, w8623; CHECK-GI-NEXT: eor w9, w11, w9624; CHECK-GI-NEXT: eor w0, w8, w9625; CHECK-GI-NEXT: ret626 %r1 = call i32 @llvm.vector.reduce.xor.i32.v4i32(<4 x i32> %a)627 %r2 = call i32 @llvm.vector.reduce.xor.i32.v4i32(<4 x i32> %b)628 %r = xor i32 %r1, %r2629 ret i32 %r630}631 632define i32 @umin_i32(<8 x i32> %a, <4 x i32> %b) {633; CHECK-SD-LABEL: umin_i32:634; CHECK-SD: // %bb.0:635; CHECK-SD-NEXT: umin v0.4s, v0.4s, v1.4s636; CHECK-SD-NEXT: umin v0.4s, v0.4s, v2.4s637; CHECK-SD-NEXT: uminv s0, v0.4s638; CHECK-SD-NEXT: fmov w0, s0639; CHECK-SD-NEXT: ret640;641; CHECK-GI-LABEL: umin_i32:642; CHECK-GI: // %bb.0:643; CHECK-GI-NEXT: umin v0.4s, v0.4s, v1.4s644; CHECK-GI-NEXT: uminv s1, v2.4s645; CHECK-GI-NEXT: uminv s0, v0.4s646; CHECK-GI-NEXT: fmov w9, s1647; CHECK-GI-NEXT: fmov w8, s0648; CHECK-GI-NEXT: cmp w8, w9649; CHECK-GI-NEXT: fcsel s0, s0, s1, lo650; CHECK-GI-NEXT: fmov w0, s0651; CHECK-GI-NEXT: ret652 %r1 = call i32 @llvm.vector.reduce.umin.i32.v8i32(<8 x i32> %a)653 %r2 = call i32 @llvm.vector.reduce.umin.i32.v4i32(<4 x i32> %b)654 %r = call i32 @llvm.umin.i32(i32 %r1, i32 %r2)655 ret i32 %r656}657 658define i32 @umin_i32_same(<4 x i32> %a, <4 x i32> %b) {659; CHECK-SD-LABEL: umin_i32_same:660; CHECK-SD: // %bb.0:661; CHECK-SD-NEXT: umin v0.4s, v0.4s, v1.4s662; CHECK-SD-NEXT: uminv s0, v0.4s663; CHECK-SD-NEXT: fmov w0, s0664; CHECK-SD-NEXT: ret665;666; CHECK-GI-LABEL: umin_i32_same:667; CHECK-GI: // %bb.0:668; CHECK-GI-NEXT: uminv s0, v0.4s669; CHECK-GI-NEXT: uminv s1, v1.4s670; CHECK-GI-NEXT: fmov w8, s0671; CHECK-GI-NEXT: fmov w9, s1672; CHECK-GI-NEXT: cmp w8, w9673; CHECK-GI-NEXT: fcsel s0, s0, s1, lo674; CHECK-GI-NEXT: fmov w0, s0675; CHECK-GI-NEXT: ret676 %r1 = call i32 @llvm.vector.reduce.umin.i32.v4i32(<4 x i32> %a)677 %r2 = call i32 @llvm.vector.reduce.umin.i32.v4i32(<4 x i32> %b)678 %r = call i32 @llvm.umin.i32(i32 %r1, i32 %r2)679 ret i32 %r680}681 682define i32 @umax_i32(<8 x i32> %a, <4 x i32> %b) {683; CHECK-SD-LABEL: umax_i32:684; CHECK-SD: // %bb.0:685; CHECK-SD-NEXT: umax v0.4s, v0.4s, v1.4s686; CHECK-SD-NEXT: umax v0.4s, v0.4s, v2.4s687; CHECK-SD-NEXT: umaxv s0, v0.4s688; CHECK-SD-NEXT: fmov w0, s0689; CHECK-SD-NEXT: ret690;691; CHECK-GI-LABEL: umax_i32:692; CHECK-GI: // %bb.0:693; CHECK-GI-NEXT: umax v0.4s, v0.4s, v1.4s694; CHECK-GI-NEXT: umaxv s1, v2.4s695; CHECK-GI-NEXT: umaxv s0, v0.4s696; CHECK-GI-NEXT: fmov w9, s1697; CHECK-GI-NEXT: fmov w8, s0698; CHECK-GI-NEXT: cmp w8, w9699; CHECK-GI-NEXT: fcsel s0, s0, s1, hi700; CHECK-GI-NEXT: fmov w0, s0701; CHECK-GI-NEXT: ret702 %r1 = call i32 @llvm.vector.reduce.umax.i32.v8i32(<8 x i32> %a)703 %r2 = call i32 @llvm.vector.reduce.umax.i32.v4i32(<4 x i32> %b)704 %r = call i32 @llvm.umax.i32(i32 %r1, i32 %r2)705 ret i32 %r706}707 708define i32 @umax_i32_same(<4 x i32> %a, <4 x i32> %b) {709; CHECK-SD-LABEL: umax_i32_same:710; CHECK-SD: // %bb.0:711; CHECK-SD-NEXT: umax v0.4s, v0.4s, v1.4s712; CHECK-SD-NEXT: umaxv s0, v0.4s713; CHECK-SD-NEXT: fmov w0, s0714; CHECK-SD-NEXT: ret715;716; CHECK-GI-LABEL: umax_i32_same:717; CHECK-GI: // %bb.0:718; CHECK-GI-NEXT: umaxv s0, v0.4s719; CHECK-GI-NEXT: umaxv s1, v1.4s720; CHECK-GI-NEXT: fmov w8, s0721; CHECK-GI-NEXT: fmov w9, s1722; CHECK-GI-NEXT: cmp w8, w9723; CHECK-GI-NEXT: fcsel s0, s0, s1, hi724; CHECK-GI-NEXT: fmov w0, s0725; CHECK-GI-NEXT: ret726 %r1 = call i32 @llvm.vector.reduce.umax.i32.v4i32(<4 x i32> %a)727 %r2 = call i32 @llvm.vector.reduce.umax.i32.v4i32(<4 x i32> %b)728 %r = call i32 @llvm.umax.i32(i32 %r1, i32 %r2)729 ret i32 %r730}731 732define i32 @smin_i32(<8 x i32> %a, <4 x i32> %b) {733; CHECK-SD-LABEL: smin_i32:734; CHECK-SD: // %bb.0:735; CHECK-SD-NEXT: smin v0.4s, v0.4s, v1.4s736; CHECK-SD-NEXT: smin v0.4s, v0.4s, v2.4s737; CHECK-SD-NEXT: sminv s0, v0.4s738; CHECK-SD-NEXT: fmov w0, s0739; CHECK-SD-NEXT: ret740;741; CHECK-GI-LABEL: smin_i32:742; CHECK-GI: // %bb.0:743; CHECK-GI-NEXT: smin v0.4s, v0.4s, v1.4s744; CHECK-GI-NEXT: sminv s1, v2.4s745; CHECK-GI-NEXT: sminv s0, v0.4s746; CHECK-GI-NEXT: fmov w9, s1747; CHECK-GI-NEXT: fmov w8, s0748; CHECK-GI-NEXT: cmp w8, w9749; CHECK-GI-NEXT: fcsel s0, s0, s1, lt750; CHECK-GI-NEXT: fmov w0, s0751; CHECK-GI-NEXT: ret752 %r1 = call i32 @llvm.vector.reduce.smin.i32.v8i32(<8 x i32> %a)753 %r2 = call i32 @llvm.vector.reduce.smin.i32.v4i32(<4 x i32> %b)754 %r = call i32 @llvm.smin.i32(i32 %r1, i32 %r2)755 ret i32 %r756}757 758define i32 @smin_i32_same(<4 x i32> %a, <4 x i32> %b) {759; CHECK-SD-LABEL: smin_i32_same:760; CHECK-SD: // %bb.0:761; CHECK-SD-NEXT: smin v0.4s, v0.4s, v1.4s762; CHECK-SD-NEXT: sminv s0, v0.4s763; CHECK-SD-NEXT: fmov w0, s0764; CHECK-SD-NEXT: ret765;766; CHECK-GI-LABEL: smin_i32_same:767; CHECK-GI: // %bb.0:768; CHECK-GI-NEXT: sminv s0, v0.4s769; CHECK-GI-NEXT: sminv s1, v1.4s770; CHECK-GI-NEXT: fmov w8, s0771; CHECK-GI-NEXT: fmov w9, s1772; CHECK-GI-NEXT: cmp w8, w9773; CHECK-GI-NEXT: fcsel s0, s0, s1, lt774; CHECK-GI-NEXT: fmov w0, s0775; CHECK-GI-NEXT: ret776 %r1 = call i32 @llvm.vector.reduce.smin.i32.v4i32(<4 x i32> %a)777 %r2 = call i32 @llvm.vector.reduce.smin.i32.v4i32(<4 x i32> %b)778 %r = call i32 @llvm.smin.i32(i32 %r1, i32 %r2)779 ret i32 %r780}781 782define i32 @smax_i32(<8 x i32> %a, <4 x i32> %b) {783; CHECK-SD-LABEL: smax_i32:784; CHECK-SD: // %bb.0:785; CHECK-SD-NEXT: smax v0.4s, v0.4s, v1.4s786; CHECK-SD-NEXT: smax v0.4s, v0.4s, v2.4s787; CHECK-SD-NEXT: smaxv s0, v0.4s788; CHECK-SD-NEXT: fmov w0, s0789; CHECK-SD-NEXT: ret790;791; CHECK-GI-LABEL: smax_i32:792; CHECK-GI: // %bb.0:793; CHECK-GI-NEXT: smax v0.4s, v0.4s, v1.4s794; CHECK-GI-NEXT: smaxv s1, v2.4s795; CHECK-GI-NEXT: smaxv s0, v0.4s796; CHECK-GI-NEXT: fmov w9, s1797; CHECK-GI-NEXT: fmov w8, s0798; CHECK-GI-NEXT: cmp w8, w9799; CHECK-GI-NEXT: fcsel s0, s0, s1, gt800; CHECK-GI-NEXT: fmov w0, s0801; CHECK-GI-NEXT: ret802 %r1 = call i32 @llvm.vector.reduce.smax.i32.v8i32(<8 x i32> %a)803 %r2 = call i32 @llvm.vector.reduce.smax.i32.v4i32(<4 x i32> %b)804 %r = call i32 @llvm.smax.i32(i32 %r1, i32 %r2)805 ret i32 %r806}807 808define i32 @smax_i32_same(<4 x i32> %a, <4 x i32> %b) {809; CHECK-SD-LABEL: smax_i32_same:810; CHECK-SD: // %bb.0:811; CHECK-SD-NEXT: smax v0.4s, v0.4s, v1.4s812; CHECK-SD-NEXT: smaxv s0, v0.4s813; CHECK-SD-NEXT: fmov w0, s0814; CHECK-SD-NEXT: ret815;816; CHECK-GI-LABEL: smax_i32_same:817; CHECK-GI: // %bb.0:818; CHECK-GI-NEXT: smaxv s0, v0.4s819; CHECK-GI-NEXT: smaxv s1, v1.4s820; CHECK-GI-NEXT: fmov w8, s0821; CHECK-GI-NEXT: fmov w9, s1822; CHECK-GI-NEXT: cmp w8, w9823; CHECK-GI-NEXT: fcsel s0, s0, s1, gt824; CHECK-GI-NEXT: fmov w0, s0825; CHECK-GI-NEXT: ret826 %r1 = call i32 @llvm.vector.reduce.smax.i32.v4i32(<4 x i32> %a)827 %r2 = call i32 @llvm.vector.reduce.smax.i32.v4i32(<4 x i32> %b)828 %r = call i32 @llvm.smax.i32(i32 %r1, i32 %r2)829 ret i32 %r830}831 832 833define float @nested_fadd_f32(<4 x float> %a, <4 x float> %b, float %c, float %d) {834; CHECK-SD-LABEL: nested_fadd_f32:835; CHECK-SD: // %bb.0:836; CHECK-SD-NEXT: fadd v0.4s, v0.4s, v1.4s837; CHECK-SD-NEXT: fadd s2, s2, s3838; CHECK-SD-NEXT: faddp v0.4s, v0.4s, v0.4s839; CHECK-SD-NEXT: faddp s0, v0.2s840; CHECK-SD-NEXT: fadd s0, s0, s2841; CHECK-SD-NEXT: ret842;843; CHECK-GI-LABEL: nested_fadd_f32:844; CHECK-GI: // %bb.0:845; CHECK-GI-NEXT: faddp v0.4s, v0.4s, v0.4s846; CHECK-GI-NEXT: faddp v1.4s, v1.4s, v1.4s847; CHECK-GI-NEXT: faddp s0, v0.2s848; CHECK-GI-NEXT: faddp s1, v1.2s849; CHECK-GI-NEXT: fadd s0, s0, s2850; CHECK-GI-NEXT: fadd s1, s1, s3851; CHECK-GI-NEXT: fadd s0, s0, s1852; CHECK-GI-NEXT: ret853 %r1 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float -0.0, <4 x float> %a)854 %a1 = fadd fast float %r1, %c855 %r2 = call fast float @llvm.vector.reduce.fadd.f32.v4f32(float -0.0, <4 x float> %b)856 %a2 = fadd fast float %r2, %d857 %r = fadd fast float %a1, %a2858 ret float %r859}860 861define float @nested_fadd_f32_slow(<4 x float> %a, <4 x float> %b, float %c, float %d) {862; CHECK-SD-LABEL: nested_fadd_f32_slow:863; CHECK-SD: // %bb.0:864; CHECK-SD-NEXT: mov s4, v1.s[2]865; CHECK-SD-NEXT: mov s5, v0.s[2]866; CHECK-SD-NEXT: faddp s6, v0.2s867; CHECK-SD-NEXT: faddp s7, v1.2s868; CHECK-SD-NEXT: mov s1, v1.s[3]869; CHECK-SD-NEXT: mov s0, v0.s[3]870; CHECK-SD-NEXT: fadd s5, s6, s5871; CHECK-SD-NEXT: fadd s4, s7, s4872; CHECK-SD-NEXT: fadd s0, s5, s0873; CHECK-SD-NEXT: fadd s1, s4, s1874; CHECK-SD-NEXT: fadd s0, s0, s2875; CHECK-SD-NEXT: fadd s1, s1, s3876; CHECK-SD-NEXT: fadd s0, s0, s1877; CHECK-SD-NEXT: ret878;879; CHECK-GI-LABEL: nested_fadd_f32_slow:880; CHECK-GI: // %bb.0:881; CHECK-GI-NEXT: mov s4, v0.s[2]882; CHECK-GI-NEXT: faddp s5, v0.2s883; CHECK-GI-NEXT: mov s6, v1.s[2]884; CHECK-GI-NEXT: faddp s7, v1.2s885; CHECK-GI-NEXT: mov s0, v0.s[3]886; CHECK-GI-NEXT: mov s1, v1.s[3]887; CHECK-GI-NEXT: fadd s4, s5, s4888; CHECK-GI-NEXT: fadd s5, s7, s6889; CHECK-GI-NEXT: fadd s0, s4, s0890; CHECK-GI-NEXT: fadd s1, s5, s1891; CHECK-GI-NEXT: fadd s0, s0, s2892; CHECK-GI-NEXT: fadd s1, s1, s3893; CHECK-GI-NEXT: fadd s0, s0, s1894; CHECK-GI-NEXT: ret895 %r1 = call float @llvm.vector.reduce.fadd.f32.v4f32(float -0.0, <4 x float> %a)896 %a1 = fadd float %r1, %c897 %r2 = call float @llvm.vector.reduce.fadd.f32.v4f32(float -0.0, <4 x float> %b)898 %a2 = fadd float %r2, %d899 %r = fadd float %a1, %a2900 ret float %r901}902 903define float @nested_mul_f32(<4 x float> %a, <4 x float> %b, float %c, float %d) {904; CHECK-SD-LABEL: nested_mul_f32:905; CHECK-SD: // %bb.0:906; CHECK-SD-NEXT: fmul v0.4s, v0.4s, v1.4s907; CHECK-SD-NEXT: fmul s2, s2, s3908; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #8909; CHECK-SD-NEXT: fmul v0.2s, v0.2s, v1.2s910; CHECK-SD-NEXT: fmul s0, s0, v0.s[1]911; CHECK-SD-NEXT: fmul s0, s0, s2912; CHECK-SD-NEXT: ret913;914; CHECK-GI-LABEL: nested_mul_f32:915; CHECK-GI: // %bb.0:916; CHECK-GI-NEXT: mov d4, v0.d[1]917; CHECK-GI-NEXT: mov d5, v1.d[1]918; CHECK-GI-NEXT: fmul v0.2s, v0.2s, v4.2s919; CHECK-GI-NEXT: fmul v1.2s, v1.2s, v5.2s920; CHECK-GI-NEXT: mov s4, v0.s[1]921; CHECK-GI-NEXT: mov s5, v1.s[1]922; CHECK-GI-NEXT: fmul s0, s0, s4923; CHECK-GI-NEXT: fmul s1, s1, s5924; CHECK-GI-NEXT: fmul s0, s0, s2925; CHECK-GI-NEXT: fmul s1, s1, s3926; CHECK-GI-NEXT: fmul s0, s0, s1927; CHECK-GI-NEXT: ret928 %r1 = call fast float @llvm.vector.reduce.fmul.f32.v4f32(float 1.0, <4 x float> %a)929 %a1 = fmul fast float %r1, %c930 %r2 = call fast float @llvm.vector.reduce.fmul.f32.v4f32(float 1.0, <4 x float> %b)931 %a2 = fmul fast float %r2, %d932 %r = fmul fast float %a1, %a2933 ret float %r934}935 936define i32 @nested_add_i32(<4 x i32> %a, <4 x i32> %b, i32 %c, i32 %d) {937; CHECK-SD-LABEL: nested_add_i32:938; CHECK-SD: // %bb.0:939; CHECK-SD-NEXT: add v0.4s, v0.4s, v1.4s940; CHECK-SD-NEXT: add w8, w0, w1941; CHECK-SD-NEXT: addv s0, v0.4s942; CHECK-SD-NEXT: fmov w9, s0943; CHECK-SD-NEXT: add w0, w9, w8944; CHECK-SD-NEXT: ret945;946; CHECK-GI-LABEL: nested_add_i32:947; CHECK-GI: // %bb.0:948; CHECK-GI-NEXT: addv s0, v0.4s949; CHECK-GI-NEXT: addv s1, v1.4s950; CHECK-GI-NEXT: fmov w8, s0951; CHECK-GI-NEXT: fmov w9, s1952; CHECK-GI-NEXT: add w8, w8, w0953; CHECK-GI-NEXT: add w9, w9, w1954; CHECK-GI-NEXT: add w0, w8, w9955; CHECK-GI-NEXT: ret956 %r1 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %a)957 %a1 = add i32 %r1, %c958 %r2 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %b)959 %a2 = add i32 %r2, %d960 %r = add i32 %a1, %a2961 ret i32 %r962}963 964define i32 @nested_add_c1_i32(<4 x i32> %a, <4 x i32> %b, i32 %c, i32 %d) {965; CHECK-SD-LABEL: nested_add_c1_i32:966; CHECK-SD: // %bb.0:967; CHECK-SD-NEXT: add v0.4s, v0.4s, v1.4s968; CHECK-SD-NEXT: add w8, w0, w1969; CHECK-SD-NEXT: addv s0, v0.4s970; CHECK-SD-NEXT: fmov w9, s0971; CHECK-SD-NEXT: add w0, w9, w8972; CHECK-SD-NEXT: ret973;974; CHECK-GI-LABEL: nested_add_c1_i32:975; CHECK-GI: // %bb.0:976; CHECK-GI-NEXT: addv s0, v0.4s977; CHECK-GI-NEXT: addv s1, v1.4s978; CHECK-GI-NEXT: fmov w8, s0979; CHECK-GI-NEXT: fmov w9, s1980; CHECK-GI-NEXT: add w8, w0, w8981; CHECK-GI-NEXT: add w9, w9, w1982; CHECK-GI-NEXT: add w0, w8, w9983; CHECK-GI-NEXT: ret984 %r1 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %a)985 %a1 = add i32 %c, %r1986 %r2 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %b)987 %a2 = add i32 %r2, %d988 %r = add i32 %a1, %a2989 ret i32 %r990}991 992define i32 @nested_add_c2_i32(<4 x i32> %a, <4 x i32> %b, i32 %c, i32 %d) {993; CHECK-SD-LABEL: nested_add_c2_i32:994; CHECK-SD: // %bb.0:995; CHECK-SD-NEXT: add v0.4s, v0.4s, v1.4s996; CHECK-SD-NEXT: add w8, w0, w1997; CHECK-SD-NEXT: addv s0, v0.4s998; CHECK-SD-NEXT: fmov w9, s0999; CHECK-SD-NEXT: add w0, w9, w81000; CHECK-SD-NEXT: ret1001;1002; CHECK-GI-LABEL: nested_add_c2_i32:1003; CHECK-GI: // %bb.0:1004; CHECK-GI-NEXT: addv s0, v0.4s1005; CHECK-GI-NEXT: addv s1, v1.4s1006; CHECK-GI-NEXT: fmov w8, s01007; CHECK-GI-NEXT: fmov w9, s11008; CHECK-GI-NEXT: add w8, w8, w01009; CHECK-GI-NEXT: add w9, w1, w91010; CHECK-GI-NEXT: add w0, w8, w91011; CHECK-GI-NEXT: ret1012 %r1 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %a)1013 %a1 = add i32 %r1, %c1014 %r2 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %b)1015 %a2 = add i32 %d, %r21016 %r = add i32 %a1, %a21017 ret i32 %r1018}1019 1020define i32 @nested_add_manyreduct_i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c, <4 x i32> %d) {1021; CHECK-SD-LABEL: nested_add_manyreduct_i32:1022; CHECK-SD: // %bb.0:1023; CHECK-SD-NEXT: add v1.4s, v1.4s, v3.4s1024; CHECK-SD-NEXT: add v0.4s, v0.4s, v2.4s1025; CHECK-SD-NEXT: add v0.4s, v0.4s, v1.4s1026; CHECK-SD-NEXT: addv s0, v0.4s1027; CHECK-SD-NEXT: fmov w0, s01028; CHECK-SD-NEXT: ret1029;1030; CHECK-GI-LABEL: nested_add_manyreduct_i32:1031; CHECK-GI: // %bb.0:1032; CHECK-GI-NEXT: addv s0, v0.4s1033; CHECK-GI-NEXT: addv s2, v2.4s1034; CHECK-GI-NEXT: addv s1, v1.4s1035; CHECK-GI-NEXT: addv s3, v3.4s1036; CHECK-GI-NEXT: fmov w8, s01037; CHECK-GI-NEXT: fmov w9, s21038; CHECK-GI-NEXT: fmov w10, s11039; CHECK-GI-NEXT: fmov w11, s31040; CHECK-GI-NEXT: add w8, w8, w91041; CHECK-GI-NEXT: add w9, w10, w111042; CHECK-GI-NEXT: add w0, w8, w91043; CHECK-GI-NEXT: ret1044 %r1 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %a)1045 %r3 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %c)1046 %a1 = add i32 %r1, %r31047 %r2 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %b)1048 %r4 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %d)1049 %a2 = add i32 %r2, %r41050 %r = add i32 %a1, %a21051 ret i32 %r1052}1053 1054define i32 @nested_mul_i32(<4 x i32> %a, <4 x i32> %b, i32 %c, i32 %d) {1055; CHECK-SD-LABEL: nested_mul_i32:1056; CHECK-SD: // %bb.0:1057; CHECK-SD-NEXT: mul v0.4s, v0.4s, v1.4s1058; CHECK-SD-NEXT: mul w8, w0, w11059; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #81060; CHECK-SD-NEXT: mul v0.2s, v0.2s, v1.2s1061; CHECK-SD-NEXT: mov w9, v0.s[1]1062; CHECK-SD-NEXT: fmov w10, s01063; CHECK-SD-NEXT: mul w9, w10, w91064; CHECK-SD-NEXT: mul w0, w9, w81065; CHECK-SD-NEXT: ret1066;1067; CHECK-GI-LABEL: nested_mul_i32:1068; CHECK-GI: // %bb.0:1069; CHECK-GI-NEXT: mov d2, v0.d[1]1070; CHECK-GI-NEXT: mov d3, v1.d[1]1071; CHECK-GI-NEXT: mul v0.2s, v0.2s, v2.2s1072; CHECK-GI-NEXT: mul v1.2s, v1.2s, v3.2s1073; CHECK-GI-NEXT: mov w8, v0.s[1]1074; CHECK-GI-NEXT: fmov w10, s01075; CHECK-GI-NEXT: mov w9, v1.s[1]1076; CHECK-GI-NEXT: mul w8, w10, w81077; CHECK-GI-NEXT: fmov w10, s11078; CHECK-GI-NEXT: mul w9, w10, w91079; CHECK-GI-NEXT: mul w8, w8, w01080; CHECK-GI-NEXT: mul w9, w9, w11081; CHECK-GI-NEXT: mul w0, w8, w91082; CHECK-GI-NEXT: ret1083 %r1 = call i32 @llvm.vector.reduce.mul.v4i32(<4 x i32> %a)1084 %a1 = mul i32 %r1, %c1085 %r2 = call i32 @llvm.vector.reduce.mul.v4i32(<4 x i32> %b)1086 %a2 = mul i32 %r2, %d1087 %r = mul i32 %a1, %a21088 ret i32 %r1089}1090 1091define i32 @nested_and_i32(<4 x i32> %a, <4 x i32> %b, i32 %c, i32 %d) {1092; CHECK-SD-LABEL: nested_and_i32:1093; CHECK-SD: // %bb.0:1094; CHECK-SD-NEXT: and v0.16b, v0.16b, v1.16b1095; CHECK-SD-NEXT: and w8, w0, w11096; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #81097; CHECK-SD-NEXT: and v0.8b, v0.8b, v1.8b1098; CHECK-SD-NEXT: fmov x9, d01099; CHECK-SD-NEXT: lsr x10, x9, #321100; CHECK-SD-NEXT: and w8, w9, w81101; CHECK-SD-NEXT: and w0, w8, w101102; CHECK-SD-NEXT: ret1103;1104; CHECK-GI-LABEL: nested_and_i32:1105; CHECK-GI: // %bb.0:1106; CHECK-GI-NEXT: mov d2, v0.d[1]1107; CHECK-GI-NEXT: mov d3, v1.d[1]1108; CHECK-GI-NEXT: and v0.8b, v0.8b, v2.8b1109; CHECK-GI-NEXT: and v1.8b, v1.8b, v3.8b1110; CHECK-GI-NEXT: mov w8, v0.s[1]1111; CHECK-GI-NEXT: mov w9, v1.s[1]1112; CHECK-GI-NEXT: fmov w10, s01113; CHECK-GI-NEXT: fmov w11, s11114; CHECK-GI-NEXT: and w10, w10, w01115; CHECK-GI-NEXT: and w11, w11, w11116; CHECK-GI-NEXT: and w8, w10, w81117; CHECK-GI-NEXT: and w9, w11, w91118; CHECK-GI-NEXT: and w0, w8, w91119; CHECK-GI-NEXT: ret1120 %r1 = call i32 @llvm.vector.reduce.and.v4i32(<4 x i32> %a)1121 %a1 = and i32 %r1, %c1122 %r2 = call i32 @llvm.vector.reduce.and.v4i32(<4 x i32> %b)1123 %a2 = and i32 %r2, %d1124 %r = and i32 %a1, %a21125 ret i32 %r1126}1127 1128define i32 @nested_or_i32(<4 x i32> %a, <4 x i32> %b, i32 %c, i32 %d) {1129; CHECK-SD-LABEL: nested_or_i32:1130; CHECK-SD: // %bb.0:1131; CHECK-SD-NEXT: orr v0.16b, v0.16b, v1.16b1132; CHECK-SD-NEXT: orr w8, w0, w11133; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #81134; CHECK-SD-NEXT: orr v0.8b, v0.8b, v1.8b1135; CHECK-SD-NEXT: fmov x9, d01136; CHECK-SD-NEXT: lsr x10, x9, #321137; CHECK-SD-NEXT: orr w8, w9, w81138; CHECK-SD-NEXT: orr w0, w8, w101139; CHECK-SD-NEXT: ret1140;1141; CHECK-GI-LABEL: nested_or_i32:1142; CHECK-GI: // %bb.0:1143; CHECK-GI-NEXT: mov d2, v0.d[1]1144; CHECK-GI-NEXT: mov d3, v1.d[1]1145; CHECK-GI-NEXT: orr v0.8b, v0.8b, v2.8b1146; CHECK-GI-NEXT: orr v1.8b, v1.8b, v3.8b1147; CHECK-GI-NEXT: mov w8, v0.s[1]1148; CHECK-GI-NEXT: mov w9, v1.s[1]1149; CHECK-GI-NEXT: fmov w10, s01150; CHECK-GI-NEXT: fmov w11, s11151; CHECK-GI-NEXT: orr w10, w10, w01152; CHECK-GI-NEXT: orr w11, w11, w11153; CHECK-GI-NEXT: orr w8, w10, w81154; CHECK-GI-NEXT: orr w9, w11, w91155; CHECK-GI-NEXT: orr w0, w8, w91156; CHECK-GI-NEXT: ret1157 %r1 = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %a)1158 %a1 = or i32 %r1, %c1159 %r2 = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %b)1160 %a2 = or i32 %r2, %d1161 %r = or i32 %a1, %a21162 ret i32 %r1163}1164 1165define i32 @nested_xor_i32(<4 x i32> %a, <4 x i32> %b, i32 %c, i32 %d) {1166; CHECK-SD-LABEL: nested_xor_i32:1167; CHECK-SD: // %bb.0:1168; CHECK-SD-NEXT: eor v0.16b, v0.16b, v1.16b1169; CHECK-SD-NEXT: eor w8, w0, w11170; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #81171; CHECK-SD-NEXT: eor v0.8b, v0.8b, v1.8b1172; CHECK-SD-NEXT: fmov x9, d01173; CHECK-SD-NEXT: lsr x10, x9, #321174; CHECK-SD-NEXT: eor w8, w9, w81175; CHECK-SD-NEXT: eor w0, w8, w101176; CHECK-SD-NEXT: ret1177;1178; CHECK-GI-LABEL: nested_xor_i32:1179; CHECK-GI: // %bb.0:1180; CHECK-GI-NEXT: mov d2, v0.d[1]1181; CHECK-GI-NEXT: mov d3, v1.d[1]1182; CHECK-GI-NEXT: eor v0.8b, v0.8b, v2.8b1183; CHECK-GI-NEXT: eor v1.8b, v1.8b, v3.8b1184; CHECK-GI-NEXT: mov w8, v0.s[1]1185; CHECK-GI-NEXT: mov w9, v1.s[1]1186; CHECK-GI-NEXT: fmov w10, s01187; CHECK-GI-NEXT: fmov w11, s11188; CHECK-GI-NEXT: eor w10, w10, w01189; CHECK-GI-NEXT: eor w11, w11, w11190; CHECK-GI-NEXT: eor w8, w10, w81191; CHECK-GI-NEXT: eor w9, w11, w91192; CHECK-GI-NEXT: eor w0, w8, w91193; CHECK-GI-NEXT: ret1194 %r1 = call i32 @llvm.vector.reduce.xor.v4i32(<4 x i32> %a)1195 %a1 = xor i32 %r1, %c1196 %r2 = call i32 @llvm.vector.reduce.xor.v4i32(<4 x i32> %b)1197 %a2 = xor i32 %r2, %d1198 %r = xor i32 %a1, %a21199 ret i32 %r1200}1201 1202define i32 @nested_smin_i32(<4 x i32> %a, <4 x i32> %b, i32 %c, i32 %d) {1203; CHECK-SD-LABEL: nested_smin_i32:1204; CHECK-SD: // %bb.0:1205; CHECK-SD-NEXT: smin v0.4s, v0.4s, v1.4s1206; CHECK-SD-NEXT: cmp w0, w11207; CHECK-SD-NEXT: csel w8, w0, w1, lt1208; CHECK-SD-NEXT: sminv s0, v0.4s1209; CHECK-SD-NEXT: fmov w9, s01210; CHECK-SD-NEXT: cmp w9, w81211; CHECK-SD-NEXT: csel w0, w9, w8, lt1212; CHECK-SD-NEXT: ret1213;1214; CHECK-GI-LABEL: nested_smin_i32:1215; CHECK-GI: // %bb.0:1216; CHECK-GI-NEXT: sminv s0, v0.4s1217; CHECK-GI-NEXT: sminv s1, v1.4s1218; CHECK-GI-NEXT: fmov w8, s01219; CHECK-GI-NEXT: fmov w9, s11220; CHECK-GI-NEXT: cmp w8, w01221; CHECK-GI-NEXT: csel w8, w8, w0, lt1222; CHECK-GI-NEXT: cmp w9, w11223; CHECK-GI-NEXT: csel w9, w9, w1, lt1224; CHECK-GI-NEXT: cmp w8, w91225; CHECK-GI-NEXT: csel w0, w8, w9, lt1226; CHECK-GI-NEXT: ret1227 %r1 = call i32 @llvm.vector.reduce.smin.v4i32(<4 x i32> %a)1228 %a1 = call i32 @llvm.smin.i32(i32 %r1, i32 %c)1229 %r2 = call i32 @llvm.vector.reduce.smin.v4i32(<4 x i32> %b)1230 %a2 = call i32 @llvm.smin.i32(i32 %r2, i32 %d)1231 %r = call i32 @llvm.smin.i32(i32 %a1, i32 %a2)1232 ret i32 %r1233}1234 1235define i32 @nested_smax_i32(<4 x i32> %a, <4 x i32> %b, i32 %c, i32 %d) {1236; CHECK-SD-LABEL: nested_smax_i32:1237; CHECK-SD: // %bb.0:1238; CHECK-SD-NEXT: smax v0.4s, v0.4s, v1.4s1239; CHECK-SD-NEXT: cmp w0, w11240; CHECK-SD-NEXT: csel w8, w0, w1, gt1241; CHECK-SD-NEXT: smaxv s0, v0.4s1242; CHECK-SD-NEXT: fmov w9, s01243; CHECK-SD-NEXT: cmp w9, w81244; CHECK-SD-NEXT: csel w0, w9, w8, gt1245; CHECK-SD-NEXT: ret1246;1247; CHECK-GI-LABEL: nested_smax_i32:1248; CHECK-GI: // %bb.0:1249; CHECK-GI-NEXT: smaxv s0, v0.4s1250; CHECK-GI-NEXT: smaxv s1, v1.4s1251; CHECK-GI-NEXT: fmov w8, s01252; CHECK-GI-NEXT: fmov w9, s11253; CHECK-GI-NEXT: cmp w8, w01254; CHECK-GI-NEXT: csel w8, w8, w0, gt1255; CHECK-GI-NEXT: cmp w9, w11256; CHECK-GI-NEXT: csel w9, w9, w1, gt1257; CHECK-GI-NEXT: cmp w8, w91258; CHECK-GI-NEXT: csel w0, w8, w9, gt1259; CHECK-GI-NEXT: ret1260 %r1 = call i32 @llvm.vector.reduce.smax.v4i32(<4 x i32> %a)1261 %a1 = call i32 @llvm.smax.i32(i32 %r1, i32 %c)1262 %r2 = call i32 @llvm.vector.reduce.smax.v4i32(<4 x i32> %b)1263 %a2 = call i32 @llvm.smax.i32(i32 %r2, i32 %d)1264 %r = call i32 @llvm.smax.i32(i32 %a1, i32 %a2)1265 ret i32 %r1266}1267 1268define i32 @nested_umin_i32(<4 x i32> %a, <4 x i32> %b, i32 %c, i32 %d) {1269; CHECK-SD-LABEL: nested_umin_i32:1270; CHECK-SD: // %bb.0:1271; CHECK-SD-NEXT: umin v0.4s, v0.4s, v1.4s1272; CHECK-SD-NEXT: cmp w0, w11273; CHECK-SD-NEXT: csel w8, w0, w1, lo1274; CHECK-SD-NEXT: uminv s0, v0.4s1275; CHECK-SD-NEXT: fmov w9, s01276; CHECK-SD-NEXT: cmp w9, w81277; CHECK-SD-NEXT: csel w0, w9, w8, lo1278; CHECK-SD-NEXT: ret1279;1280; CHECK-GI-LABEL: nested_umin_i32:1281; CHECK-GI: // %bb.0:1282; CHECK-GI-NEXT: uminv s0, v0.4s1283; CHECK-GI-NEXT: uminv s1, v1.4s1284; CHECK-GI-NEXT: fmov w8, s01285; CHECK-GI-NEXT: fmov w9, s11286; CHECK-GI-NEXT: cmp w8, w01287; CHECK-GI-NEXT: csel w8, w8, w0, lo1288; CHECK-GI-NEXT: cmp w9, w11289; CHECK-GI-NEXT: csel w9, w9, w1, lo1290; CHECK-GI-NEXT: cmp w8, w91291; CHECK-GI-NEXT: csel w0, w8, w9, lo1292; CHECK-GI-NEXT: ret1293 %r1 = call i32 @llvm.vector.reduce.umin.v4i32(<4 x i32> %a)1294 %a1 = call i32 @llvm.umin.i32(i32 %r1, i32 %c)1295 %r2 = call i32 @llvm.vector.reduce.umin.v4i32(<4 x i32> %b)1296 %a2 = call i32 @llvm.umin.i32(i32 %r2, i32 %d)1297 %r = call i32 @llvm.umin.i32(i32 %a1, i32 %a2)1298 ret i32 %r1299}1300 1301define i32 @nested_umax_i32(<4 x i32> %a, <4 x i32> %b, i32 %c, i32 %d) {1302; CHECK-SD-LABEL: nested_umax_i32:1303; CHECK-SD: // %bb.0:1304; CHECK-SD-NEXT: umax v0.4s, v0.4s, v1.4s1305; CHECK-SD-NEXT: cmp w0, w11306; CHECK-SD-NEXT: csel w8, w0, w1, hi1307; CHECK-SD-NEXT: umaxv s0, v0.4s1308; CHECK-SD-NEXT: fmov w9, s01309; CHECK-SD-NEXT: cmp w9, w81310; CHECK-SD-NEXT: csel w0, w9, w8, hi1311; CHECK-SD-NEXT: ret1312;1313; CHECK-GI-LABEL: nested_umax_i32:1314; CHECK-GI: // %bb.0:1315; CHECK-GI-NEXT: umaxv s0, v0.4s1316; CHECK-GI-NEXT: umaxv s1, v1.4s1317; CHECK-GI-NEXT: fmov w8, s01318; CHECK-GI-NEXT: fmov w9, s11319; CHECK-GI-NEXT: cmp w8, w01320; CHECK-GI-NEXT: csel w8, w8, w0, hi1321; CHECK-GI-NEXT: cmp w9, w11322; CHECK-GI-NEXT: csel w9, w9, w1, hi1323; CHECK-GI-NEXT: cmp w8, w91324; CHECK-GI-NEXT: csel w0, w8, w9, hi1325; CHECK-GI-NEXT: ret1326 %r1 = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> %a)1327 %a1 = call i32 @llvm.umax.i32(i32 %r1, i32 %c)1328 %r2 = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> %b)1329 %a2 = call i32 @llvm.umax.i32(i32 %r2, i32 %d)1330 %r = call i32 @llvm.umax.i32(i32 %a1, i32 %a2)1331 ret i32 %r1332}1333 1334define float @nested_fmin_float(<4 x float> %a, <4 x float> %b, float %c, float %d) {1335; CHECK-SD-LABEL: nested_fmin_float:1336; CHECK-SD: // %bb.0:1337; CHECK-SD-NEXT: fminnm v0.4s, v0.4s, v1.4s1338; CHECK-SD-NEXT: fminnm s2, s2, s31339; CHECK-SD-NEXT: fminnmv s0, v0.4s1340; CHECK-SD-NEXT: fminnm s0, s0, s21341; CHECK-SD-NEXT: ret1342;1343; CHECK-GI-LABEL: nested_fmin_float:1344; CHECK-GI: // %bb.0:1345; CHECK-GI-NEXT: fminnmv s0, v0.4s1346; CHECK-GI-NEXT: fminnmv s1, v1.4s1347; CHECK-GI-NEXT: fminnm s0, s0, s21348; CHECK-GI-NEXT: fminnm s1, s1, s31349; CHECK-GI-NEXT: fminnm s0, s0, s11350; CHECK-GI-NEXT: ret1351 %r1 = call float @llvm.vector.reduce.fmin.v4f32(<4 x float> %a)1352 %a1 = call float @llvm.minnum.f32(float %r1, float %c)1353 %r2 = call float @llvm.vector.reduce.fmin.v4f32(<4 x float> %b)1354 %a2 = call float @llvm.minnum.f32(float %r2, float %d)1355 %r = call float @llvm.minnum.f32(float %a1, float %a2)1356 ret float %r1357}1358 1359define float @nested_fmax_float(<4 x float> %a, <4 x float> %b, float %c, float %d) {1360; CHECK-SD-LABEL: nested_fmax_float:1361; CHECK-SD: // %bb.0:1362; CHECK-SD-NEXT: fmaxnm v0.4s, v0.4s, v1.4s1363; CHECK-SD-NEXT: fmaxnm s2, s2, s31364; CHECK-SD-NEXT: fmaxnmv s0, v0.4s1365; CHECK-SD-NEXT: fmaxnm s0, s0, s21366; CHECK-SD-NEXT: ret1367;1368; CHECK-GI-LABEL: nested_fmax_float:1369; CHECK-GI: // %bb.0:1370; CHECK-GI-NEXT: fmaxnmv s0, v0.4s1371; CHECK-GI-NEXT: fmaxnmv s1, v1.4s1372; CHECK-GI-NEXT: fmaxnm s0, s0, s21373; CHECK-GI-NEXT: fmaxnm s1, s1, s31374; CHECK-GI-NEXT: fmaxnm s0, s0, s11375; CHECK-GI-NEXT: ret1376 %r1 = call float @llvm.vector.reduce.fmax.v4f32(<4 x float> %a)1377 %a1 = call float @llvm.maxnum.f32(float %r1, float %c)1378 %r2 = call float @llvm.vector.reduce.fmax.v4f32(<4 x float> %b)1379 %a2 = call float @llvm.maxnum.f32(float %r2, float %d)1380 %r = call float @llvm.maxnum.f32(float %a1, float %a2)1381 ret float %r1382}1383 1384 1385declare float @llvm.vector.reduce.fadd.f32.v8f32(float, <8 x float>)1386declare float @llvm.vector.reduce.fadd.f32.v4f32(float, <4 x float>)1387declare float @llvm.vector.reduce.fmul.f32.v8f32(float, <8 x float>)1388declare float @llvm.vector.reduce.fmul.f32.v4f32(float, <4 x float>)1389declare float @llvm.vector.reduce.fmin.v8f32(<8 x float>)1390declare float @llvm.vector.reduce.fmin.v4f32(<4 x float>)1391declare float @llvm.vector.reduce.fmax.v8f32(<8 x float>)1392declare float @llvm.vector.reduce.fmax.v4f32(<4 x float>)1393declare float @llvm.vector.reduce.fminimum.v8f32(<8 x float>)1394declare float @llvm.vector.reduce.fminimum.v4f32(<4 x float>)1395declare float @llvm.vector.reduce.fmaximum.v8f32(<8 x float>)1396declare float @llvm.vector.reduce.fmaximum.v4f32(<4 x float>)1397declare i32 @llvm.vector.reduce.add.i32.v8i32(<8 x i32>)1398declare i32 @llvm.vector.reduce.add.i32.v4i32(<4 x i32>)1399declare i16 @llvm.vector.reduce.add.i16.v32i16(<32 x i16>)1400declare i16 @llvm.vector.reduce.add.i16.v16i16(<16 x i16>)1401declare i32 @llvm.vector.reduce.mul.i32.v8i32(<8 x i32>)1402declare i32 @llvm.vector.reduce.mul.i32.v4i32(<4 x i32>)1403declare i32 @llvm.vector.reduce.and.i32.v8i32(<8 x i32>)1404declare i32 @llvm.vector.reduce.and.i32.v4i32(<4 x i32>)1405declare i32 @llvm.vector.reduce.or.i32.v8i32(<8 x i32>)1406declare i32 @llvm.vector.reduce.or.i32.v4i32(<4 x i32>)1407declare i32 @llvm.vector.reduce.xor.i32.v8i32(<8 x i32>)1408declare i32 @llvm.vector.reduce.xor.i32.v4i32(<4 x i32>)1409declare i32 @llvm.vector.reduce.umin.i32.v8i32(<8 x i32>)1410declare i32 @llvm.vector.reduce.umin.i32.v4i32(<4 x i32>)1411declare i32 @llvm.vector.reduce.umax.i32.v8i32(<8 x i32>)1412declare i32 @llvm.vector.reduce.umax.i32.v4i32(<4 x i32>)1413declare i32 @llvm.vector.reduce.smin.i32.v8i32(<8 x i32>)1414declare i32 @llvm.vector.reduce.smin.i32.v4i32(<4 x i32>)1415declare i32 @llvm.vector.reduce.smax.i32.v8i32(<8 x i32>)1416declare i32 @llvm.vector.reduce.smax.i32.v4i32(<4 x i32>)1417declare float @llvm.minnum.f32(float, float)1418declare float @llvm.maxnum.f32(float, float)1419declare float @llvm.minimum.f32(float, float)1420declare float @llvm.maximum.f32(float, float)1421declare i32 @llvm.umin.i32(i32, i32)1422declare i32 @llvm.umax.i32(i32, i32)1423declare i32 @llvm.smin.i32(i32, i32)1424declare i32 @llvm.smax.i32(i32, i32)1425