1; RUN: llc < %s -verify-machineinstrs -mtriple=arm64-none-linux-gnu -mattr=+neon -fp-contract=fast | FileCheck %s 2 3define <8x i8> @test_select_cc_v8i8_i8(i8 %a, i8 %b, <8x i8> %c, <8x i8> %d ) { 4; CHECK-LABEL: test_select_cc_v8i8_i8: 5; CHECK-DAG: fmov s[[LHS:[0-9]+]], w0 6; CHECK-DAG: fmov s[[RHS:[0-9]+]], w1 7; CHECK: cmeq [[MASK:v[0-9]+]].8b, v[[LHS]].8b, v[[RHS]].8b 8; CHECK: dup [[DUPMASK:v[0-9]+]].8b, [[MASK]].b[0] 9; CHECK: bsl [[DUPMASK]].8b, v0.8b, v1.8b 10 %cmp31 = icmp eq i8 %a, %b 11 %e = select i1 %cmp31, <8x i8> %c, <8x i8> %d 12 ret <8x i8> %e 13} 14 15define <8x i8> @test_select_cc_v8i8_f32(float %a, float %b, <8x i8> %c, <8x i8> %d ) { 16; CHECK-LABEL: test_select_cc_v8i8_f32: 17; CHECK: fcmeq [[MASK:v[0-9]+]].2s, v0.2s, v1.2s 18; CHECK-NEXT: dup [[DUPMASK:v[0-9]+]].2s, [[MASK]].s[0] 19; CHECK-NEXT: bsl [[DUPMASK]].8b, v2.8b, v3.8b 20 %cmp31 = fcmp oeq float %a, %b 21 %e = select i1 %cmp31, <8x i8> %c, <8x i8> %d 22 ret <8x i8> %e 23} 24 25define <8x i8> @test_select_cc_v8i8_f64(double %a, double %b, <8x i8> %c, <8x i8> %d ) { 26; CHECK-LABEL: test_select_cc_v8i8_f64: 27; CHECK: fcmeq d[[MASK:[0-9]+]], d0, d1 28; CHECK-NEXT: bsl v[[MASK]].8b, v2.8b, v3.8b 29 %cmp31 = fcmp oeq double %a, %b 30 %e = select i1 %cmp31, <8x i8> %c, <8x i8> %d 31 ret <8x i8> %e 32} 33 34define <16x i8> @test_select_cc_v16i8_i8(i8 %a, i8 %b, <16x i8> %c, <16x i8> %d ) { 35; CHECK-LABEL: test_select_cc_v16i8_i8: 36; CHECK-DAG: fmov s[[LHS:[0-9]+]], w0 37; CHECK-DAG: fmov s[[RHS:[0-9]+]], w1 38; CHECK: cmeq [[MASK:v[0-9]+]].16b, v[[LHS]].16b, v[[RHS]].16b 39; CHECK: dup [[DUPMASK:v[0-9]+]].16b, [[MASK]].b[0] 40; CHECK: bsl [[DUPMASK]].16b, v0.16b, v1.16b 41 %cmp31 = icmp eq i8 %a, %b 42 %e = select i1 %cmp31, <16x i8> %c, <16x i8> %d 43 ret <16x i8> %e 44} 45 46define <16x i8> @test_select_cc_v16i8_f32(float %a, float %b, <16x i8> %c, <16x i8> %d ) { 47; CHECK-LABEL: test_select_cc_v16i8_f32: 48; CHECK: fcmeq [[MASK:v[0-9]+]].4s, v0.4s, v1.4s 49; CHECK-NEXT: dup [[DUPMASK:v[0-9]+]].4s, [[MASK]].s[0] 50; CHECK-NEXT: bsl [[DUPMASK]].16b, v2.16b, v3.16b 51 %cmp31 = fcmp oeq float %a, %b 52 %e = select i1 %cmp31, <16x i8> %c, <16x i8> %d 53 ret <16x i8> %e 54} 55 56define <16x i8> @test_select_cc_v16i8_f64(double %a, double %b, <16x i8> %c, <16x i8> %d ) { 57; CHECK-LABEL: test_select_cc_v16i8_f64: 58; CHECK: fcmeq [[MASK:v[0-9]+]].2d, v0.2d, v1.2d 59; CHECK-NEXT: dup [[DUPMASK:v[0-9]+]].2d, [[MASK]].d[0] 60; CHECK-NEXT: bsl [[DUPMASK]].16b, v2.16b, v3.16b 61 %cmp31 = fcmp oeq double %a, %b 62 %e = select i1 %cmp31, <16x i8> %c, <16x i8> %d 63 ret <16x i8> %e 64} 65 66define <4x i16> @test_select_cc_v4i16(i16 %a, i16 %b, <4x i16> %c, <4x i16> %d ) { 67; CHECK-LABEL: test_select_cc_v4i16: 68; CHECK-DAG: fmov s[[LHS:[0-9]+]], w0 69; CHECK-DAG: fmov s[[RHS:[0-9]+]], w1 70; CHECK: cmeq [[MASK:v[0-9]+]].4h, v[[LHS]].4h, v[[RHS]].4h 71; CHECK: dup [[DUPMASK:v[0-9]+]].4h, [[MASK]].h[0] 72; CHECK: bsl [[DUPMASK]].8b, v0.8b, v1.8b 73 %cmp31 = icmp eq i16 %a, %b 74 %e = select i1 %cmp31, <4x i16> %c, <4x i16> %d 75 ret <4x i16> %e 76} 77 78define <8x i16> @test_select_cc_v8i16(i16 %a, i16 %b, <8x i16> %c, <8x i16> %d ) { 79; CHECK-LABEL: test_select_cc_v8i16: 80; CHECK-DAG: fmov s[[LHS:[0-9]+]], w0 81; CHECK-DAG: fmov s[[RHS:[0-9]+]], w1 82; CHECK: cmeq [[MASK:v[0-9]+]].8h, v[[LHS]].8h, v[[RHS]].8h 83; CHECK: dup [[DUPMASK:v[0-9]+]].8h, [[MASK]].h[0] 84; CHECK: bsl [[DUPMASK]].16b, v0.16b, v1.16b 85 %cmp31 = icmp eq i16 %a, %b 86 %e = select i1 %cmp31, <8x i16> %c, <8x i16> %d 87 ret <8x i16> %e 88} 89 90define <2x i32> @test_select_cc_v2i32(i32 %a, i32 %b, <2x i32> %c, <2x i32> %d ) { 91; CHECK-LABEL: test_select_cc_v2i32: 92; CHECK-DAG: fmov s[[LHS:[0-9]+]], w0 93; CHECK-DAG: fmov s[[RHS:[0-9]+]], w1 94; CHECK: cmeq [[MASK:v[0-9]+]].2s, v[[LHS]].2s, v[[RHS]].2s 95; CHECK: dup [[DUPMASK:v[0-9]+]].2s, [[MASK]].s[0] 96; CHECK: bsl [[DUPMASK]].8b, v0.8b, v1.8b 97 %cmp31 = icmp eq i32 %a, %b 98 %e = select i1 %cmp31, <2x i32> %c, <2x i32> %d 99 ret <2x i32> %e 100} 101 102define <4x i32> @test_select_cc_v4i32(i32 %a, i32 %b, <4x i32> %c, <4x i32> %d ) { 103; CHECK-LABEL: test_select_cc_v4i32: 104; CHECK-DAG: fmov s[[LHS:[0-9]+]], w0 105; CHECK-DAG: fmov s[[RHS:[0-9]+]], w1 106; CHECK: cmeq [[MASK:v[0-9]+]].4s, v[[LHS]].4s, v[[RHS]].4s 107; CHECK: dup [[DUPMASK:v[0-9]+]].4s, [[MASK]].s[0] 108; CHECK: bsl [[DUPMASK]].16b, v0.16b, v1.16b 109 %cmp31 = icmp eq i32 %a, %b 110 %e = select i1 %cmp31, <4x i32> %c, <4x i32> %d 111 ret <4x i32> %e 112} 113 114define <1x i64> @test_select_cc_v1i64(i64 %a, i64 %b, <1x i64> %c, <1x i64> %d ) { 115; CHECK-LABEL: test_select_cc_v1i64: 116; CHECK-DAG: fmov d[[LHS:[0-9]+]], x0 117; CHECK-DAG: fmov d[[RHS:[0-9]+]], x1 118; CHECK: cmeq d[[MASK:[0-9]+]], d[[LHS]], d[[RHS]] 119; CHECK: bsl v[[MASK]].8b, v0.8b, v1.8b 120 %cmp31 = icmp eq i64 %a, %b 121 %e = select i1 %cmp31, <1x i64> %c, <1x i64> %d 122 ret <1x i64> %e 123} 124 125define <2x i64> @test_select_cc_v2i64(i64 %a, i64 %b, <2x i64> %c, <2x i64> %d ) { 126; CHECK-LABEL: test_select_cc_v2i64: 127; CHECK-DAG: fmov d[[LHS:[0-9]+]], x0 128; CHECK-DAG: fmov d[[RHS:[0-9]+]], x1 129; CHECK: cmeq [[MASK:v[0-9]+]].2d, v[[LHS]].2d, v[[RHS]].2d 130; CHECK: dup [[DUPMASK:v[0-9]+]].2d, [[MASK]].d[0] 131; CHECK: bsl [[DUPMASK]].16b, v0.16b, v1.16b 132 %cmp31 = icmp eq i64 %a, %b 133 %e = select i1 %cmp31, <2x i64> %c, <2x i64> %d 134 ret <2x i64> %e 135} 136 137define <1 x float> @test_select_cc_v1f32(float %a, float %b, <1 x float> %c, <1 x float> %d ) { 138; CHECK-LABEL: test_select_cc_v1f32: 139; CHECK: fcmeq [[MASK:v[0-9]+]].2s, v0.2s, v1.2s 140; CHECK-NEXT: bsl [[MASK]].8b, v2.8b, v3.8b 141 %cmp31 = fcmp oeq float %a, %b 142 %e = select i1 %cmp31, <1 x float> %c, <1 x float> %d 143 ret <1 x float> %e 144} 145 146define <2 x float> @test_select_cc_v2f32(float %a, float %b, <2 x float> %c, <2 x float> %d ) { 147; CHECK-LABEL: test_select_cc_v2f32: 148; CHECK: fcmeq [[MASK:v[0-9]+]].2s, v0.2s, v1.2s 149; CHECK: dup [[DUPMASK:v[0-9]+]].2s, [[MASK]].s[0] 150; CHECK: bsl [[DUPMASK]].8b, v2.8b, v3.8b 151 %cmp31 = fcmp oeq float %a, %b 152 %e = select i1 %cmp31, <2 x float> %c, <2 x float> %d 153 ret <2 x float> %e 154} 155 156define <4x float> @test_select_cc_v4f32(float %a, float %b, <4x float> %c, <4x float> %d ) { 157; CHECK-LABEL: test_select_cc_v4f32: 158; CHECK: fcmeq [[MASK:v[0-9]+]].4s, v0.4s, v1.4s 159; CHECK: dup [[DUPMASK:v[0-9]+]].4s, [[MASK]].s[0] 160; CHECK: bsl [[DUPMASK]].16b, v2.16b, v3.16b 161 %cmp31 = fcmp oeq float %a, %b 162 %e = select i1 %cmp31, <4x float> %c, <4x float> %d 163 ret <4x float> %e 164} 165 166define <4x float> @test_select_cc_v4f32_icmp(i32 %a, i32 %b, <4x float> %c, <4x float> %d ) { 167; CHECK-LABEL: test_select_cc_v4f32_icmp: 168; CHECK-DAG: fmov s[[LHS:[0-9]+]], w0 169; CHECK-DAG: fmov s[[RHS:[0-9]+]], w1 170; CHECK: cmeq [[MASK:v[0-9]+]].4s, v[[LHS]].4s, v[[RHS]].4s 171; CHECK: dup [[DUPMASK:v[0-9]+]].4s, [[MASK]].s[0] 172; CHECK: bsl [[DUPMASK]].16b, v0.16b, v1.16b 173 %cmp31 = icmp eq i32 %a, %b 174 %e = select i1 %cmp31, <4x float> %c, <4x float> %d 175 ret <4x float> %e 176} 177 178define <1 x double> @test_select_cc_v1f64(double %a, double %b, <1 x double> %c, <1 x double> %d ) { 179; CHECK-LABEL: test_select_cc_v1f64: 180; CHECK: fcmeq d[[MASK:[0-9]+]], d0, d1 181; CHECK: bsl v[[MASK]].8b, v2.8b, v3.8b 182 %cmp31 = fcmp oeq double %a, %b 183 %e = select i1 %cmp31, <1 x double> %c, <1 x double> %d 184 ret <1 x double> %e 185} 186 187define <1 x double> @test_select_cc_v1f64_icmp(i64 %a, i64 %b, <1 x double> %c, <1 x double> %d ) { 188; CHECK-LABEL: test_select_cc_v1f64_icmp: 189; CHECK-DAG: fmov [[LHS:d[0-9]+]], x0 190; CHECK-DAG: fmov [[RHS:d[0-9]+]], x1 191; CHECK: cmeq d[[MASK:[0-9]+]], [[LHS]], [[RHS]] 192; CHECK: bsl v[[MASK]].8b, v0.8b, v1.8b 193 %cmp31 = icmp eq i64 %a, %b 194 %e = select i1 %cmp31, <1 x double> %c, <1 x double> %d 195 ret <1 x double> %e 196} 197 198define <2 x double> @test_select_cc_v2f64(double %a, double %b, <2 x double> %c, <2 x double> %d ) { 199; CHECK-LABEL: test_select_cc_v2f64: 200; CHECK: fcmeq [[MASK:v[0-9]+]].2d, v0.2d, v1.2d 201; CHECK: dup [[DUPMASK:v[0-9]+]].2d, [[MASK]].d[0] 202; CHECK: bsl [[DUPMASK]].16b, v2.16b, v3.16b 203 %cmp31 = fcmp oeq double %a, %b 204 %e = select i1 %cmp31, <2 x double> %c, <2 x double> %d 205 ret <2 x double> %e 206} 207 208; Special case: when the select condition is an icmp with i1 operands, don't 209; do the comparison on vectors. 210; Part of PR21549. 211define <2 x i32> @test_select_cc_v2i32_icmpi1(i1 %cc, <2 x i32> %a, <2 x i32> %b) { 212; CHECK-LABEL: test_select_cc_v2i32_icmpi1: 213; CHECK: tst w0, #0x1 214; CHECK: csetm [[MASK:w[0-9]+]], ne 215; CHECK: dup [[DUPMASK:v[0-9]+]].2s, [[MASK]] 216; CHECK: bsl [[DUPMASK]].8b, v0.8b, v1.8b 217; CHECK: mov v0.16b, [[DUPMASK]].16b 218 %cmp = icmp ne i1 %cc, 0 219 %e = select i1 %cmp, <2 x i32> %a, <2 x i32> %b 220 ret <2 x i32> %e 221} 222