1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=aarch64-unknown-linux-gnu -mattr=+neon | FileCheck %s 3; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -mattr=+neon -global-isel -global-isel-abort=1 | FileCheck %s --check-prefix=GISEL 4 5 6define i1 @test_redand_v1i1(<1 x i1> %a) { 7; CHECK-LABEL: test_redand_v1i1: 8; CHECK: // %bb.0: 9; CHECK-NEXT: and w0, w0, #0x1 10; CHECK-NEXT: ret 11; 12; GISEL-LABEL: test_redand_v1i1: 13; GISEL: // %bb.0: 14; GISEL-NEXT: and w0, w0, #0x1 15; GISEL-NEXT: ret 16 %or_result = call i1 @llvm.vector.reduce.and.v1i1(<1 x i1> %a) 17 ret i1 %or_result 18} 19 20define i1 @test_redand_v2i1(<2 x i1> %a) { 21; CHECK-LABEL: test_redand_v2i1: 22; CHECK: // %bb.0: 23; CHECK-NEXT: shl v0.2s, v0.2s, #31 24; CHECK-NEXT: cmlt v0.2s, v0.2s, #0 25; CHECK-NEXT: uminp v0.2s, v0.2s, v0.2s 26; CHECK-NEXT: fmov w8, s0 27; CHECK-NEXT: and w0, w8, #0x1 28; CHECK-NEXT: ret 29; 30; GISEL-LABEL: test_redand_v2i1: 31; GISEL: // %bb.0: 32; GISEL-NEXT: // kill: def $d0 killed $d0 def $q0 33; GISEL-NEXT: mov w8, v0.s[1] 34; GISEL-NEXT: fmov w9, s0 35; GISEL-NEXT: and w8, w9, w8 36; GISEL-NEXT: and w0, w8, #0x1 37; GISEL-NEXT: ret 38 %or_result = call i1 @llvm.vector.reduce.and.v2i1(<2 x i1> %a) 39 ret i1 %or_result 40} 41 42define i1 @test_redand_v4i1(<4 x i1> %a) { 43; CHECK-LABEL: test_redand_v4i1: 44; CHECK: // %bb.0: 45; CHECK-NEXT: shl v0.4h, v0.4h, #15 46; CHECK-NEXT: cmlt v0.4h, v0.4h, #0 47; CHECK-NEXT: uminv h0, v0.4h 48; CHECK-NEXT: fmov w8, s0 49; CHECK-NEXT: and w0, w8, #0x1 50; CHECK-NEXT: ret 51; 52; GISEL-LABEL: test_redand_v4i1: 53; GISEL: // %bb.0: 54; GISEL-NEXT: // kill: def $d0 killed $d0 def $q0 55; GISEL-NEXT: umov w8, v0.h[0] 56; GISEL-NEXT: umov w9, v0.h[1] 57; GISEL-NEXT: umov w10, v0.h[2] 58; GISEL-NEXT: umov w11, v0.h[3] 59; GISEL-NEXT: and w8, w8, w9 60; GISEL-NEXT: and w9, w10, w11 61; GISEL-NEXT: and w8, w8, w9 62; GISEL-NEXT: and w0, w8, #0x1 63; GISEL-NEXT: ret 64 %or_result = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> %a) 65 ret i1 %or_result 66} 67 68define i1 @test_redand_v8i1(<8 x i1> %a) { 69; CHECK-LABEL: test_redand_v8i1: 70; CHECK: // %bb.0: 71; CHECK-NEXT: shl v0.8b, v0.8b, #7 72; CHECK-NEXT: cmlt v0.8b, v0.8b, #0 73; CHECK-NEXT: uminv b0, v0.8b 74; CHECK-NEXT: fmov w8, s0 75; CHECK-NEXT: and w0, w8, #0x1 76; CHECK-NEXT: ret 77; 78; GISEL-LABEL: test_redand_v8i1: 79; GISEL: // %bb.0: 80; GISEL-NEXT: // kill: def $d0 killed $d0 def $q0 81; GISEL-NEXT: umov w8, v0.b[0] 82; GISEL-NEXT: umov w9, v0.b[1] 83; GISEL-NEXT: umov w10, v0.b[2] 84; GISEL-NEXT: umov w11, v0.b[3] 85; GISEL-NEXT: umov w12, v0.b[4] 86; GISEL-NEXT: umov w13, v0.b[5] 87; GISEL-NEXT: umov w14, v0.b[6] 88; GISEL-NEXT: umov w15, v0.b[7] 89; GISEL-NEXT: and w8, w8, w9 90; GISEL-NEXT: and w9, w10, w11 91; GISEL-NEXT: and w10, w12, w13 92; GISEL-NEXT: and w11, w14, w15 93; GISEL-NEXT: and w8, w8, w9 94; GISEL-NEXT: and w9, w10, w11 95; GISEL-NEXT: and w8, w8, w9 96; GISEL-NEXT: and w0, w8, #0x1 97; GISEL-NEXT: ret 98 %or_result = call i1 @llvm.vector.reduce.and.v8i1(<8 x i1> %a) 99 ret i1 %or_result 100} 101 102define i1 @test_redand_v16i1(<16 x i1> %a) { 103; CHECK-LABEL: test_redand_v16i1: 104; CHECK: // %bb.0: 105; CHECK-NEXT: shl v0.16b, v0.16b, #7 106; CHECK-NEXT: cmlt v0.16b, v0.16b, #0 107; CHECK-NEXT: uminv b0, v0.16b 108; CHECK-NEXT: fmov w8, s0 109; CHECK-NEXT: and w0, w8, #0x1 110; CHECK-NEXT: ret 111; 112; GISEL-LABEL: test_redand_v16i1: 113; GISEL: // %bb.0: 114; GISEL-NEXT: umov w8, v0.b[0] 115; GISEL-NEXT: umov w9, v0.b[1] 116; GISEL-NEXT: umov w10, v0.b[2] 117; GISEL-NEXT: umov w11, v0.b[3] 118; GISEL-NEXT: umov w12, v0.b[4] 119; GISEL-NEXT: umov w13, v0.b[5] 120; GISEL-NEXT: umov w14, v0.b[6] 121; GISEL-NEXT: umov w15, v0.b[7] 122; GISEL-NEXT: umov w16, v0.b[8] 123; GISEL-NEXT: umov w17, v0.b[9] 124; GISEL-NEXT: umov w18, v0.b[10] 125; GISEL-NEXT: umov w0, v0.b[11] 126; GISEL-NEXT: and w8, w8, w9 127; GISEL-NEXT: umov w1, v0.b[12] 128; GISEL-NEXT: umov w2, v0.b[13] 129; GISEL-NEXT: and w9, w10, w11 130; GISEL-NEXT: and w10, w12, w13 131; GISEL-NEXT: umov w3, v0.b[14] 132; GISEL-NEXT: and w11, w14, w15 133; GISEL-NEXT: and w8, w8, w9 134; GISEL-NEXT: umov w4, v0.b[15] 135; GISEL-NEXT: and w12, w16, w17 136; GISEL-NEXT: and w13, w18, w0 137; GISEL-NEXT: and w9, w10, w11 138; GISEL-NEXT: and w14, w1, w2 139; GISEL-NEXT: and w10, w12, w13 140; GISEL-NEXT: and w8, w8, w9 141; GISEL-NEXT: and w15, w3, w4 142; GISEL-NEXT: and w11, w14, w15 143; GISEL-NEXT: and w9, w10, w11 144; GISEL-NEXT: and w8, w8, w9 145; GISEL-NEXT: and w0, w8, #0x1 146; GISEL-NEXT: ret 147 %or_result = call i1 @llvm.vector.reduce.and.v16i1(<16 x i1> %a) 148 ret i1 %or_result 149} 150 151define <16 x i1> @test_redand_ins_v16i1(<16 x i1> %a) { 152; CHECK-LABEL: test_redand_ins_v16i1: 153; CHECK: // %bb.0: 154; CHECK-NEXT: shl v0.16b, v0.16b, #7 155; CHECK-NEXT: cmlt v0.16b, v0.16b, #0 156; CHECK-NEXT: uminv b0, v0.16b 157; CHECK-NEXT: ret 158; 159; GISEL-LABEL: test_redand_ins_v16i1: 160; GISEL: // %bb.0: 161; GISEL-NEXT: umov w8, v0.b[0] 162; GISEL-NEXT: umov w9, v0.b[1] 163; GISEL-NEXT: umov w10, v0.b[2] 164; GISEL-NEXT: umov w11, v0.b[3] 165; GISEL-NEXT: umov w12, v0.b[4] 166; GISEL-NEXT: umov w13, v0.b[5] 167; GISEL-NEXT: umov w14, v0.b[6] 168; GISEL-NEXT: umov w15, v0.b[7] 169; GISEL-NEXT: umov w16, v0.b[8] 170; GISEL-NEXT: umov w17, v0.b[9] 171; GISEL-NEXT: umov w18, v0.b[10] 172; GISEL-NEXT: umov w0, v0.b[11] 173; GISEL-NEXT: and w8, w8, w9 174; GISEL-NEXT: umov w1, v0.b[12] 175; GISEL-NEXT: umov w2, v0.b[13] 176; GISEL-NEXT: and w9, w10, w11 177; GISEL-NEXT: and w10, w12, w13 178; GISEL-NEXT: umov w3, v0.b[14] 179; GISEL-NEXT: and w11, w14, w15 180; GISEL-NEXT: and w8, w8, w9 181; GISEL-NEXT: umov w4, v0.b[15] 182; GISEL-NEXT: and w12, w16, w17 183; GISEL-NEXT: and w13, w18, w0 184; GISEL-NEXT: and w9, w10, w11 185; GISEL-NEXT: and w14, w1, w2 186; GISEL-NEXT: and w10, w12, w13 187; GISEL-NEXT: and w8, w8, w9 188; GISEL-NEXT: and w15, w3, w4 189; GISEL-NEXT: and w11, w14, w15 190; GISEL-NEXT: and w9, w10, w11 191; GISEL-NEXT: and w8, w8, w9 192; GISEL-NEXT: fmov s0, w8 193; GISEL-NEXT: ret 194 %and_result = call i1 @llvm.vector.reduce.and.v16i1(<16 x i1> %a) 195 %ins = insertelement <16 x i1> poison, i1 %and_result, i64 0 196 ret <16 x i1> %ins 197} 198 199define i8 @test_redand_v1i8(<1 x i8> %a) { 200; CHECK-LABEL: test_redand_v1i8: 201; CHECK: // %bb.0: 202; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0 203; CHECK-NEXT: umov w0, v0.b[0] 204; CHECK-NEXT: ret 205; 206; GISEL-LABEL: test_redand_v1i8: 207; GISEL: // %bb.0: 208; GISEL-NEXT: // kill: def $d0 killed $d0 def $q0 209; GISEL-NEXT: umov w0, v0.b[0] 210; GISEL-NEXT: ret 211 %and_result = call i8 @llvm.vector.reduce.and.v1i8(<1 x i8> %a) 212 ret i8 %and_result 213} 214 215define i8 @test_redand_v3i8(<3 x i8> %a) { 216; CHECK-LABEL: test_redand_v3i8: 217; CHECK: // %bb.0: 218; CHECK-NEXT: movi d0, #0xff00ff00ff00ff 219; CHECK-NEXT: mov v0.h[0], w0 220; CHECK-NEXT: mov v0.h[1], w1 221; CHECK-NEXT: mov v0.h[2], w2 222; CHECK-NEXT: fmov x8, d0 223; CHECK-NEXT: and x8, x8, x8, lsr #32 224; CHECK-NEXT: lsr x9, x8, #16 225; CHECK-NEXT: and w0, w8, w9 226; CHECK-NEXT: ret 227; 228; GISEL-LABEL: test_redand_v3i8: 229; GISEL: // %bb.0: 230; GISEL-NEXT: and w8, w0, w1 231; GISEL-NEXT: and w0, w8, w2 232; GISEL-NEXT: ret 233 %and_result = call i8 @llvm.vector.reduce.and.v3i8(<3 x i8> %a) 234 ret i8 %and_result 235} 236 237define i8 @test_redand_v4i8(<4 x i8> %a) { 238; CHECK-LABEL: test_redand_v4i8: 239; CHECK: // %bb.0: 240; CHECK-NEXT: fmov x8, d0 241; CHECK-NEXT: and x8, x8, x8, lsr #32 242; CHECK-NEXT: lsr x9, x8, #16 243; CHECK-NEXT: and w0, w8, w9 244; CHECK-NEXT: ret 245; 246; GISEL-LABEL: test_redand_v4i8: 247; GISEL: // %bb.0: 248; GISEL-NEXT: // kill: def $d0 killed $d0 def $q0 249; GISEL-NEXT: umov w8, v0.h[0] 250; GISEL-NEXT: umov w9, v0.h[1] 251; GISEL-NEXT: umov w10, v0.h[2] 252; GISEL-NEXT: umov w11, v0.h[3] 253; GISEL-NEXT: and w8, w8, w9 254; GISEL-NEXT: and w9, w10, w11 255; GISEL-NEXT: and w0, w8, w9 256; GISEL-NEXT: ret 257 %and_result = call i8 @llvm.vector.reduce.and.v4i8(<4 x i8> %a) 258 ret i8 %and_result 259} 260 261define i8 @test_redand_v8i8(<8 x i8> %a) { 262; CHECK-LABEL: test_redand_v8i8: 263; CHECK: // %bb.0: 264; CHECK-NEXT: fmov x8, d0 265; CHECK-NEXT: and x8, x8, x8, lsr #32 266; CHECK-NEXT: and x8, x8, x8, lsr #16 267; CHECK-NEXT: lsr x9, x8, #8 268; CHECK-NEXT: and w0, w8, w9 269; CHECK-NEXT: ret 270; 271; GISEL-LABEL: test_redand_v8i8: 272; GISEL: // %bb.0: 273; GISEL-NEXT: // kill: def $d0 killed $d0 def $q0 274; GISEL-NEXT: umov w8, v0.b[0] 275; GISEL-NEXT: umov w9, v0.b[1] 276; GISEL-NEXT: umov w10, v0.b[2] 277; GISEL-NEXT: umov w11, v0.b[3] 278; GISEL-NEXT: umov w12, v0.b[4] 279; GISEL-NEXT: umov w13, v0.b[5] 280; GISEL-NEXT: umov w14, v0.b[6] 281; GISEL-NEXT: umov w15, v0.b[7] 282; GISEL-NEXT: and w8, w8, w9 283; GISEL-NEXT: and w9, w10, w11 284; GISEL-NEXT: and w10, w12, w13 285; GISEL-NEXT: and w11, w14, w15 286; GISEL-NEXT: and w8, w8, w9 287; GISEL-NEXT: and w9, w10, w11 288; GISEL-NEXT: and w0, w8, w9 289; GISEL-NEXT: ret 290 %and_result = call i8 @llvm.vector.reduce.and.v8i8(<8 x i8> %a) 291 ret i8 %and_result 292} 293 294define i8 @test_redand_v16i8(<16 x i8> %a) { 295; CHECK-LABEL: test_redand_v16i8: 296; CHECK: // %bb.0: 297; CHECK-NEXT: ext v1.16b, v0.16b, v0.16b, #8 298; CHECK-NEXT: and v0.8b, v0.8b, v1.8b 299; CHECK-NEXT: fmov x8, d0 300; CHECK-NEXT: and x8, x8, x8, lsr #32 301; CHECK-NEXT: and x8, x8, x8, lsr #16 302; CHECK-NEXT: lsr x9, x8, #8 303; CHECK-NEXT: and w0, w8, w9 304; CHECK-NEXT: ret 305; 306; GISEL-LABEL: test_redand_v16i8: 307; GISEL: // %bb.0: 308; GISEL-NEXT: mov d1, v0.d[1] 309; GISEL-NEXT: and v0.8b, v0.8b, v1.8b 310; GISEL-NEXT: umov w8, v0.b[0] 311; GISEL-NEXT: umov w9, v0.b[1] 312; GISEL-NEXT: umov w10, v0.b[2] 313; GISEL-NEXT: umov w11, v0.b[3] 314; GISEL-NEXT: umov w12, v0.b[4] 315; GISEL-NEXT: umov w13, v0.b[5] 316; GISEL-NEXT: umov w14, v0.b[6] 317; GISEL-NEXT: umov w15, v0.b[7] 318; GISEL-NEXT: and w8, w8, w9 319; GISEL-NEXT: and w9, w10, w11 320; GISEL-NEXT: and w10, w12, w13 321; GISEL-NEXT: and w11, w14, w15 322; GISEL-NEXT: and w8, w8, w9 323; GISEL-NEXT: and w9, w10, w11 324; GISEL-NEXT: and w0, w8, w9 325; GISEL-NEXT: ret 326 %and_result = call i8 @llvm.vector.reduce.and.v16i8(<16 x i8> %a) 327 ret i8 %and_result 328} 329 330define i8 @test_redand_v32i8(<32 x i8> %a) { 331; CHECK-LABEL: test_redand_v32i8: 332; CHECK: // %bb.0: 333; CHECK-NEXT: and v0.16b, v0.16b, v1.16b 334; CHECK-NEXT: ext v1.16b, v0.16b, v0.16b, #8 335; CHECK-NEXT: and v0.8b, v0.8b, v1.8b 336; CHECK-NEXT: fmov x8, d0 337; CHECK-NEXT: and x8, x8, x8, lsr #32 338; CHECK-NEXT: and x8, x8, x8, lsr #16 339; CHECK-NEXT: lsr x9, x8, #8 340; CHECK-NEXT: and w0, w8, w9 341; CHECK-NEXT: ret 342; 343; GISEL-LABEL: test_redand_v32i8: 344; GISEL: // %bb.0: 345; GISEL-NEXT: and v0.16b, v0.16b, v1.16b 346; GISEL-NEXT: mov d1, v0.d[1] 347; GISEL-NEXT: and v0.8b, v0.8b, v1.8b 348; GISEL-NEXT: umov w8, v0.b[0] 349; GISEL-NEXT: umov w9, v0.b[1] 350; GISEL-NEXT: umov w10, v0.b[2] 351; GISEL-NEXT: umov w11, v0.b[3] 352; GISEL-NEXT: umov w12, v0.b[4] 353; GISEL-NEXT: umov w13, v0.b[5] 354; GISEL-NEXT: umov w14, v0.b[6] 355; GISEL-NEXT: umov w15, v0.b[7] 356; GISEL-NEXT: and w8, w8, w9 357; GISEL-NEXT: and w9, w10, w11 358; GISEL-NEXT: and w10, w12, w13 359; GISEL-NEXT: and w11, w14, w15 360; GISEL-NEXT: and w8, w8, w9 361; GISEL-NEXT: and w9, w10, w11 362; GISEL-NEXT: and w0, w8, w9 363; GISEL-NEXT: ret 364 %and_result = call i8 @llvm.vector.reduce.and.v32i8(<32 x i8> %a) 365 ret i8 %and_result 366} 367 368define i16 @test_redand_v4i16(<4 x i16> %a) { 369; CHECK-LABEL: test_redand_v4i16: 370; CHECK: // %bb.0: 371; CHECK-NEXT: fmov x8, d0 372; CHECK-NEXT: and x8, x8, x8, lsr #32 373; CHECK-NEXT: lsr x9, x8, #16 374; CHECK-NEXT: and w0, w8, w9 375; CHECK-NEXT: ret 376; 377; GISEL-LABEL: test_redand_v4i16: 378; GISEL: // %bb.0: 379; GISEL-NEXT: // kill: def $d0 killed $d0 def $q0 380; GISEL-NEXT: umov w8, v0.h[0] 381; GISEL-NEXT: umov w9, v0.h[1] 382; GISEL-NEXT: umov w10, v0.h[2] 383; GISEL-NEXT: umov w11, v0.h[3] 384; GISEL-NEXT: and w8, w8, w9 385; GISEL-NEXT: and w9, w10, w11 386; GISEL-NEXT: and w0, w8, w9 387; GISEL-NEXT: ret 388 %and_result = call i16 @llvm.vector.reduce.and.v4i16(<4 x i16> %a) 389 ret i16 %and_result 390} 391 392define i16 @test_redand_v8i16(<8 x i16> %a) { 393; CHECK-LABEL: test_redand_v8i16: 394; CHECK: // %bb.0: 395; CHECK-NEXT: ext v1.16b, v0.16b, v0.16b, #8 396; CHECK-NEXT: and v0.8b, v0.8b, v1.8b 397; CHECK-NEXT: fmov x8, d0 398; CHECK-NEXT: and x8, x8, x8, lsr #32 399; CHECK-NEXT: lsr x9, x8, #16 400; CHECK-NEXT: and w0, w8, w9 401; CHECK-NEXT: ret 402; 403; GISEL-LABEL: test_redand_v8i16: 404; GISEL: // %bb.0: 405; GISEL-NEXT: mov d1, v0.d[1] 406; GISEL-NEXT: and v0.8b, v0.8b, v1.8b 407; GISEL-NEXT: umov w8, v0.h[0] 408; GISEL-NEXT: umov w9, v0.h[1] 409; GISEL-NEXT: umov w10, v0.h[2] 410; GISEL-NEXT: umov w11, v0.h[3] 411; GISEL-NEXT: and w8, w8, w9 412; GISEL-NEXT: and w9, w10, w11 413; GISEL-NEXT: and w0, w8, w9 414; GISEL-NEXT: ret 415 %and_result = call i16 @llvm.vector.reduce.and.v8i16(<8 x i16> %a) 416 ret i16 %and_result 417} 418 419define i16 @test_redand_v16i16(<16 x i16> %a) { 420; CHECK-LABEL: test_redand_v16i16: 421; CHECK: // %bb.0: 422; CHECK-NEXT: and v0.16b, v0.16b, v1.16b 423; CHECK-NEXT: ext v1.16b, v0.16b, v0.16b, #8 424; CHECK-NEXT: and v0.8b, v0.8b, v1.8b 425; CHECK-NEXT: fmov x8, d0 426; CHECK-NEXT: and x8, x8, x8, lsr #32 427; CHECK-NEXT: lsr x9, x8, #16 428; CHECK-NEXT: and w0, w8, w9 429; CHECK-NEXT: ret 430; 431; GISEL-LABEL: test_redand_v16i16: 432; GISEL: // %bb.0: 433; GISEL-NEXT: and v0.16b, v0.16b, v1.16b 434; GISEL-NEXT: mov d1, v0.d[1] 435; GISEL-NEXT: and v0.8b, v0.8b, v1.8b 436; GISEL-NEXT: umov w8, v0.h[0] 437; GISEL-NEXT: umov w9, v0.h[1] 438; GISEL-NEXT: umov w10, v0.h[2] 439; GISEL-NEXT: umov w11, v0.h[3] 440; GISEL-NEXT: and w8, w8, w9 441; GISEL-NEXT: and w9, w10, w11 442; GISEL-NEXT: and w0, w8, w9 443; GISEL-NEXT: ret 444 %and_result = call i16 @llvm.vector.reduce.and.v16i16(<16 x i16> %a) 445 ret i16 %and_result 446} 447 448define i32 @test_redand_v2i32(<2 x i32> %a) { 449; CHECK-LABEL: test_redand_v2i32: 450; CHECK: // %bb.0: 451; CHECK-NEXT: fmov x8, d0 452; CHECK-NEXT: lsr x9, x8, #32 453; CHECK-NEXT: and w0, w8, w9 454; CHECK-NEXT: ret 455; 456; GISEL-LABEL: test_redand_v2i32: 457; GISEL: // %bb.0: 458; GISEL-NEXT: // kill: def $d0 killed $d0 def $q0 459; GISEL-NEXT: mov w8, v0.s[1] 460; GISEL-NEXT: fmov w9, s0 461; GISEL-NEXT: and w0, w9, w8 462; GISEL-NEXT: ret 463 %and_result = call i32 @llvm.vector.reduce.and.v2i32(<2 x i32> %a) 464 ret i32 %and_result 465} 466 467define i32 @test_redand_v4i32(<4 x i32> %a) { 468; CHECK-LABEL: test_redand_v4i32: 469; CHECK: // %bb.0: 470; CHECK-NEXT: ext v1.16b, v0.16b, v0.16b, #8 471; CHECK-NEXT: and v0.8b, v0.8b, v1.8b 472; CHECK-NEXT: fmov x8, d0 473; CHECK-NEXT: lsr x9, x8, #32 474; CHECK-NEXT: and w0, w8, w9 475; CHECK-NEXT: ret 476; 477; GISEL-LABEL: test_redand_v4i32: 478; GISEL: // %bb.0: 479; GISEL-NEXT: mov d1, v0.d[1] 480; GISEL-NEXT: and v0.8b, v0.8b, v1.8b 481; GISEL-NEXT: mov w8, v0.s[1] 482; GISEL-NEXT: fmov w9, s0 483; GISEL-NEXT: and w0, w9, w8 484; GISEL-NEXT: ret 485 %and_result = call i32 @llvm.vector.reduce.and.v4i32(<4 x i32> %a) 486 ret i32 %and_result 487} 488 489define i32 @test_redand_v8i32(<8 x i32> %a) { 490; CHECK-LABEL: test_redand_v8i32: 491; CHECK: // %bb.0: 492; CHECK-NEXT: and v0.16b, v0.16b, v1.16b 493; CHECK-NEXT: ext v1.16b, v0.16b, v0.16b, #8 494; CHECK-NEXT: and v0.8b, v0.8b, v1.8b 495; CHECK-NEXT: fmov x8, d0 496; CHECK-NEXT: lsr x9, x8, #32 497; CHECK-NEXT: and w0, w8, w9 498; CHECK-NEXT: ret 499; 500; GISEL-LABEL: test_redand_v8i32: 501; GISEL: // %bb.0: 502; GISEL-NEXT: and v0.16b, v0.16b, v1.16b 503; GISEL-NEXT: mov d1, v0.d[1] 504; GISEL-NEXT: and v0.8b, v0.8b, v1.8b 505; GISEL-NEXT: mov w8, v0.s[1] 506; GISEL-NEXT: fmov w9, s0 507; GISEL-NEXT: and w0, w9, w8 508; GISEL-NEXT: ret 509 %and_result = call i32 @llvm.vector.reduce.and.v8i32(<8 x i32> %a) 510 ret i32 %and_result 511} 512 513define i64 @test_redand_v2i64(<2 x i64> %a) { 514; CHECK-LABEL: test_redand_v2i64: 515; CHECK: // %bb.0: 516; CHECK-NEXT: ext v1.16b, v0.16b, v0.16b, #8 517; CHECK-NEXT: and v0.8b, v0.8b, v1.8b 518; CHECK-NEXT: fmov x0, d0 519; CHECK-NEXT: ret 520; 521; GISEL-LABEL: test_redand_v2i64: 522; GISEL: // %bb.0: 523; GISEL-NEXT: mov x8, v0.d[1] 524; GISEL-NEXT: fmov x9, d0 525; GISEL-NEXT: and x0, x9, x8 526; GISEL-NEXT: ret 527 %and_result = call i64 @llvm.vector.reduce.and.v2i64(<2 x i64> %a) 528 ret i64 %and_result 529} 530 531define i64 @test_redand_v4i64(<4 x i64> %a) { 532; CHECK-LABEL: test_redand_v4i64: 533; CHECK: // %bb.0: 534; CHECK-NEXT: and v0.16b, v0.16b, v1.16b 535; CHECK-NEXT: ext v1.16b, v0.16b, v0.16b, #8 536; CHECK-NEXT: and v0.8b, v0.8b, v1.8b 537; CHECK-NEXT: fmov x0, d0 538; CHECK-NEXT: ret 539; 540; GISEL-LABEL: test_redand_v4i64: 541; GISEL: // %bb.0: 542; GISEL-NEXT: and v0.16b, v0.16b, v1.16b 543; GISEL-NEXT: mov x8, v0.d[1] 544; GISEL-NEXT: fmov x9, d0 545; GISEL-NEXT: and x0, x9, x8 546; GISEL-NEXT: ret 547 %and_result = call i64 @llvm.vector.reduce.and.v4i64(<4 x i64> %a) 548 ret i64 %and_result 549} 550 551declare i1 @llvm.vector.reduce.and.v1i1(<1 x i1>) 552declare i1 @llvm.vector.reduce.and.v2i1(<2 x i1>) 553declare i1 @llvm.vector.reduce.and.v4i1(<4 x i1>) 554declare i1 @llvm.vector.reduce.and.v8i1(<8 x i1>) 555declare i1 @llvm.vector.reduce.and.v16i1(<16 x i1>) 556declare i64 @llvm.vector.reduce.and.v2i64(<2 x i64>) 557declare i64 @llvm.vector.reduce.and.v4i64(<4 x i64>) 558declare i32 @llvm.vector.reduce.and.v2i32(<2 x i32>) 559declare i32 @llvm.vector.reduce.and.v4i32(<4 x i32>) 560declare i32 @llvm.vector.reduce.and.v8i32(<8 x i32>) 561declare i16 @llvm.vector.reduce.and.v4i16(<4 x i16>) 562declare i16 @llvm.vector.reduce.and.v8i16(<8 x i16>) 563declare i16 @llvm.vector.reduce.and.v16i16(<16 x i16>) 564declare i8 @llvm.vector.reduce.and.v1i8(<1 x i8>) 565declare i8 @llvm.vector.reduce.and.v3i8(<3 x i8>) 566declare i8 @llvm.vector.reduce.and.v4i8(<4 x i8>) 567declare i8 @llvm.vector.reduce.and.v8i8(<8 x i8>) 568declare i8 @llvm.vector.reduce.and.v16i8(<16 x i8>) 569declare i8 @llvm.vector.reduce.and.v32i8(<32 x i8>) 570