1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mattr=+sve -force-streaming-compatible < %s | FileCheck %s 3; RUN: llc -mattr=+sme -force-streaming < %s | FileCheck %s 4; RUN: llc -force-streaming-compatible < %s | FileCheck %s --check-prefix=NONEON-NOSVE 5 6target triple = "aarch64-unknown-linux-gnu" 7 8define <2 x half> @select_v2f16(<2 x half> %op1, <2 x half> %op2, <2 x i1> %mask) { 9; CHECK-LABEL: select_v2f16: 10; CHECK: // %bb.0: 11; CHECK-NEXT: // kill: def $d2 killed $d2 def $z2 12; CHECK-NEXT: mov z3.s, z2.s[1] 13; CHECK-NEXT: ptrue p0.h 14; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 15; CHECK-NEXT: // kill: def $d1 killed $d1 def $z1 16; CHECK-NEXT: zip1 z2.h, z2.h, z3.h 17; CHECK-NEXT: lsl z2.h, z2.h, #15 18; CHECK-NEXT: asr z2.h, z2.h, #15 19; CHECK-NEXT: and z2.h, z2.h, #0x1 20; CHECK-NEXT: cmpne p0.h, p0/z, z2.h, #0 21; CHECK-NEXT: sel z0.h, p0, z0.h, z1.h 22; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0 23; CHECK-NEXT: ret 24; 25; NONEON-NOSVE-LABEL: select_v2f16: 26; NONEON-NOSVE: // %bb.0: 27; NONEON-NOSVE-NEXT: sub sp, sp, #32 28; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 32 29; NONEON-NOSVE-NEXT: stp d1, d2, [sp, #8] 30; NONEON-NOSVE-NEXT: ldp w8, w9, [sp, #16] 31; NONEON-NOSVE-NEXT: str d0, [sp] 32; NONEON-NOSVE-NEXT: ldr h0, [sp, #10] 33; NONEON-NOSVE-NEXT: ldr w10, [sp, #12] 34; NONEON-NOSVE-NEXT: ldr h1, [sp, #2] 35; NONEON-NOSVE-NEXT: sbfx w9, w9, #0, #1 36; NONEON-NOSVE-NEXT: sbfx w8, w8, #0, #1 37; NONEON-NOSVE-NEXT: str w10, [sp, #28] 38; NONEON-NOSVE-NEXT: tst w9, #0xffff 39; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, ne 40; NONEON-NOSVE-NEXT: ldr h1, [sp] 41; NONEON-NOSVE-NEXT: tst w8, #0xffff 42; NONEON-NOSVE-NEXT: str h0, [sp, #26] 43; NONEON-NOSVE-NEXT: ldr h0, [sp, #8] 44; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, ne 45; NONEON-NOSVE-NEXT: str h0, [sp, #24] 46; NONEON-NOSVE-NEXT: ldr d0, [sp, #24] 47; NONEON-NOSVE-NEXT: add sp, sp, #32 48; NONEON-NOSVE-NEXT: ret 49 %sel = select <2 x i1> %mask, <2 x half> %op1, <2 x half> %op2 50 ret <2 x half> %sel 51} 52 53define <4 x half> @select_v4f16(<4 x half> %op1, <4 x half> %op2, <4 x i1> %mask) { 54; CHECK-LABEL: select_v4f16: 55; CHECK: // %bb.0: 56; CHECK-NEXT: // kill: def $d2 killed $d2 def $z2 57; CHECK-NEXT: ptrue p0.h 58; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 59; CHECK-NEXT: // kill: def $d1 killed $d1 def $z1 60; CHECK-NEXT: lsl z2.h, z2.h, #15 61; CHECK-NEXT: asr z2.h, z2.h, #15 62; CHECK-NEXT: and z2.h, z2.h, #0x1 63; CHECK-NEXT: cmpne p0.h, p0/z, z2.h, #0 64; CHECK-NEXT: sel z0.h, p0, z0.h, z1.h 65; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0 66; CHECK-NEXT: ret 67; 68; NONEON-NOSVE-LABEL: select_v4f16: 69; NONEON-NOSVE: // %bb.0: 70; NONEON-NOSVE-NEXT: sub sp, sp, #32 71; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 32 72; NONEON-NOSVE-NEXT: stp d1, d2, [sp, #8] 73; NONEON-NOSVE-NEXT: ldrh w9, [sp, #22] 74; NONEON-NOSVE-NEXT: str d0, [sp] 75; NONEON-NOSVE-NEXT: ldr h0, [sp, #14] 76; NONEON-NOSVE-NEXT: ldr h1, [sp, #6] 77; NONEON-NOSVE-NEXT: ldrh w11, [sp, #20] 78; NONEON-NOSVE-NEXT: ldrh w10, [sp, #18] 79; NONEON-NOSVE-NEXT: sbfx w9, w9, #0, #1 80; NONEON-NOSVE-NEXT: ldrh w8, [sp, #16] 81; NONEON-NOSVE-NEXT: tst w9, #0xffff 82; NONEON-NOSVE-NEXT: sbfx w9, w11, #0, #1 83; NONEON-NOSVE-NEXT: sbfx w8, w8, #0, #1 84; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, ne 85; NONEON-NOSVE-NEXT: ldr h1, [sp, #4] 86; NONEON-NOSVE-NEXT: tst w9, #0xffff 87; NONEON-NOSVE-NEXT: sbfx w9, w10, #0, #1 88; NONEON-NOSVE-NEXT: str h0, [sp, #30] 89; NONEON-NOSVE-NEXT: ldr h0, [sp, #12] 90; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, ne 91; NONEON-NOSVE-NEXT: ldr h1, [sp, #2] 92; NONEON-NOSVE-NEXT: tst w9, #0xffff 93; NONEON-NOSVE-NEXT: str h0, [sp, #28] 94; NONEON-NOSVE-NEXT: ldr h0, [sp, #10] 95; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, ne 96; NONEON-NOSVE-NEXT: ldr h1, [sp] 97; NONEON-NOSVE-NEXT: tst w8, #0xffff 98; NONEON-NOSVE-NEXT: str h0, [sp, #26] 99; NONEON-NOSVE-NEXT: ldr h0, [sp, #8] 100; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, ne 101; NONEON-NOSVE-NEXT: str h0, [sp, #24] 102; NONEON-NOSVE-NEXT: ldr d0, [sp, #24] 103; NONEON-NOSVE-NEXT: add sp, sp, #32 104; NONEON-NOSVE-NEXT: ret 105 %sel = select <4 x i1> %mask, <4 x half> %op1, <4 x half> %op2 106 ret <4 x half> %sel 107} 108 109define <8 x half> @select_v8f16(<8 x half> %op1, <8 x half> %op2, <8 x i1> %mask) { 110; CHECK-LABEL: select_v8f16: 111; CHECK: // %bb.0: 112; CHECK-NEXT: // kill: def $d2 killed $d2 def $z2 113; CHECK-NEXT: ptrue p0.h 114; CHECK-NEXT: // kill: def $q0 killed $q0 def $z0 115; CHECK-NEXT: // kill: def $q1 killed $q1 def $z1 116; CHECK-NEXT: uunpklo z2.h, z2.b 117; CHECK-NEXT: lsl z2.h, z2.h, #15 118; CHECK-NEXT: asr z2.h, z2.h, #15 119; CHECK-NEXT: and z2.h, z2.h, #0x1 120; CHECK-NEXT: cmpne p0.h, p0/z, z2.h, #0 121; CHECK-NEXT: sel z0.h, p0, z0.h, z1.h 122; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0 123; CHECK-NEXT: ret 124; 125; NONEON-NOSVE-LABEL: select_v8f16: 126; NONEON-NOSVE: // %bb.0: 127; NONEON-NOSVE-NEXT: sub sp, sp, #64 128; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 64 129; NONEON-NOSVE-NEXT: str d2, [sp, #40] 130; NONEON-NOSVE-NEXT: ldrb w13, [sp, #47] 131; NONEON-NOSVE-NEXT: stp q0, q1, [sp] 132; NONEON-NOSVE-NEXT: ldrb w15, [sp, #46] 133; NONEON-NOSVE-NEXT: ldr h0, [sp, #30] 134; NONEON-NOSVE-NEXT: ldr h1, [sp, #14] 135; NONEON-NOSVE-NEXT: ldrb w14, [sp, #45] 136; NONEON-NOSVE-NEXT: sbfx w13, w13, #0, #1 137; NONEON-NOSVE-NEXT: ldrb w12, [sp, #44] 138; NONEON-NOSVE-NEXT: ldrb w11, [sp, #43] 139; NONEON-NOSVE-NEXT: ldrb w10, [sp, #42] 140; NONEON-NOSVE-NEXT: ldrb w9, [sp, #41] 141; NONEON-NOSVE-NEXT: ldrb w8, [sp, #40] 142; NONEON-NOSVE-NEXT: tst w13, #0xffff 143; NONEON-NOSVE-NEXT: sbfx w13, w15, #0, #1 144; NONEON-NOSVE-NEXT: sbfx w12, w12, #0, #1 145; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, ne 146; NONEON-NOSVE-NEXT: ldr h1, [sp, #12] 147; NONEON-NOSVE-NEXT: sbfx w11, w11, #0, #1 148; NONEON-NOSVE-NEXT: tst w13, #0xffff 149; NONEON-NOSVE-NEXT: sbfx w13, w14, #0, #1 150; NONEON-NOSVE-NEXT: sbfx w10, w10, #0, #1 151; NONEON-NOSVE-NEXT: sbfx w9, w9, #0, #1 152; NONEON-NOSVE-NEXT: sbfx w8, w8, #0, #1 153; NONEON-NOSVE-NEXT: str h0, [sp, #62] 154; NONEON-NOSVE-NEXT: ldr h0, [sp, #28] 155; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, ne 156; NONEON-NOSVE-NEXT: ldr h1, [sp, #10] 157; NONEON-NOSVE-NEXT: tst w13, #0xffff 158; NONEON-NOSVE-NEXT: str h0, [sp, #60] 159; NONEON-NOSVE-NEXT: ldr h0, [sp, #26] 160; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, ne 161; NONEON-NOSVE-NEXT: ldr h1, [sp, #8] 162; NONEON-NOSVE-NEXT: tst w12, #0xffff 163; NONEON-NOSVE-NEXT: str h0, [sp, #58] 164; NONEON-NOSVE-NEXT: ldr h0, [sp, #24] 165; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, ne 166; NONEON-NOSVE-NEXT: ldr h1, [sp, #6] 167; NONEON-NOSVE-NEXT: tst w11, #0xffff 168; NONEON-NOSVE-NEXT: str h0, [sp, #56] 169; NONEON-NOSVE-NEXT: ldr h0, [sp, #22] 170; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, ne 171; NONEON-NOSVE-NEXT: ldr h1, [sp, #4] 172; NONEON-NOSVE-NEXT: tst w10, #0xffff 173; NONEON-NOSVE-NEXT: str h0, [sp, #54] 174; NONEON-NOSVE-NEXT: ldr h0, [sp, #20] 175; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, ne 176; NONEON-NOSVE-NEXT: ldr h1, [sp, #2] 177; NONEON-NOSVE-NEXT: tst w9, #0xffff 178; NONEON-NOSVE-NEXT: str h0, [sp, #52] 179; NONEON-NOSVE-NEXT: ldr h0, [sp, #18] 180; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, ne 181; NONEON-NOSVE-NEXT: ldr h1, [sp] 182; NONEON-NOSVE-NEXT: tst w8, #0xffff 183; NONEON-NOSVE-NEXT: str h0, [sp, #50] 184; NONEON-NOSVE-NEXT: ldr h0, [sp, #16] 185; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, ne 186; NONEON-NOSVE-NEXT: str h0, [sp, #48] 187; NONEON-NOSVE-NEXT: ldr q0, [sp, #48] 188; NONEON-NOSVE-NEXT: add sp, sp, #64 189; NONEON-NOSVE-NEXT: ret 190 %sel = select <8 x i1> %mask, <8 x half> %op1, <8 x half> %op2 191 ret <8 x half> %sel 192} 193 194define void @select_v16f16(ptr %a, ptr %b) { 195; CHECK-LABEL: select_v16f16: 196; CHECK: // %bb.0: 197; CHECK-NEXT: ldp q0, q2, [x0] 198; CHECK-NEXT: ptrue p0.h, vl8 199; CHECK-NEXT: ldp q1, q3, [x1] 200; CHECK-NEXT: fcmeq p1.h, p0/z, z0.h, z1.h 201; CHECK-NEXT: fcmeq p0.h, p0/z, z2.h, z3.h 202; CHECK-NEXT: sel z0.h, p1, z0.h, z1.h 203; CHECK-NEXT: sel z1.h, p0, z2.h, z3.h 204; CHECK-NEXT: stp q0, q1, [x0] 205; CHECK-NEXT: ret 206; 207; NONEON-NOSVE-LABEL: select_v16f16: 208; NONEON-NOSVE: // %bb.0: 209; NONEON-NOSVE-NEXT: ldp q0, q3, [x1] 210; NONEON-NOSVE-NEXT: ldp q1, q2, [x0] 211; NONEON-NOSVE-NEXT: stp q1, q0, [sp, #-96]! 212; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 96 213; NONEON-NOSVE-NEXT: ldr h0, [sp, #18] 214; NONEON-NOSVE-NEXT: ldr h1, [sp, #2] 215; NONEON-NOSVE-NEXT: stp q2, q3, [sp, #32] 216; NONEON-NOSVE-NEXT: ldr h4, [sp, #20] 217; NONEON-NOSVE-NEXT: ldr h5, [sp, #4] 218; NONEON-NOSVE-NEXT: ldr h16, [sp, #22] 219; NONEON-NOSVE-NEXT: fcvt s2, h0 220; NONEON-NOSVE-NEXT: fcvt s3, h1 221; NONEON-NOSVE-NEXT: ldr h17, [sp, #6] 222; NONEON-NOSVE-NEXT: fcvt s6, h4 223; NONEON-NOSVE-NEXT: fcvt s7, h5 224; NONEON-NOSVE-NEXT: ldr h19, [sp, #8] 225; NONEON-NOSVE-NEXT: fcvt s18, h17 226; NONEON-NOSVE-NEXT: ldr h21, [sp, #10] 227; NONEON-NOSVE-NEXT: ldr h22, [sp, #12] 228; NONEON-NOSVE-NEXT: fcvt s20, h19 229; NONEON-NOSVE-NEXT: ldr h24, [sp, #32] 230; NONEON-NOSVE-NEXT: ldr h25, [sp, #34] 231; NONEON-NOSVE-NEXT: fcmp s3, s2 232; NONEON-NOSVE-NEXT: fcvt s2, h16 233; NONEON-NOSVE-NEXT: ldr h3, [sp, #24] 234; NONEON-NOSVE-NEXT: ldr h26, [sp, #36] 235; NONEON-NOSVE-NEXT: ldr h27, [sp, #38] 236; NONEON-NOSVE-NEXT: ldr h28, [sp, #42] 237; NONEON-NOSVE-NEXT: ldr h29, [sp, #44] 238; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, eq 239; NONEON-NOSVE-NEXT: fcmp s7, s6 240; NONEON-NOSVE-NEXT: fcvt s7, h3 241; NONEON-NOSVE-NEXT: ldr h6, [sp, #26] 242; NONEON-NOSVE-NEXT: fcsel s1, s5, s4, eq 243; NONEON-NOSVE-NEXT: fcmp s18, s2 244; NONEON-NOSVE-NEXT: fcvt s4, h6 245; NONEON-NOSVE-NEXT: fcvt s18, h21 246; NONEON-NOSVE-NEXT: ldr h5, [sp, #28] 247; NONEON-NOSVE-NEXT: str h0, [sp, #66] 248; NONEON-NOSVE-NEXT: fcsel s2, s17, s16, eq 249; NONEON-NOSVE-NEXT: fcmp s20, s7 250; NONEON-NOSVE-NEXT: fcvt s16, h5 251; NONEON-NOSVE-NEXT: fcvt s17, h22 252; NONEON-NOSVE-NEXT: ldr h7, [sp, #30] 253; NONEON-NOSVE-NEXT: ldr h20, [sp, #14] 254; NONEON-NOSVE-NEXT: str h1, [sp, #68] 255; NONEON-NOSVE-NEXT: fcsel s3, s19, s3, eq 256; NONEON-NOSVE-NEXT: fcmp s18, s4 257; NONEON-NOSVE-NEXT: fcvt s19, h7 258; NONEON-NOSVE-NEXT: fcvt s23, h20 259; NONEON-NOSVE-NEXT: ldr h18, [sp, #48] 260; NONEON-NOSVE-NEXT: str h2, [sp, #70] 261; NONEON-NOSVE-NEXT: fcsel s4, s21, s6, eq 262; NONEON-NOSVE-NEXT: fcmp s17, s16 263; NONEON-NOSVE-NEXT: fcvt s17, h18 264; NONEON-NOSVE-NEXT: fcvt s21, h24 265; NONEON-NOSVE-NEXT: ldr h16, [sp, #50] 266; NONEON-NOSVE-NEXT: str h3, [sp, #72] 267; NONEON-NOSVE-NEXT: fcsel s5, s22, s5, eq 268; NONEON-NOSVE-NEXT: fcmp s23, s19 269; NONEON-NOSVE-NEXT: fcvt s22, h16 270; NONEON-NOSVE-NEXT: fcvt s23, h25 271; NONEON-NOSVE-NEXT: ldr h19, [sp, #52] 272; NONEON-NOSVE-NEXT: str h4, [sp, #74] 273; NONEON-NOSVE-NEXT: fcsel s6, s20, s7, eq 274; NONEON-NOSVE-NEXT: fcmp s21, s17 275; NONEON-NOSVE-NEXT: fcvt s20, h19 276; NONEON-NOSVE-NEXT: fcvt s21, h26 277; NONEON-NOSVE-NEXT: ldr h17, [sp, #54] 278; NONEON-NOSVE-NEXT: str h5, [sp, #76] 279; NONEON-NOSVE-NEXT: fcsel s7, s24, s18, eq 280; NONEON-NOSVE-NEXT: fcmp s23, s22 281; NONEON-NOSVE-NEXT: fcvt s22, h17 282; NONEON-NOSVE-NEXT: fcvt s23, h27 283; NONEON-NOSVE-NEXT: ldr h18, [sp, #56] 284; NONEON-NOSVE-NEXT: ldr h24, [sp, #40] 285; NONEON-NOSVE-NEXT: str h6, [sp, #78] 286; NONEON-NOSVE-NEXT: fcsel s16, s25, s16, eq 287; NONEON-NOSVE-NEXT: fcmp s21, s20 288; NONEON-NOSVE-NEXT: fcvt s21, h18 289; NONEON-NOSVE-NEXT: fcvt s25, h24 290; NONEON-NOSVE-NEXT: ldr h20, [sp, #58] 291; NONEON-NOSVE-NEXT: str h7, [sp, #80] 292; NONEON-NOSVE-NEXT: fcsel s19, s26, s19, eq 293; NONEON-NOSVE-NEXT: fcmp s23, s22 294; NONEON-NOSVE-NEXT: fcvt s23, h20 295; NONEON-NOSVE-NEXT: fcvt s26, h28 296; NONEON-NOSVE-NEXT: ldr h22, [sp, #60] 297; NONEON-NOSVE-NEXT: str h16, [sp, #82] 298; NONEON-NOSVE-NEXT: fcsel s17, s27, s17, eq 299; NONEON-NOSVE-NEXT: fcmp s25, s21 300; NONEON-NOSVE-NEXT: fcvt s25, h22 301; NONEON-NOSVE-NEXT: fcvt s27, h29 302; NONEON-NOSVE-NEXT: ldr h21, [sp, #62] 303; NONEON-NOSVE-NEXT: str h19, [sp, #84] 304; NONEON-NOSVE-NEXT: fcsel s18, s24, s18, eq 305; NONEON-NOSVE-NEXT: ldr h24, [sp, #46] 306; NONEON-NOSVE-NEXT: fcmp s26, s23 307; NONEON-NOSVE-NEXT: fcvt s23, h21 308; NONEON-NOSVE-NEXT: str h17, [sp, #86] 309; NONEON-NOSVE-NEXT: fcvt s26, h24 310; NONEON-NOSVE-NEXT: fcsel s20, s28, s20, eq 311; NONEON-NOSVE-NEXT: fcmp s27, s25 312; NONEON-NOSVE-NEXT: ldr h25, [sp, #16] 313; NONEON-NOSVE-NEXT: ldr h27, [sp] 314; NONEON-NOSVE-NEXT: str h18, [sp, #88] 315; NONEON-NOSVE-NEXT: fcvt s17, h25 316; NONEON-NOSVE-NEXT: fcvt s18, h27 317; NONEON-NOSVE-NEXT: fcsel s7, s29, s22, eq 318; NONEON-NOSVE-NEXT: fcmp s26, s23 319; NONEON-NOSVE-NEXT: str h20, [sp, #90] 320; NONEON-NOSVE-NEXT: fcsel s16, s24, s21, eq 321; NONEON-NOSVE-NEXT: str h7, [sp, #92] 322; NONEON-NOSVE-NEXT: fcmp s18, s17 323; NONEON-NOSVE-NEXT: str h16, [sp, #94] 324; NONEON-NOSVE-NEXT: fcsel s2, s27, s25, eq 325; NONEON-NOSVE-NEXT: str h2, [sp, #64] 326; NONEON-NOSVE-NEXT: ldp q0, q1, [sp, #64] 327; NONEON-NOSVE-NEXT: stp q0, q1, [x0] 328; NONEON-NOSVE-NEXT: add sp, sp, #96 329; NONEON-NOSVE-NEXT: ret 330 %op1 = load <16 x half>, ptr %a 331 %op2 = load <16 x half>, ptr %b 332 %mask = fcmp oeq <16 x half> %op1, %op2 333 %sel = select <16 x i1> %mask, <16 x half> %op1, <16 x half> %op2 334 store <16 x half> %sel, ptr %a 335 ret void 336} 337 338define <2 x float> @select_v2f32(<2 x float> %op1, <2 x float> %op2, <2 x i1> %mask) { 339; CHECK-LABEL: select_v2f32: 340; CHECK: // %bb.0: 341; CHECK-NEXT: // kill: def $d2 killed $d2 def $z2 342; CHECK-NEXT: ptrue p0.s 343; CHECK-NEXT: // kill: def $d0 killed $d0 def $z0 344; CHECK-NEXT: // kill: def $d1 killed $d1 def $z1 345; CHECK-NEXT: lsl z2.s, z2.s, #31 346; CHECK-NEXT: asr z2.s, z2.s, #31 347; CHECK-NEXT: and z2.s, z2.s, #0x1 348; CHECK-NEXT: cmpne p0.s, p0/z, z2.s, #0 349; CHECK-NEXT: sel z0.s, p0, z0.s, z1.s 350; CHECK-NEXT: // kill: def $d0 killed $d0 killed $z0 351; CHECK-NEXT: ret 352; 353; NONEON-NOSVE-LABEL: select_v2f32: 354; NONEON-NOSVE: // %bb.0: 355; NONEON-NOSVE-NEXT: stp d2, d0, [sp, #-32]! 356; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 32 357; NONEON-NOSVE-NEXT: ldp w9, w8, [sp] 358; NONEON-NOSVE-NEXT: str d1, [sp, #16] 359; NONEON-NOSVE-NEXT: ldp s1, s2, [sp, #8] 360; NONEON-NOSVE-NEXT: ldr s0, [sp, #20] 361; NONEON-NOSVE-NEXT: sbfx w8, w8, #0, #1 362; NONEON-NOSVE-NEXT: cmp w8, #0 363; NONEON-NOSVE-NEXT: sbfx w8, w9, #0, #1 364; NONEON-NOSVE-NEXT: fcsel s3, s2, s0, ne 365; NONEON-NOSVE-NEXT: ldr s0, [sp, #16] 366; NONEON-NOSVE-NEXT: cmp w8, #0 367; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, ne 368; NONEON-NOSVE-NEXT: stp s0, s3, [sp, #24] 369; NONEON-NOSVE-NEXT: ldr d0, [sp, #24] 370; NONEON-NOSVE-NEXT: add sp, sp, #32 371; NONEON-NOSVE-NEXT: ret 372 %sel = select <2 x i1> %mask, <2 x float> %op1, <2 x float> %op2 373 ret <2 x float> %sel 374} 375 376define <4 x float> @select_v4f32(<4 x float> %op1, <4 x float> %op2, <4 x i1> %mask) { 377; CHECK-LABEL: select_v4f32: 378; CHECK: // %bb.0: 379; CHECK-NEXT: // kill: def $d2 killed $d2 def $z2 380; CHECK-NEXT: ptrue p0.s 381; CHECK-NEXT: // kill: def $q0 killed $q0 def $z0 382; CHECK-NEXT: // kill: def $q1 killed $q1 def $z1 383; CHECK-NEXT: uunpklo z2.s, z2.h 384; CHECK-NEXT: lsl z2.s, z2.s, #31 385; CHECK-NEXT: asr z2.s, z2.s, #31 386; CHECK-NEXT: and z2.s, z2.s, #0x1 387; CHECK-NEXT: cmpne p0.s, p0/z, z2.s, #0 388; CHECK-NEXT: sel z0.s, p0, z0.s, z1.s 389; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0 390; CHECK-NEXT: ret 391; 392; NONEON-NOSVE-LABEL: select_v4f32: 393; NONEON-NOSVE: // %bb.0: 394; NONEON-NOSVE-NEXT: sub sp, sp, #64 395; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 64 396; NONEON-NOSVE-NEXT: str d2, [sp, #8] 397; NONEON-NOSVE-NEXT: ldrh w9, [sp, #14] 398; NONEON-NOSVE-NEXT: stp q0, q1, [sp, #16] 399; NONEON-NOSVE-NEXT: ldrh w11, [sp, #12] 400; NONEON-NOSVE-NEXT: ldp s1, s2, [sp, #24] 401; NONEON-NOSVE-NEXT: ldr s0, [sp, #44] 402; NONEON-NOSVE-NEXT: sbfx w9, w9, #0, #1 403; NONEON-NOSVE-NEXT: ldrh w10, [sp, #10] 404; NONEON-NOSVE-NEXT: ldrh w8, [sp, #8] 405; NONEON-NOSVE-NEXT: cmp w9, #0 406; NONEON-NOSVE-NEXT: sbfx w9, w11, #0, #1 407; NONEON-NOSVE-NEXT: sbfx w8, w8, #0, #1 408; NONEON-NOSVE-NEXT: fcsel s3, s2, s0, ne 409; NONEON-NOSVE-NEXT: ldr s0, [sp, #40] 410; NONEON-NOSVE-NEXT: cmp w9, #0 411; NONEON-NOSVE-NEXT: sbfx w9, w10, #0, #1 412; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, ne 413; NONEON-NOSVE-NEXT: ldp s1, s2, [sp, #16] 414; NONEON-NOSVE-NEXT: cmp w9, #0 415; NONEON-NOSVE-NEXT: stp s0, s3, [sp, #56] 416; NONEON-NOSVE-NEXT: ldr s0, [sp, #36] 417; NONEON-NOSVE-NEXT: fcsel s3, s2, s0, ne 418; NONEON-NOSVE-NEXT: ldr s0, [sp, #32] 419; NONEON-NOSVE-NEXT: cmp w8, #0 420; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, ne 421; NONEON-NOSVE-NEXT: stp s0, s3, [sp, #48] 422; NONEON-NOSVE-NEXT: ldr q0, [sp, #48] 423; NONEON-NOSVE-NEXT: add sp, sp, #64 424; NONEON-NOSVE-NEXT: ret 425 %sel = select <4 x i1> %mask, <4 x float> %op1, <4 x float> %op2 426 ret <4 x float> %sel 427} 428 429define void @select_v8f32(ptr %a, ptr %b) { 430; CHECK-LABEL: select_v8f32: 431; CHECK: // %bb.0: 432; CHECK-NEXT: ldp q0, q2, [x0] 433; CHECK-NEXT: ptrue p0.s, vl4 434; CHECK-NEXT: ldp q1, q3, [x1] 435; CHECK-NEXT: fcmeq p1.s, p0/z, z0.s, z1.s 436; CHECK-NEXT: fcmeq p0.s, p0/z, z2.s, z3.s 437; CHECK-NEXT: sel z0.s, p1, z0.s, z1.s 438; CHECK-NEXT: sel z1.s, p0, z2.s, z3.s 439; CHECK-NEXT: stp q0, q1, [x0] 440; CHECK-NEXT: ret 441; 442; NONEON-NOSVE-LABEL: select_v8f32: 443; NONEON-NOSVE: // %bb.0: 444; NONEON-NOSVE-NEXT: ldp q0, q3, [x1] 445; NONEON-NOSVE-NEXT: ldp q1, q2, [x0] 446; NONEON-NOSVE-NEXT: stp q1, q0, [sp, #-96]! 447; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 96 448; NONEON-NOSVE-NEXT: stp q2, q3, [sp, #32] 449; NONEON-NOSVE-NEXT: ldp s0, s2, [sp, #20] 450; NONEON-NOSVE-NEXT: ldp s1, s3, [sp, #4] 451; NONEON-NOSVE-NEXT: ldr s4, [sp, #12] 452; NONEON-NOSVE-NEXT: ldr s17, [sp] 453; NONEON-NOSVE-NEXT: ldp s6, s7, [sp, #36] 454; NONEON-NOSVE-NEXT: fcmp s1, s0 455; NONEON-NOSVE-NEXT: fcsel s0, s1, s0, eq 456; NONEON-NOSVE-NEXT: fcmp s3, s2 457; NONEON-NOSVE-NEXT: ldp s1, s5, [sp, #28] 458; NONEON-NOSVE-NEXT: fcsel s2, s3, s2, eq 459; NONEON-NOSVE-NEXT: ldp s16, s3, [sp, #44] 460; NONEON-NOSVE-NEXT: fcmp s4, s1 461; NONEON-NOSVE-NEXT: fcsel s1, s4, s1, eq 462; NONEON-NOSVE-NEXT: fcmp s5, s3 463; NONEON-NOSVE-NEXT: ldr s4, [sp, #52] 464; NONEON-NOSVE-NEXT: fcsel s3, s5, s3, eq 465; NONEON-NOSVE-NEXT: fcmp s6, s4 466; NONEON-NOSVE-NEXT: ldr s5, [sp, #56] 467; NONEON-NOSVE-NEXT: stp s2, s1, [sp, #72] 468; NONEON-NOSVE-NEXT: fcsel s4, s6, s4, eq 469; NONEON-NOSVE-NEXT: fcmp s7, s5 470; NONEON-NOSVE-NEXT: ldr s6, [sp, #60] 471; NONEON-NOSVE-NEXT: fcsel s5, s7, s5, eq 472; NONEON-NOSVE-NEXT: fcmp s16, s6 473; NONEON-NOSVE-NEXT: ldr s7, [sp, #16] 474; NONEON-NOSVE-NEXT: stp s3, s4, [sp, #80] 475; NONEON-NOSVE-NEXT: fcsel s6, s16, s6, eq 476; NONEON-NOSVE-NEXT: fcmp s17, s7 477; NONEON-NOSVE-NEXT: fcsel s3, s17, s7, eq 478; NONEON-NOSVE-NEXT: stp s5, s6, [sp, #88] 479; NONEON-NOSVE-NEXT: stp s3, s0, [sp, #64] 480; NONEON-NOSVE-NEXT: ldp q0, q1, [sp, #64] 481; NONEON-NOSVE-NEXT: stp q0, q1, [x0] 482; NONEON-NOSVE-NEXT: add sp, sp, #96 483; NONEON-NOSVE-NEXT: ret 484 %op1 = load <8 x float>, ptr %a 485 %op2 = load <8 x float>, ptr %b 486 %mask = fcmp oeq <8 x float> %op1, %op2 487 %sel = select <8 x i1> %mask, <8 x float> %op1, <8 x float> %op2 488 store <8 x float> %sel, ptr %a 489 ret void 490} 491 492define <1 x double> @select_v1f64(<1 x double> %op1, <1 x double> %op2, <1 x i1> %mask) { 493; CHECK-LABEL: select_v1f64: 494; CHECK: // %bb.0: 495; CHECK-NEXT: tst w0, #0x1 496; CHECK-NEXT: fcsel d0, d0, d1, ne 497; CHECK-NEXT: ret 498; 499; NONEON-NOSVE-LABEL: select_v1f64: 500; NONEON-NOSVE: // %bb.0: 501; NONEON-NOSVE-NEXT: sub sp, sp, #16 502; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 16 503; NONEON-NOSVE-NEXT: tst w0, #0x1 504; NONEON-NOSVE-NEXT: fcsel d0, d0, d1, ne 505; NONEON-NOSVE-NEXT: str d0, [sp, #8] 506; NONEON-NOSVE-NEXT: ldr d0, [sp, #8] 507; NONEON-NOSVE-NEXT: add sp, sp, #16 508; NONEON-NOSVE-NEXT: ret 509 %sel = select <1 x i1> %mask, <1 x double> %op1, <1 x double> %op2 510 ret <1 x double> %sel 511} 512 513define <2 x double> @select_v2f64(<2 x double> %op1, <2 x double> %op2, <2 x i1> %mask) { 514; CHECK-LABEL: select_v2f64: 515; CHECK: // %bb.0: 516; CHECK-NEXT: // kill: def $d2 killed $d2 def $z2 517; CHECK-NEXT: ptrue p0.d 518; CHECK-NEXT: // kill: def $q0 killed $q0 def $z0 519; CHECK-NEXT: // kill: def $q1 killed $q1 def $z1 520; CHECK-NEXT: uunpklo z2.d, z2.s 521; CHECK-NEXT: lsl z2.d, z2.d, #63 522; CHECK-NEXT: asr z2.d, z2.d, #63 523; CHECK-NEXT: and z2.d, z2.d, #0x1 524; CHECK-NEXT: cmpne p0.d, p0/z, z2.d, #0 525; CHECK-NEXT: sel z0.d, p0, z0.d, z1.d 526; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0 527; CHECK-NEXT: ret 528; 529; NONEON-NOSVE-LABEL: select_v2f64: 530; NONEON-NOSVE: // %bb.0: 531; NONEON-NOSVE-NEXT: sub sp, sp, #64 532; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 64 533; NONEON-NOSVE-NEXT: str d2, [sp, #8] 534; NONEON-NOSVE-NEXT: ldp w9, w8, [sp, #8] 535; NONEON-NOSVE-NEXT: stp q0, q1, [sp, #16] 536; NONEON-NOSVE-NEXT: ldp d1, d2, [sp, #16] 537; NONEON-NOSVE-NEXT: ldr d0, [sp, #40] 538; NONEON-NOSVE-NEXT: sbfx x8, x8, #0, #1 539; NONEON-NOSVE-NEXT: cmp x8, #0 540; NONEON-NOSVE-NEXT: sbfx x8, x9, #0, #1 541; NONEON-NOSVE-NEXT: fcsel d3, d2, d0, ne 542; NONEON-NOSVE-NEXT: ldr d0, [sp, #32] 543; NONEON-NOSVE-NEXT: cmp x8, #0 544; NONEON-NOSVE-NEXT: fcsel d0, d1, d0, ne 545; NONEON-NOSVE-NEXT: stp d0, d3, [sp, #48] 546; NONEON-NOSVE-NEXT: ldr q0, [sp, #48] 547; NONEON-NOSVE-NEXT: add sp, sp, #64 548; NONEON-NOSVE-NEXT: ret 549 %sel = select <2 x i1> %mask, <2 x double> %op1, <2 x double> %op2 550 ret <2 x double> %sel 551} 552 553define void @select_v4f64(ptr %a, ptr %b) { 554; CHECK-LABEL: select_v4f64: 555; CHECK: // %bb.0: 556; CHECK-NEXT: ldp q0, q2, [x0] 557; CHECK-NEXT: ptrue p0.d, vl2 558; CHECK-NEXT: ldp q1, q3, [x1] 559; CHECK-NEXT: fcmeq p1.d, p0/z, z0.d, z1.d 560; CHECK-NEXT: fcmeq p0.d, p0/z, z2.d, z3.d 561; CHECK-NEXT: sel z0.d, p1, z0.d, z1.d 562; CHECK-NEXT: sel z1.d, p0, z2.d, z3.d 563; CHECK-NEXT: stp q0, q1, [x0] 564; CHECK-NEXT: ret 565; 566; NONEON-NOSVE-LABEL: select_v4f64: 567; NONEON-NOSVE: // %bb.0: 568; NONEON-NOSVE-NEXT: ldp q0, q3, [x1] 569; NONEON-NOSVE-NEXT: ldp q1, q2, [x0] 570; NONEON-NOSVE-NEXT: stp q1, q0, [sp, #-96]! 571; NONEON-NOSVE-NEXT: .cfi_def_cfa_offset 96 572; NONEON-NOSVE-NEXT: stp q2, q3, [sp, #32] 573; NONEON-NOSVE-NEXT: ldp d5, d1, [sp] 574; NONEON-NOSVE-NEXT: ldp d0, d3, [sp, #24] 575; NONEON-NOSVE-NEXT: ldp d4, d2, [sp, #40] 576; NONEON-NOSVE-NEXT: fcmp d1, d0 577; NONEON-NOSVE-NEXT: fcsel d0, d1, d0, eq 578; NONEON-NOSVE-NEXT: fcmp d3, d2 579; NONEON-NOSVE-NEXT: ldr d1, [sp, #56] 580; NONEON-NOSVE-NEXT: fcsel d2, d3, d2, eq 581; NONEON-NOSVE-NEXT: fcmp d4, d1 582; NONEON-NOSVE-NEXT: ldr d3, [sp, #16] 583; NONEON-NOSVE-NEXT: fcsel d1, d4, d1, eq 584; NONEON-NOSVE-NEXT: fcmp d5, d3 585; NONEON-NOSVE-NEXT: fcsel d3, d5, d3, eq 586; NONEON-NOSVE-NEXT: stp d2, d1, [sp, #80] 587; NONEON-NOSVE-NEXT: stp d3, d0, [sp, #64] 588; NONEON-NOSVE-NEXT: ldp q0, q1, [sp, #64] 589; NONEON-NOSVE-NEXT: stp q0, q1, [x0] 590; NONEON-NOSVE-NEXT: add sp, sp, #96 591; NONEON-NOSVE-NEXT: ret 592 %op1 = load <4 x double>, ptr %a 593 %op2 = load <4 x double>, ptr %b 594 %mask = fcmp oeq <4 x double> %op1, %op2 595 %sel = select <4 x i1> %mask, <4 x double> %op1, <4 x double> %op2 596 store <4 x double> %sel, ptr %a 597 ret void 598} 599