1; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+unimplemented-simd128 | FileCheck %s --check-prefixes CHECK,SIMD128,SIMD128-SLOW 2; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+unimplemented-simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,SIMD128,SIMD128-FAST 3; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128-VM 4; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,SIMD128-VM 5; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefixes CHECK,NO-SIMD128 6; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -fast-isel | FileCheck %s --check-prefixes CHECK,NO-SIMD128 7 8; check that a non-test run (including explicit locals pass) at least finishes 9; RUN: llc < %s -O0 -mattr=+unimplemented-simd128 10; RUN: llc < %s -O2 -mattr=+unimplemented-simd128 11 12; Test that basic SIMD128 arithmetic operations assemble as expected. 13 14target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 15target triple = "wasm32-unknown-unknown" 16 17; ============================================================================== 18; 16 x i8 19; ============================================================================== 20; CHECK-LABEL: add_v16i8: 21; NO-SIMD128-NOT: i8x16 22; SIMD128-NEXT: .functype add_v16i8 (v128, v128) -> (v128){{$}} 23; SIMD128-NEXT: i8x16.add $push[[R:[0-9]+]]=, $0, $1{{$}} 24; SIMD128-NEXT: return $pop[[R]]{{$}} 25define <16 x i8> @add_v16i8(<16 x i8> %x, <16 x i8> %y) { 26 %a = add <16 x i8> %x, %y 27 ret <16 x i8> %a 28} 29 30; CHECK-LABEL: sub_v16i8: 31; NO-SIMD128-NOT: i8x16 32; SIMD128-NEXT: .functype sub_v16i8 (v128, v128) -> (v128){{$}} 33; SIMD128-NEXT: i8x16.sub $push[[R:[0-9]+]]=, $0, $1{{$}} 34; SIMD128-NEXT: return $pop[[R]]{{$}} 35define <16 x i8> @sub_v16i8(<16 x i8> %x, <16 x i8> %y) { 36 %a = sub <16 x i8> %x, %y 37 ret <16 x i8> %a 38} 39 40; CHECK-LABEL: mul_v16i8: 41; NO-SIMD128-NOT: i8x16 42; SIMD128-NEXT: .functype mul_v16i8 (v128, v128) -> (v128){{$}} 43; SIMD128-NEXT: i8x16.mul $push[[R:[0-9]+]]=, $0, $1{{$}} 44; SIMD128-NEXT: return $pop[[R]]{{$}} 45define <16 x i8> @mul_v16i8(<16 x i8> %x, <16 x i8> %y) { 46 %a = mul <16 x i8> %x, %y 47 ret <16 x i8> %a 48} 49 50; CHECK-LABEL: neg_v16i8: 51; NO-SIMD128-NOT: i8x16 52; SIMD128-NEXT: .functype neg_v16i8 (v128) -> (v128){{$}} 53; SIMD128-NEXT: i8x16.neg $push[[R:[0-9]+]]=, $0{{$}} 54; SIMD128-NEXT: return $pop[[R]]{{$}} 55define <16 x i8> @neg_v16i8(<16 x i8> %x) { 56 %a = sub <16 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, 57 i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>, 58 %x 59 ret <16 x i8> %a 60} 61 62; CHECK-LABEL: shl_v16i8: 63; NO-SIMD128-NOT: i8x16 64; SIMD128-NEXT: .functype shl_v16i8 (v128, i32) -> (v128){{$}} 65; SIMD128-NEXT: i8x16.shl $push[[R:[0-9]+]]=, $0, $1{{$}} 66; SIMD128-NEXT: return $pop[[R]]{{$}} 67define <16 x i8> @shl_v16i8(<16 x i8> %v, i8 %x) { 68 %t = insertelement <16 x i8> undef, i8 %x, i32 0 69 %s = shufflevector <16 x i8> %t, <16 x i8> undef, 70 <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, 71 i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 72 %a = shl <16 x i8> %v, %s 73 ret <16 x i8> %a 74} 75 76; CHECK-LABEL: shl_const_v16i8: 77; NO-SIMD128-NOT: i8x16 78; SIMD128-NEXT: .functype shl_const_v16i8 (v128) -> (v128){{$}} 79; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5 80; SIMD128-NEXT: i8x16.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 81; SIMD128-NEXT: return $pop[[R]]{{$}} 82define <16 x i8> @shl_const_v16i8(<16 x i8> %v) { 83 %a = shl <16 x i8> %v, 84 <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, 85 i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5> 86 ret <16 x i8> %a 87} 88 89; CHECK-LABEL: shl_vec_v16i8: 90; NO-SIMD128-NOT: i8x16 91; SIMD128-NEXT: .functype shl_vec_v16i8 (v128, v128) -> (v128){{$}} 92; SIMD128-NEXT: i8x16.extract_lane_s $push[[L0:[0-9]+]]=, $0, 0{{$}} 93; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 7{{$}} 94; SIMD128-NEXT: i8x16.splat $push[[M1:[0-9]+]]=, $pop[[M0]]{{$}} 95; SIMD128-NEXT: v128.and $push[[M2:[0-9]+]]=, $1, $pop[[M1]]{{$}} 96; SIMD128-NEXT: local.tee $push[[M:[0-9]+]]=, $1=, $pop[[M2]]{{$}} 97; SIMD128-NEXT: i8x16.extract_lane_u $push[[L1:[0-9]+]]=, $pop[[M]], 0{{$}} 98; SIMD128-NEXT: i32.shl $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 99; SIMD128-NEXT: i8x16.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 100; Skip 14 lanes 101; SIMD128: i8x16.extract_lane_s $push[[L4:[0-9]+]]=, $0, 15{{$}} 102; SIMD128-NEXT: i8x16.extract_lane_u $push[[L5:[0-9]+]]=, $1, 15{{$}} 103; SIMD128-NEXT: i32.shl $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 104; SIMD128-NEXT: i8x16.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 15, $pop[[L6]]{{$}} 105; SIMD128-NEXT: return $pop[[R]]{{$}} 106define <16 x i8> @shl_vec_v16i8(<16 x i8> %v, <16 x i8> %x) { 107 %a = shl <16 x i8> %v, %x 108 ret <16 x i8> %a 109} 110 111; CHECK-LABEL: shr_s_v16i8: 112; NO-SIMD128-NOT: i8x16 113; SIMD128-NEXT: .functype shr_s_v16i8 (v128, i32) -> (v128){{$}} 114; SIMD128-NEXT: i8x16.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}} 115; SIMD128-NEXT: return $pop[[R]]{{$}} 116define <16 x i8> @shr_s_v16i8(<16 x i8> %v, i8 %x) { 117 %t = insertelement <16 x i8> undef, i8 %x, i32 0 118 %s = shufflevector <16 x i8> %t, <16 x i8> undef, 119 <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, 120 i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 121 %a = ashr <16 x i8> %v, %s 122 ret <16 x i8> %a 123} 124 125; CHECK-LABEL: shr_s_vec_v16i8: 126; NO-SIMD128-NOT: i8x16 127; SIMD128-NEXT: .functype shr_s_vec_v16i8 (v128, v128) -> (v128){{$}} 128; SIMD128-NEXT: i8x16.extract_lane_s $push[[L0:[0-9]+]]=, $0, 0{{$}} 129; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 7{{$}} 130; SIMD128-NEXT: i8x16.splat $push[[M1:[0-9]+]]=, $pop[[M0]]{{$}} 131; SIMD128-NEXT: v128.and $push[[M2:[0-9]+]]=, $1, $pop[[M1]]{{$}} 132; SIMD128-NEXT: local.tee $push[[M:[0-9]+]]=, $1=, $pop[[M2]]{{$}} 133; SIMD128-NEXT: i8x16.extract_lane_u $push[[L1:[0-9]+]]=, $pop[[M]], 0{{$}} 134; SIMD128-NEXT: i32.shr_s $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 135; SIMD128-NEXT: i8x16.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 136; Skip 14 lanes 137; SIMD128: i8x16.extract_lane_s $push[[L0:[0-9]+]]=, $0, 15{{$}} 138; SIMD128-NEXT: i8x16.extract_lane_u $push[[L1:[0-9]+]]=, $1, 15{{$}} 139; SIMD128-NEXT: i32.shr_s $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 140; SIMD128-NEXT: i8x16.replace_lane $push[[R:[0-9]+]]=, $pop{{[0-9]+}}, 15, $pop[[L2]]{{$}} 141; SIMD128-NEXT: return $pop[[R]]{{$}} 142define <16 x i8> @shr_s_vec_v16i8(<16 x i8> %v, <16 x i8> %x) { 143 %a = ashr <16 x i8> %v, %x 144 ret <16 x i8> %a 145} 146 147; CHECK-LABEL: shr_u_v16i8: 148; NO-SIMD128-NOT: i8x16 149; SIMD128-NEXT: .functype shr_u_v16i8 (v128, i32) -> (v128){{$}} 150; SIMD128-NEXT: i8x16.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}} 151; SIMD128-NEXT: return $pop[[R]]{{$}} 152define <16 x i8> @shr_u_v16i8(<16 x i8> %v, i8 %x) { 153 %t = insertelement <16 x i8> undef, i8 %x, i32 0 154 %s = shufflevector <16 x i8> %t, <16 x i8> undef, 155 <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, 156 i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 157 %a = lshr <16 x i8> %v, %s 158 ret <16 x i8> %a 159} 160 161; CHECK-LABEL: shr_u_vec_v16i8: 162; NO-SIMD128-NOT: i8x16 163; SIMD128-NEXT: .functype shr_u_vec_v16i8 (v128, v128) -> (v128){{$}} 164; SIMD128-NEXT: i8x16.extract_lane_u $push[[L0:[0-9]+]]=, $0, 0{{$}} 165; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 7{{$}} 166; SIMD128-NEXT: i8x16.splat $push[[M1:[0-9]+]]=, $pop[[M0]]{{$}} 167; SIMD128-NEXT: v128.and $push[[M2:[0-9]+]]=, $1, $pop[[M1]]{{$}} 168; SIMD128-NEXT: local.tee $push[[M:[0-9]+]]=, $1=, $pop[[M2]]{{$}} 169; SIMD128-NEXT: i8x16.extract_lane_u $push[[L1:[0-9]+]]=, $pop[[M]], 0{{$}} 170; SIMD128-NEXT: i32.shr_u $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 171; SIMD128-NEXT: i8x16.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 172; Skip 14 lanes 173; SIMD128: i8x16.extract_lane_u $push[[L4:[0-9]+]]=, $0, 15{{$}} 174; SIMD128-NEXT: i8x16.extract_lane_u $push[[L5:[0-9]+]]=, $1, 15{{$}} 175; SIMD128-NEXT: i32.shr_u $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 176; SIMD128-NEXT: i8x16.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 15, $pop[[L6]]{{$}} 177; SIMD128-NEXT: return $pop[[R]]{{$}} 178define <16 x i8> @shr_u_vec_v16i8(<16 x i8> %v, <16 x i8> %x) { 179 %a = lshr <16 x i8> %v, %x 180 ret <16 x i8> %a 181} 182 183; CHECK-LABEL: and_v16i8: 184; NO-SIMD128-NOT: v128 185; SIMD128-NEXT: .functype and_v16i8 (v128, v128) -> (v128){{$}} 186; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}} 187; SIMD128-NEXT: return $pop[[R]]{{$}} 188define <16 x i8> @and_v16i8(<16 x i8> %x, <16 x i8> %y) { 189 %a = and <16 x i8> %x, %y 190 ret <16 x i8> %a 191} 192 193; CHECK-LABEL: or_v16i8: 194; NO-SIMD128-NOT: v128 195; SIMD128-NEXT: .functype or_v16i8 (v128, v128) -> (v128){{$}} 196; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}} 197; SIMD128-NEXT: return $pop[[R]]{{$}} 198define <16 x i8> @or_v16i8(<16 x i8> %x, <16 x i8> %y) { 199 %a = or <16 x i8> %x, %y 200 ret <16 x i8> %a 201} 202 203; CHECK-LABEL: xor_v16i8: 204; NO-SIMD128-NOT: v128 205; SIMD128-NEXT: .functype xor_v16i8 (v128, v128) -> (v128){{$}} 206; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}} 207; SIMD128-NEXT: return $pop[[R]]{{$}} 208define <16 x i8> @xor_v16i8(<16 x i8> %x, <16 x i8> %y) { 209 %a = xor <16 x i8> %x, %y 210 ret <16 x i8> %a 211} 212 213; CHECK-LABEL: not_v16i8: 214; NO-SIMD128-NOT: v128 215; SIMD128-NEXT: .functype not_v16i8 (v128) -> (v128){{$}} 216; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}} 217; SIMD128-NEXT: return $pop[[R]]{{$}} 218define <16 x i8> @not_v16i8(<16 x i8> %x) { 219 %a = xor <16 x i8> %x, <i8 -1, i8 -1, i8 -1, i8 -1, 220 i8 -1, i8 -1, i8 -1, i8 -1, 221 i8 -1, i8 -1, i8 -1, i8 -1, 222 i8 -1, i8 -1, i8 -1, i8 -1> 223 ret <16 x i8> %a 224} 225 226; CHECK-LABEL: andnot_v16i8: 227; NO-SIMD128-NOT: v128 228; SIMD128-VM-NOT: v128.andnot 229; SIMD128-NEXT: .functype andnot_v16i8 (v128, v128) -> (v128){{$}} 230; SIMD128-SLOW-NEXT: v128.andnot $push[[R:[0-9]+]]=, $0, $1{{$}} 231; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}} 232; SIMD128-FAST-NEXT: v128.not 233; SIMD128-FAST-NEXT: v128.and 234; SIMD128-FAST-NEXT: return 235define <16 x i8> @andnot_v16i8(<16 x i8> %x, <16 x i8> %y) { 236 %inv_y = xor <16 x i8> %y, 237 <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, 238 i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> 239 %a = and <16 x i8> %x, %inv_y 240 ret <16 x i8> %a 241} 242 243; CHECK-LABEL: bitselect_v16i8: 244; NO-SIMD128-NOT: v128 245; SIMD128-NEXT: .functype bitselect_v16i8 (v128, v128, v128) -> (v128){{$}} 246; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}} 247; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}} 248; SIMD128-FAST-NEXT: v128.and 249; SIMD128-FAST-NEXT: v128.not 250; SIMD128-FAST-NEXT: v128.and 251; SIMD128-FAST-NEXT: v128.or 252; SIMD128-FAST-NEXT: return 253define <16 x i8> @bitselect_v16i8(<16 x i8> %c, <16 x i8> %v1, <16 x i8> %v2) { 254 %masked_v1 = and <16 x i8> %c, %v1 255 %inv_mask = xor <16 x i8> %c, 256 <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, 257 i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> 258 %masked_v2 = and <16 x i8> %inv_mask, %v2 259 %a = or <16 x i8> %masked_v1, %masked_v2 260 ret <16 x i8> %a 261} 262 263; ============================================================================== 264; 8 x i16 265; ============================================================================== 266; CHECK-LABEL: add_v8i16: 267; NO-SIMD128-NOT: i16x8 268; SIMD128-NEXT: .functype add_v8i16 (v128, v128) -> (v128){{$}} 269; SIMD128-NEXT: i16x8.add $push[[R:[0-9]+]]=, $0, $1{{$}} 270; SIMD128-NEXT: return $pop[[R]]{{$}} 271define <8 x i16> @add_v8i16(<8 x i16> %x, <8 x i16> %y) { 272 %a = add <8 x i16> %x, %y 273 ret <8 x i16> %a 274} 275 276; CHECK-LABEL: sub_v8i16: 277; NO-SIMD128-NOT: i16x8 278; SIMD128-NEXT: .functype sub_v8i16 (v128, v128) -> (v128){{$}} 279; SIMD128-NEXT: i16x8.sub $push[[R:[0-9]+]]=, $0, $1{{$}} 280; SIMD128-NEXT: return $pop[[R]]{{$}} 281define <8 x i16> @sub_v8i16(<8 x i16> %x, <8 x i16> %y) { 282 %a = sub <8 x i16> %x, %y 283 ret <8 x i16> %a 284} 285 286; CHECK-LABEL: mul_v8i16: 287; NO-SIMD128-NOT: i16x8 288; SIMD128-NEXT: .functype mul_v8i16 (v128, v128) -> (v128){{$}} 289; SIMD128-NEXT: i16x8.mul $push[[R:[0-9]+]]=, $0, $1{{$}} 290; SIMD128-NEXT: return $pop[[R]]{{$}} 291define <8 x i16> @mul_v8i16(<8 x i16> %x, <8 x i16> %y) { 292 %a = mul <8 x i16> %x, %y 293 ret <8 x i16> %a 294} 295 296; CHECK-LABEL: neg_v8i16: 297; NO-SIMD128-NOT: i16x8 298; SIMD128-NEXT: .functype neg_v8i16 (v128) -> (v128){{$}} 299; SIMD128-NEXT: i16x8.neg $push[[R:[0-9]+]]=, $0{{$}} 300; SIMD128-NEXT: return $pop[[R]]{{$}} 301define <8 x i16> @neg_v8i16(<8 x i16> %x) { 302 %a = sub <8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>, 303 %x 304 ret <8 x i16> %a 305} 306 307; CHECK-LABEL: shl_v8i16: 308; NO-SIMD128-NOT: i16x8 309; SIMD128-NEXT: .functype shl_v8i16 (v128, i32) -> (v128){{$}} 310; SIMD128-NEXT: i16x8.shl $push[[R:[0-9]+]]=, $0, $1{{$}} 311; SIMD128-NEXT: return $pop[[R]]{{$}} 312define <8 x i16> @shl_v8i16(<8 x i16> %v, i16 %x) { 313 %t = insertelement <8 x i16> undef, i16 %x, i32 0 314 %s = shufflevector <8 x i16> %t, <8 x i16> undef, 315 <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 316 %a = shl <8 x i16> %v, %s 317 ret <8 x i16> %a 318} 319 320; CHECK-LABEL: shl_const_v8i16: 321; NO-SIMD128-NOT: i16x8 322; SIMD128-NEXT: .functype shl_const_v8i16 (v128) -> (v128){{$}} 323; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5 324; SIMD128-NEXT: i16x8.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 325; SIMD128-NEXT: return $pop[[R]]{{$}} 326define <8 x i16> @shl_const_v8i16(<8 x i16> %v) { 327 %a = shl <8 x i16> %v, 328 <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5> 329 ret <8 x i16> %a 330} 331 332; CHECK-LABEL: shl_vec_v8i16: 333; NO-SIMD128-NOT: i16x8 334; SIMD128-NEXT: .functype shl_vec_v8i16 (v128, v128) -> (v128){{$}} 335; SIMD128-NEXT: i16x8.extract_lane_s $push[[L0:[0-9]+]]=, $0, 0{{$}} 336; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 15{{$}} 337; SIMD128-NEXT: i16x8.splat $push[[M1:[0-9]+]]=, $pop[[M0]]{{$}} 338; SIMD128-NEXT: v128.and $push[[M2:[0-9]+]]=, $1, $pop[[M1]]{{$}} 339; SIMD128-NEXT: local.tee $push[[M:[0-9]+]]=, $1=, $pop[[M2]]{{$}} 340; SIMD128-NEXT: i16x8.extract_lane_u $push[[L1:[0-9]+]]=, $pop[[M]], 0{{$}} 341; SIMD128-NEXT: i32.shl $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 342; SIMD128-NEXT: i16x8.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 343; Skip 6 lanes 344; SIMD128: i16x8.extract_lane_s $push[[L4:[0-9]+]]=, $0, 7{{$}} 345; SIMD128-NEXT: i16x8.extract_lane_u $push[[L5:[0-9]+]]=, $1, 7{{$}} 346; SIMD128-NEXT: i32.shl $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 347; SIMD128-NEXT: i16x8.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 7, $pop[[L6]]{{$}} 348; SIMD128-NEXT: return $pop[[R]]{{$}} 349define <8 x i16> @shl_vec_v8i16(<8 x i16> %v, <8 x i16> %x) { 350 %a = shl <8 x i16> %v, %x 351 ret <8 x i16> %a 352} 353 354; CHECK-LABEL: shr_s_v8i16: 355; NO-SIMD128-NOT: i16x8 356; SIMD128-NEXT: .functype shr_s_v8i16 (v128, i32) -> (v128){{$}} 357; SIMD128-NEXT: i16x8.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}} 358; SIMD128-NEXT: return $pop[[R]]{{$}} 359define <8 x i16> @shr_s_v8i16(<8 x i16> %v, i16 %x) { 360 %t = insertelement <8 x i16> undef, i16 %x, i32 0 361 %s = shufflevector <8 x i16> %t, <8 x i16> undef, 362 <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 363 %a = ashr <8 x i16> %v, %s 364 ret <8 x i16> %a 365} 366 367; CHECK-LABEL: shr_s_vec_v8i16: 368; NO-SIMD128-NOT: i16x8 369; SIMD128-NEXT: .functype shr_s_vec_v8i16 (v128, v128) -> (v128){{$}} 370; SIMD128-NEXT: i16x8.extract_lane_s $push[[L0:[0-9]+]]=, $0, 0{{$}} 371; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 15{{$}} 372; SIMD128-NEXT: i16x8.splat $push[[M1:[0-9]+]]=, $pop[[M0]]{{$}} 373; SIMD128-NEXT: v128.and $push[[M2:[0-9]+]]=, $1, $pop[[M1]]{{$}} 374; SIMD128-NEXT: local.tee $push[[M:[0-9]+]]=, $1=, $pop[[M2]]{{$}} 375; SIMD128-NEXT: i16x8.extract_lane_u $push[[L1:[0-9]+]]=, $pop[[M]], 0{{$}} 376; SIMD128-NEXT: i32.shr_s $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 377; SIMD128-NEXT: i16x8.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 378; Skip 6 lanes 379; SIMD128: i16x8.extract_lane_s $push[[L0:[0-9]+]]=, $0, 7{{$}} 380; SIMD128-NEXT: i16x8.extract_lane_u $push[[L1:[0-9]+]]=, $1, 7{{$}} 381; SIMD128-NEXT: i32.shr_s $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 382; SIMD128-NEXT: i16x8.replace_lane $push[[R:[0-9]+]]=, $pop{{[0-9]+}}, 7, $pop[[L2]]{{$}} 383; SIMD128-NEXT: return $pop[[R]]{{$}} 384define <8 x i16> @shr_s_vec_v8i16(<8 x i16> %v, <8 x i16> %x) { 385 %a = ashr <8 x i16> %v, %x 386 ret <8 x i16> %a 387} 388 389; CHECK-LABEL: shr_u_v8i16: 390; NO-SIMD128-NOT: i16x8 391; SIMD128-NEXT: .functype shr_u_v8i16 (v128, i32) -> (v128){{$}} 392; SIMD128-NEXT: i16x8.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}} 393; SIMD128-NEXT: return $pop[[R]]{{$}} 394define <8 x i16> @shr_u_v8i16(<8 x i16> %v, i16 %x) { 395 %t = insertelement <8 x i16> undef, i16 %x, i32 0 396 %s = shufflevector <8 x i16> %t, <8 x i16> undef, 397 <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 398 %a = lshr <8 x i16> %v, %s 399 ret <8 x i16> %a 400} 401 402; CHECK-LABEL: shr_u_vec_v8i16: 403; NO-SIMD128-NOT: i16x8 404; SIMD128-NEXT: .functype shr_u_vec_v8i16 (v128, v128) -> (v128){{$}} 405; SIMD128-NEXT: i16x8.extract_lane_u $push[[L0:[0-9]+]]=, $0, 0{{$}} 406; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 15{{$}} 407; SIMD128-NEXT: i16x8.splat $push[[M1:[0-9]+]]=, $pop[[M0]]{{$}} 408; SIMD128-NEXT: v128.and $push[[M2:[0-9]+]]=, $1, $pop[[M1]]{{$}} 409; SIMD128-NEXT: local.tee $push[[M:[0-9]+]]=, $1=, $pop[[M2]]{{$}} 410; SIMD128-NEXT: i16x8.extract_lane_u $push[[L1:[0-9]+]]=, $pop[[M]], 0{{$}} 411; SIMD128-NEXT: i32.shr_u $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 412; SIMD128-NEXT: i16x8.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 413; Skip 6 lanes 414; SIMD128: i16x8.extract_lane_u $push[[L4:[0-9]+]]=, $0, 7{{$}} 415; SIMD128-NEXT: i16x8.extract_lane_u $push[[L5:[0-9]+]]=, $1, 7{{$}} 416; SIMD128-NEXT: i32.shr_u $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 417; SIMD128-NEXT: i16x8.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 7, $pop[[L6]]{{$}} 418; SIMD128-NEXT: return $pop[[R]]{{$}} 419define <8 x i16> @shr_u_vec_v8i16(<8 x i16> %v, <8 x i16> %x) { 420 %a = lshr <8 x i16> %v, %x 421 ret <8 x i16> %a 422} 423 424; CHECK-LABEL: and_v8i16: 425; NO-SIMD128-NOT: v128 426; SIMD128-NEXT: .functype and_v8i16 (v128, v128) -> (v128){{$}} 427; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}} 428; SIMD128-NEXT: return $pop[[R]]{{$}} 429define <8 x i16> @and_v8i16(<8 x i16> %x, <8 x i16> %y) { 430 %a = and <8 x i16> %x, %y 431 ret <8 x i16> %a 432} 433 434; CHECK-LABEL: or_v8i16: 435; NO-SIMD128-NOT: v128 436; SIMD128-NEXT: .functype or_v8i16 (v128, v128) -> (v128){{$}} 437; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}} 438; SIMD128-NEXT: return $pop[[R]]{{$}} 439define <8 x i16> @or_v8i16(<8 x i16> %x, <8 x i16> %y) { 440 %a = or <8 x i16> %x, %y 441 ret <8 x i16> %a 442} 443 444; CHECK-LABEL: xor_v8i16: 445; NO-SIMD128-NOT: v128 446; SIMD128-NEXT: .functype xor_v8i16 (v128, v128) -> (v128){{$}} 447; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}} 448; SIMD128-NEXT: return $pop[[R]]{{$}} 449define <8 x i16> @xor_v8i16(<8 x i16> %x, <8 x i16> %y) { 450 %a = xor <8 x i16> %x, %y 451 ret <8 x i16> %a 452} 453 454; CHECK-LABEL: not_v8i16: 455; NO-SIMD128-NOT: v128 456; SIMD128-NEXT: .functype not_v8i16 (v128) -> (v128){{$}} 457; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}} 458; SIMD128-NEXT: return $pop[[R]]{{$}} 459define <8 x i16> @not_v8i16(<8 x i16> %x) { 460 %a = xor <8 x i16> %x, <i16 -1, i16 -1, i16 -1, i16 -1, 461 i16 -1, i16 -1, i16 -1, i16 -1> 462 ret <8 x i16> %a 463} 464 465; CHECK-LABEL: andnot_v8i16: 466; SIMD128-VM-NOT: v128.andnot 467; NO-SIMD128-NOT: v128 468; SIMD128-NEXT: .functype andnot_v8i16 (v128, v128) -> (v128){{$}} 469; SIMD128-SLOW-NEXT: v128.andnot $push[[R:[0-9]+]]=, $0, $1{{$}} 470; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}} 471; SIMD128-FAST-NEXT: v128.not 472; SIMD128-FAST-NEXT: v128.and 473; SIMD128-FAST-NEXT: return 474define <8 x i16> @andnot_v8i16(<8 x i16> %x, <8 x i16> %y) { 475 %inv_y = xor <8 x i16> %y, 476 <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1> 477 %a = and <8 x i16> %x, %inv_y 478 ret <8 x i16> %a 479} 480 481; CHECK-LABEL: bitselect_v8i16: 482; NO-SIMD128-NOT: v128 483; SIMD128-NEXT: .functype bitselect_v8i16 (v128, v128, v128) -> (v128){{$}} 484; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}} 485; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}} 486; SIMD128-FAST-NEXT: v128.and 487; SIMD128-FAST-NEXT: v128.not 488; SIMD128-FAST-NEXT: v128.and 489; SIMD128-FAST-NEXT: v128.or 490; SIMD128-FAST-NEXT: return 491define <8 x i16> @bitselect_v8i16(<8 x i16> %c, <8 x i16> %v1, <8 x i16> %v2) { 492 %masked_v1 = and <8 x i16> %v1, %c 493 %inv_mask = xor <8 x i16> 494 <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>, 495 %c 496 %masked_v2 = and <8 x i16> %v2, %inv_mask 497 %a = or <8 x i16> %masked_v1, %masked_v2 498 ret <8 x i16> %a 499} 500 501; ============================================================================== 502; 4 x i32 503; ============================================================================== 504; CHECK-LABEL: add_v4i32: 505; NO-SIMD128-NOT: i32x4 506; SIMD128-NEXT: .functype add_v4i32 (v128, v128) -> (v128){{$}} 507; SIMD128-NEXT: i32x4.add $push[[R:[0-9]+]]=, $0, $1{{$}} 508; SIMD128-NEXT: return $pop[[R]]{{$}} 509define <4 x i32> @add_v4i32(<4 x i32> %x, <4 x i32> %y) { 510 %a = add <4 x i32> %x, %y 511 ret <4 x i32> %a 512} 513 514; CHECK-LABEL: sub_v4i32: 515; NO-SIMD128-NOT: i32x4 516; SIMD128-NEXT: .functype sub_v4i32 (v128, v128) -> (v128){{$}} 517; SIMD128-NEXT: i32x4.sub $push[[R:[0-9]+]]=, $0, $1{{$}} 518; SIMD128-NEXT: return $pop[[R]]{{$}} 519define <4 x i32> @sub_v4i32(<4 x i32> %x, <4 x i32> %y) { 520 %a = sub <4 x i32> %x, %y 521 ret <4 x i32> %a 522} 523 524; CHECK-LABEL: mul_v4i32: 525; NO-SIMD128-NOT: i32x4 526; SIMD128-NEXT: .functype mul_v4i32 (v128, v128) -> (v128){{$}} 527; SIMD128-NEXT: i32x4.mul $push[[R:[0-9]+]]=, $0, $1{{$}} 528; SIMD128-NEXT: return $pop[[R]]{{$}} 529define <4 x i32> @mul_v4i32(<4 x i32> %x, <4 x i32> %y) { 530 %a = mul <4 x i32> %x, %y 531 ret <4 x i32> %a 532} 533 534; CHECK-LABEL: neg_v4i32: 535; NO-SIMD128-NOT: i32x4 536; SIMD128-NEXT: .functype neg_v4i32 (v128) -> (v128){{$}} 537; SIMD128-NEXT: i32x4.neg $push[[R:[0-9]+]]=, $0{{$}} 538; SIMD128-NEXT: return $pop[[R]]{{$}} 539define <4 x i32> @neg_v4i32(<4 x i32> %x) { 540 %a = sub <4 x i32> <i32 0, i32 0, i32 0, i32 0>, %x 541 ret <4 x i32> %a 542} 543 544; CHECK-LABEL: shl_v4i32: 545; NO-SIMD128-NOT: i32x4 546; SIMD128-NEXT: .functype shl_v4i32 (v128, i32) -> (v128){{$}} 547; SIMD128-NEXT: i32x4.shl $push[[R:[0-9]+]]=, $0, $1{{$}} 548; SIMD128-NEXT: return $pop[[R]]{{$}} 549define <4 x i32> @shl_v4i32(<4 x i32> %v, i32 %x) { 550 %t = insertelement <4 x i32> undef, i32 %x, i32 0 551 %s = shufflevector <4 x i32> %t, <4 x i32> undef, 552 <4 x i32> <i32 0, i32 0, i32 0, i32 0> 553 %a = shl <4 x i32> %v, %s 554 ret <4 x i32> %a 555} 556 557; CHECK-LABEL: shl_const_v4i32: 558; NO-SIMD128-NOT: i32x4 559; SIMD128-NEXT: .functype shl_const_v4i32 (v128) -> (v128){{$}} 560; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5 561; SIMD128-NEXT: i32x4.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 562; SIMD128-NEXT: return $pop[[R]]{{$}} 563define <4 x i32> @shl_const_v4i32(<4 x i32> %v) { 564 %a = shl <4 x i32> %v, <i32 5, i32 5, i32 5, i32 5> 565 ret <4 x i32> %a 566} 567 568; CHECK-LABEL: shl_vec_v4i32: 569; NO-SIMD128-NOT: i32x4 570; SIMD128-NEXT: .functype shl_vec_v4i32 (v128, v128) -> (v128){{$}} 571; SIMD128-NEXT: i32x4.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}} 572; SIMD128-NEXT: i32x4.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}} 573; SIMD128-NEXT: i32.shl $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 574; SIMD128-NEXT: i32x4.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 575; Skip 2 lanes 576; SIMD128: i32x4.extract_lane $push[[L4:[0-9]+]]=, $0, 3{{$}} 577; SIMD128-NEXT: i32x4.extract_lane $push[[L5:[0-9]+]]=, $1, 3{{$}} 578; SIMD128-NEXT: i32.shl $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 579; SIMD128-NEXT: i32x4.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 3, $pop[[L6]]{{$}} 580; SIMD128-NEXT: return $pop[[R]]{{$}} 581define <4 x i32> @shl_vec_v4i32(<4 x i32> %v, <4 x i32> %x) { 582 %a = shl <4 x i32> %v, %x 583 ret <4 x i32> %a 584} 585 586; CHECK-LABEL: shr_s_v4i32: 587; NO-SIMD128-NOT: i32x4 588; SIMD128-NEXT: .functype shr_s_v4i32 (v128, i32) -> (v128){{$}} 589; SIMD128-NEXT: i32x4.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}} 590; SIMD128-NEXT: return $pop[[R]]{{$}} 591define <4 x i32> @shr_s_v4i32(<4 x i32> %v, i32 %x) { 592 %t = insertelement <4 x i32> undef, i32 %x, i32 0 593 %s = shufflevector <4 x i32> %t, <4 x i32> undef, 594 <4 x i32> <i32 0, i32 0, i32 0, i32 0> 595 %a = ashr <4 x i32> %v, %s 596 ret <4 x i32> %a 597} 598 599; CHECK-LABEL: shr_s_vec_v4i32: 600; NO-SIMD128-NOT: i32x4 601; SIMD128-NEXT: .functype shr_s_vec_v4i32 (v128, v128) -> (v128){{$}} 602; SIMD128-NEXT: i32x4.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}} 603; SIMD128-NEXT: i32x4.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}} 604; SIMD128-NEXT: i32.shr_s $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 605; SIMD128-NEXT: i32x4.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 606; Skip 2 lanes 607; SIMD128: i32x4.extract_lane $push[[L4:[0-9]+]]=, $0, 3{{$}} 608; SIMD128-NEXT: i32x4.extract_lane $push[[L5:[0-9]+]]=, $1, 3{{$}} 609; SIMD128-NEXT: i32.shr_s $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 610; SIMD128-NEXT: i32x4.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 3, $pop[[L6]]{{$}} 611; SIMD128-NEXT: return $pop[[R]]{{$}} 612define <4 x i32> @shr_s_vec_v4i32(<4 x i32> %v, <4 x i32> %x) { 613 %a = ashr <4 x i32> %v, %x 614 ret <4 x i32> %a 615} 616 617; CHECK-LABEL: shr_u_v4i32: 618; NO-SIMD128-NOT: i32x4 619; SIMD128-NEXT: .functype shr_u_v4i32 (v128, i32) -> (v128){{$}} 620; SIMD128-NEXT: i32x4.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}} 621; SIMD128-NEXT: return $pop[[R]]{{$}} 622define <4 x i32> @shr_u_v4i32(<4 x i32> %v, i32 %x) { 623 %t = insertelement <4 x i32> undef, i32 %x, i32 0 624 %s = shufflevector <4 x i32> %t, <4 x i32> undef, 625 <4 x i32> <i32 0, i32 0, i32 0, i32 0> 626 %a = lshr <4 x i32> %v, %s 627 ret <4 x i32> %a 628} 629 630; CHECK-LABEL: shr_u_vec_v4i32: 631; NO-SIMD128-NOT: i32x4 632; SIMD128-NEXT: .functype shr_u_vec_v4i32 (v128, v128) -> (v128){{$}} 633; SIMD128-NEXT: i32x4.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}} 634; SIMD128-NEXT: i32x4.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}} 635; SIMD128-NEXT: i32.shr_u $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 636; SIMD128-NEXT: i32x4.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 637; Skip 2 lanes 638; SIMD128: i32x4.extract_lane $push[[L4:[0-9]+]]=, $0, 3{{$}} 639; SIMD128-NEXT: i32x4.extract_lane $push[[L5:[0-9]+]]=, $1, 3{{$}} 640; SIMD128-NEXT: i32.shr_u $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 641; SIMD128-NEXT: i32x4.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 3, $pop[[L6]]{{$}} 642; SIMD128-NEXT: return $pop[[R]]{{$}} 643define <4 x i32> @shr_u_vec_v4i32(<4 x i32> %v, <4 x i32> %x) { 644 %a = lshr <4 x i32> %v, %x 645 ret <4 x i32> %a 646} 647 648; CHECK-LABEL: and_v4i32: 649; NO-SIMD128-NOT: v128 650; SIMD128-NEXT: .functype and_v4i32 (v128, v128) -> (v128){{$}} 651; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}} 652; SIMD128-NEXT: return $pop[[R]]{{$}} 653define <4 x i32> @and_v4i32(<4 x i32> %x, <4 x i32> %y) { 654 %a = and <4 x i32> %x, %y 655 ret <4 x i32> %a 656} 657 658; CHECK-LABEL: or_v4i32: 659; NO-SIMD128-NOT: v128 660; SIMD128-NEXT: .functype or_v4i32 (v128, v128) -> (v128){{$}} 661; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}} 662; SIMD128-NEXT: return $pop[[R]]{{$}} 663define <4 x i32> @or_v4i32(<4 x i32> %x, <4 x i32> %y) { 664 %a = or <4 x i32> %x, %y 665 ret <4 x i32> %a 666} 667 668; CHECK-LABEL: xor_v4i32: 669; NO-SIMD128-NOT: v128 670; SIMD128-NEXT: .functype xor_v4i32 (v128, v128) -> (v128){{$}} 671; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}} 672; SIMD128-NEXT: return $pop[[R]]{{$}} 673define <4 x i32> @xor_v4i32(<4 x i32> %x, <4 x i32> %y) { 674 %a = xor <4 x i32> %x, %y 675 ret <4 x i32> %a 676} 677 678; CHECK-LABEL: not_v4i32: 679; NO-SIMD128-NOT: v128 680; SIMD128-NEXT: .functype not_v4i32 (v128) -> (v128){{$}} 681; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}} 682; SIMD128-NEXT: return $pop[[R]]{{$}} 683define <4 x i32> @not_v4i32(<4 x i32> %x) { 684 %a = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1> 685 ret <4 x i32> %a 686} 687 688; CHECK-LABEL: andnot_v4i32: 689; SIMD128-VM-NOT: v128.andnot 690; NO-SIMD128-NOT: v128 691; SIMD128-NEXT: .functype andnot_v4i32 (v128, v128) -> (v128){{$}} 692; SIMD128-SLOW-NEXT: v128.andnot $push[[R:[0-9]+]]=, $0, $1{{$}} 693; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}} 694; SIMD128-FAST-NEXT: v128.not 695; SIMD128-FAST-NEXT: v128.and 696; SIMD128-FAST-NEXT: return 697define <4 x i32> @andnot_v4i32(<4 x i32> %x, <4 x i32> %y) { 698 %inv_y = xor <4 x i32> %y, <i32 -1, i32 -1, i32 -1, i32 -1> 699 %a = and <4 x i32> %x, %inv_y 700 ret <4 x i32> %a 701} 702 703; CHECK-LABEL: bitselect_v4i32: 704; NO-SIMD128-NOT: v128 705; SIMD128-NEXT: .functype bitselect_v4i32 (v128, v128, v128) -> (v128){{$}} 706; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}} 707; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}} 708; SIMD128-FAST-NEXT: v128.not 709; SIMD128-FAST-NEXT: v128.and 710; SIMD128-FAST-NEXT: v128.and 711; SIMD128-FAST-NEXT: v128.or 712; SIMD128-FAST-NEXT: return 713define <4 x i32> @bitselect_v4i32(<4 x i32> %c, <4 x i32> %v1, <4 x i32> %v2) { 714 %masked_v1 = and <4 x i32> %c, %v1 715 %inv_mask = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %c 716 %masked_v2 = and <4 x i32> %inv_mask, %v2 717 %a = or <4 x i32> %masked_v2, %masked_v1 718 ret <4 x i32> %a 719} 720 721; ============================================================================== 722; 2 x i64 723; ============================================================================== 724; CHECK-LABEL: add_v2i64: 725; NO-SIMD128-NOT: i64x2 726; SIMD128-VM-NOT: i64x2 727; SIMD128-NEXT: .functype add_v2i64 (v128, v128) -> (v128){{$}} 728; SIMD128-NEXT: i64x2.add $push[[R:[0-9]+]]=, $0, $1{{$}} 729; SIMD128-NEXT: return $pop[[R]]{{$}} 730define <2 x i64> @add_v2i64(<2 x i64> %x, <2 x i64> %y) { 731 %a = add <2 x i64> %x, %y 732 ret <2 x i64> %a 733} 734 735; CHECK-LABEL: sub_v2i64: 736; NO-SIMD128-NOT: i64x2 737; SIMD128-VM-NOT: i64x2 738; SIMD128-NEXT: .functype sub_v2i64 (v128, v128) -> (v128){{$}} 739; SIMD128-NEXT: i64x2.sub $push[[R:[0-9]+]]=, $0, $1{{$}} 740; SIMD128-NEXT: return $pop[[R]]{{$}} 741define <2 x i64> @sub_v2i64(<2 x i64> %x, <2 x i64> %y) { 742 %a = sub <2 x i64> %x, %y 743 ret <2 x i64> %a 744} 745 746; v2i64.mul is not in spec 747; CHECK-LABEL: mul_v2i64: 748; NO-SIMD128-NOT: i64x2 749; SIMD128-VM-NOT: i64x2 750; SIMD128-NOT: i64x2.mul 751; SIMD128: i64x2.extract_lane 752; SIMD128: i64.mul 753define <2 x i64> @mul_v2i64(<2 x i64> %x, <2 x i64> %y) { 754 %a = mul <2 x i64> %x, %y 755 ret <2 x i64> %a 756} 757 758; CHECK-LABEL: neg_v2i64: 759; NO-SIMD128-NOT: i64x2 760; SIMD128-NEXT: .functype neg_v2i64 (v128) -> (v128){{$}} 761; SIMD128-NEXT: i64x2.neg $push[[R:[0-9]+]]=, $0{{$}} 762; SIMD128-NEXT: return $pop[[R]]{{$}} 763define <2 x i64> @neg_v2i64(<2 x i64> %x) { 764 %a = sub <2 x i64> <i64 0, i64 0>, %x 765 ret <2 x i64> %a 766} 767 768; CHECK-LABEL: shl_v2i64: 769; NO-SIMD128-NOT: i64x2 770; SIMD128-NEXT: .functype shl_v2i64 (v128, i32) -> (v128){{$}} 771; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $1{{$}} 772; SIMD128-NEXT: return $pop[[R]]{{$}} 773define <2 x i64> @shl_v2i64(<2 x i64> %v, i32 %x) { 774 %x2 = zext i32 %x to i64 775 %t = insertelement <2 x i64> undef, i64 %x2, i32 0 776 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 777 %a = shl <2 x i64> %v, %s 778 ret <2 x i64> %a 779} 780 781; CHECK-LABEL: shl_sext_v2i64: 782; NO-SIMD128-NOT: i64x2 783; SIMD128-NEXT: .functype shl_sext_v2i64 (v128, i32) -> (v128){{$}} 784; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $1{{$}} 785; SIMD128-NEXT: return $pop[[R]]{{$}} 786define <2 x i64> @shl_sext_v2i64(<2 x i64> %v, i32 %x) { 787 %x2 = sext i32 %x to i64 788 %t = insertelement <2 x i64> undef, i64 %x2, i32 0 789 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 790 %a = shl <2 x i64> %v, %s 791 ret <2 x i64> %a 792} 793 794; CHECK-LABEL: shl_noext_v2i64: 795; NO-SIMD128-NOT: i64x2 796; SIMD128-NEXT: .functype shl_noext_v2i64 (v128, i64) -> (v128){{$}} 797; SIMD128-NEXT: i32.wrap_i64 $push[[L0:[0-9]+]]=, $1{{$}} 798; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 799; SIMD128-NEXT: return $pop[[R]]{{$}} 800define <2 x i64> @shl_noext_v2i64(<2 x i64> %v, i64 %x) { 801 %t = insertelement <2 x i64> undef, i64 %x, i32 0 802 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 803 %a = shl <2 x i64> %v, %s 804 ret <2 x i64> %a 805} 806 807; CHECK-LABEL: shl_const_v2i64: 808; NO-SIMD128-NOT: i64x2 809; SIMD128-NEXT: .functype shl_const_v2i64 (v128) -> (v128){{$}} 810; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5{{$}} 811; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 812; SIMD128-NEXT: return $pop[[R]]{{$}} 813define <2 x i64> @shl_const_v2i64(<2 x i64> %v) { 814 %a = shl <2 x i64> %v, <i64 5, i64 5> 815 ret <2 x i64> %a 816} 817 818; CHECK-LABEL: shl_vec_v2i64: 819; NO-SIMD128-NOT: i64x2 820; SIMD128-NEXT: .functype shl_vec_v2i64 (v128, v128) -> (v128){{$}} 821; SIMD128-NEXT: i64x2.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}} 822; SIMD128-NEXT: i64x2.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}} 823; SIMD128-NEXT: i64.shl $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 824; SIMD128-NEXT: i64x2.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 825; SIMD128-NEXT: i64x2.extract_lane $push[[L4:[0-9]+]]=, $0, 1{{$}} 826; SIMD128-NEXT: i64x2.extract_lane $push[[L5:[0-9]+]]=, $1, 1{{$}} 827; SIMD128-NEXT: i64.shl $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 828; SIMD128-NEXT: i64x2.replace_lane $push[[R:[0-9]+]]=, $pop[[L3]], 1, $pop[[L6]]{{$}} 829; SIMD128-NEXT: return $pop[[R]]{{$}} 830define <2 x i64> @shl_vec_v2i64(<2 x i64> %v, <2 x i64> %x) { 831 %a = shl <2 x i64> %v, %x 832 ret <2 x i64> %a 833} 834 835; CHECK-LABEL: shr_s_v2i64: 836; NO-SIMD128-NOT: i64x2 837; SIMD128-NEXT: .functype shr_s_v2i64 (v128, i32) -> (v128){{$}} 838; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}} 839; SIMD128-NEXT: return $pop[[R]]{{$}} 840define <2 x i64> @shr_s_v2i64(<2 x i64> %v, i32 %x) { 841 %x2 = zext i32 %x to i64 842 %t = insertelement <2 x i64> undef, i64 %x2, i32 0 843 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 844 %a = ashr <2 x i64> %v, %s 845 ret <2 x i64> %a 846} 847 848; CHECK-LABEL: shr_s_sext_v2i64: 849; NO-SIMD128-NOT: i64x2 850; SIMD128-NEXT: .functype shr_s_sext_v2i64 (v128, i32) -> (v128){{$}} 851; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}} 852; SIMD128-NEXT: return $pop[[R]]{{$}} 853define <2 x i64> @shr_s_sext_v2i64(<2 x i64> %v, i32 %x) { 854 %x2 = sext i32 %x to i64 855 %t = insertelement <2 x i64> undef, i64 %x2, i32 0 856 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 857 %a = ashr <2 x i64> %v, %s 858 ret <2 x i64> %a 859} 860 861; CHECK-LABEL: shr_s_noext_v2i64: 862; NO-SIMD128-NOT: i64x2 863; SIMD128-NEXT: .functype shr_s_noext_v2i64 (v128, i64) -> (v128){{$}} 864; SIMD128-NEXT: i32.wrap_i64 $push[[L0:[0-9]+]]=, $1{{$}} 865; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 866; SIMD128-NEXT: return $pop[[R]]{{$}} 867define <2 x i64> @shr_s_noext_v2i64(<2 x i64> %v, i64 %x) { 868 %t = insertelement <2 x i64> undef, i64 %x, i32 0 869 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 870 %a = ashr <2 x i64> %v, %s 871 ret <2 x i64> %a 872} 873 874; CHECK-LABEL: shr_s_const_v2i64: 875; NO-SIMD128-NOT: i64x2 876; SIMD128-NEXT: .functype shr_s_const_v2i64 (v128) -> (v128){{$}} 877; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5{{$}} 878; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 879; SIMD128-NEXT: return $pop[[R]]{{$}} 880define <2 x i64> @shr_s_const_v2i64(<2 x i64> %v) { 881 %a = ashr <2 x i64> %v, <i64 5, i64 5> 882 ret <2 x i64> %a 883} 884 885; CHECK-LABEL: shr_s_vec_v2i64: 886; NO-SIMD128-NOT: i64x2 887; SIMD128-NEXT: .functype shr_s_vec_v2i64 (v128, v128) -> (v128){{$}} 888; SIMD128-NEXT: i64x2.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}} 889; SIMD128-NEXT: i64x2.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}} 890; SIMD128-NEXT: i64.shr_s $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 891; SIMD128-NEXT: i64x2.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 892; SIMD128-NEXT: i64x2.extract_lane $push[[L4:[0-9]+]]=, $0, 1{{$}} 893; SIMD128-NEXT: i64x2.extract_lane $push[[L5:[0-9]+]]=, $1, 1{{$}} 894; SIMD128-NEXT: i64.shr_s $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 895; SIMD128-NEXT: i64x2.replace_lane $push[[R:[0-9]+]]=, $pop[[L3]], 1, $pop[[L6]]{{$}} 896; SIMD128-NEXT: return $pop[[R]]{{$}} 897define <2 x i64> @shr_s_vec_v2i64(<2 x i64> %v, <2 x i64> %x) { 898 %a = ashr <2 x i64> %v, %x 899 ret <2 x i64> %a 900} 901 902; CHECK-LABEL: shr_u_v2i64: 903; NO-SIMD128-NOT: i64x2 904; SIMD128-NEXT: .functype shr_u_v2i64 (v128, i32) -> (v128){{$}} 905; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}} 906; SIMD128-NEXT: return $pop[[R]]{{$}} 907define <2 x i64> @shr_u_v2i64(<2 x i64> %v, i32 %x) { 908 %x2 = zext i32 %x to i64 909 %t = insertelement <2 x i64> undef, i64 %x2, i32 0 910 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 911 %a = lshr <2 x i64> %v, %s 912 ret <2 x i64> %a 913} 914 915; CHECK-LABEL: shr_u_sext_v2i64: 916; NO-SIMD128-NOT: i64x2 917; SIMD128-NEXT: .functype shr_u_sext_v2i64 (v128, i32) -> (v128){{$}} 918; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}} 919; SIMD128-NEXT: return $pop[[R]]{{$}} 920define <2 x i64> @shr_u_sext_v2i64(<2 x i64> %v, i32 %x) { 921 %x2 = sext i32 %x to i64 922 %t = insertelement <2 x i64> undef, i64 %x2, i32 0 923 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 924 %a = lshr <2 x i64> %v, %s 925 ret <2 x i64> %a 926} 927 928; CHECK-LABEL: shr_u_noext_v2i64: 929; NO-SIMD128-NOT: i64x2 930; SIMD128-NEXT: .functype shr_u_noext_v2i64 (v128, i64) -> (v128){{$}} 931; SIMD128-NEXT: i32.wrap_i64 $push[[L0:[0-9]+]]=, $1{{$}} 932; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 933; SIMD128-NEXT: return $pop[[R]]{{$}} 934define <2 x i64> @shr_u_noext_v2i64(<2 x i64> %v, i64 %x) { 935 %t = insertelement <2 x i64> undef, i64 %x, i32 0 936 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 937 %a = lshr <2 x i64> %v, %s 938 ret <2 x i64> %a 939} 940 941; CHECK-LABEL: shr_u_const_v2i64: 942; NO-SIMD128-NOT: i64x2 943; SIMD128-NEXT: .functype shr_u_const_v2i64 (v128) -> (v128){{$}} 944; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5{{$}} 945; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 946; SIMD128-NEXT: return $pop[[R]]{{$}} 947define <2 x i64> @shr_u_const_v2i64(<2 x i64> %v) { 948 %a = lshr <2 x i64> %v, <i64 5, i64 5> 949 ret <2 x i64> %a 950} 951 952; CHECK-LABEL: shr_u_vec_v2i64: 953; NO-SIMD128-NOT: i64x2 954; SIMD128-NEXT: .functype shr_u_vec_v2i64 (v128, v128) -> (v128){{$}} 955; SIMD128-NEXT: i64x2.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}} 956; SIMD128-NEXT: i64x2.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}} 957; SIMD128-NEXT: i64.shr_u $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 958; SIMD128-NEXT: i64x2.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 959; SIMD128-NEXT: i64x2.extract_lane $push[[L4:[0-9]+]]=, $0, 1{{$}} 960; SIMD128-NEXT: i64x2.extract_lane $push[[L5:[0-9]+]]=, $1, 1{{$}} 961; SIMD128-NEXT: i64.shr_u $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 962; SIMD128-NEXT: i64x2.replace_lane $push[[R:[0-9]+]]=, $pop[[L3]], 1, $pop[[L6]]{{$}} 963; SIMD128-NEXT: return $pop[[R]]{{$}} 964define <2 x i64> @shr_u_vec_v2i64(<2 x i64> %v, <2 x i64> %x) { 965 %a = lshr <2 x i64> %v, %x 966 ret <2 x i64> %a 967} 968 969; CHECK-LABEL: and_v2i64: 970; NO-SIMD128-NOT: v128 971; SIMD128-VM-NOT: v128 972; SIMD128-NEXT: .functype and_v2i64 (v128, v128) -> (v128){{$}} 973; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}} 974; SIMD128-NEXT: return $pop[[R]]{{$}} 975define <2 x i64> @and_v2i64(<2 x i64> %x, <2 x i64> %y) { 976 %a = and <2 x i64> %x, %y 977 ret <2 x i64> %a 978} 979 980; CHECK-LABEL: or_v2i64: 981; NO-SIMD128-NOT: v128 982; SIMD128-VM-NOT: v128 983; SIMD128-NEXT: .functype or_v2i64 (v128, v128) -> (v128){{$}} 984; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}} 985; SIMD128-NEXT: return $pop[[R]]{{$}} 986define <2 x i64> @or_v2i64(<2 x i64> %x, <2 x i64> %y) { 987 %a = or <2 x i64> %x, %y 988 ret <2 x i64> %a 989} 990 991; CHECK-LABEL: xor_v2i64: 992; NO-SIMD128-NOT: v128 993; SIMD128-VM-NOT: v128 994; SIMD128-NEXT: .functype xor_v2i64 (v128, v128) -> (v128){{$}} 995; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}} 996; SIMD128-NEXT: return $pop[[R]]{{$}} 997define <2 x i64> @xor_v2i64(<2 x i64> %x, <2 x i64> %y) { 998 %a = xor <2 x i64> %x, %y 999 ret <2 x i64> %a 1000} 1001 1002; CHECK-LABEL: not_v2i64: 1003; NO-SIMD128-NOT: v128 1004; SIMD128-VM-NOT: v128 1005; SIMD128-NEXT: .functype not_v2i64 (v128) -> (v128){{$}} 1006; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}} 1007; SIMD128-NEXT: return $pop[[R]]{{$}} 1008define <2 x i64> @not_v2i64(<2 x i64> %x) { 1009 %a = xor <2 x i64> %x, <i64 -1, i64 -1> 1010 ret <2 x i64> %a 1011} 1012 1013; CHECK-LABEL: andnot_v2i64: 1014; SIMD128-VM-NOT: v128.andnot 1015; NO-SIMD128-NOT: v128 1016; SIMD128-NEXT: .functype andnot_v2i64 (v128, v128) -> (v128){{$}} 1017; SIMD128-SLOW-NEXT: v128.andnot $push[[R:[0-9]+]]=, $0, $1{{$}} 1018; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}} 1019; SIMD128-FAST-NEXT: v128.not 1020; SIMD128-FAST-NEXT: v128.and 1021; SIMD128-FAST-NEXT: return 1022define <2 x i64> @andnot_v2i64(<2 x i64> %x, <2 x i64> %y) { 1023 %inv_y = xor <2 x i64> %y, <i64 -1, i64 -1> 1024 %a = and <2 x i64> %x, %inv_y 1025 ret <2 x i64> %a 1026} 1027 1028; CHECK-LABEL: bitselect_v2i64: 1029; NO-SIMD128-NOT: v128 1030; SIMD128-VM-NOT: v128 1031; SIMD128-NEXT: .functype bitselect_v2i64 (v128, v128, v128) -> (v128){{$}} 1032; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}} 1033; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}} 1034; SIMD128-FAST-NEXT: v128.not 1035; SIMD128-FAST-NEXT: v128.and 1036; SIMD128-FAST-NEXT: v128.and 1037; SIMD128-FAST-NEXT: v128.or 1038; SIMD128-FAST-NEXT: return 1039define <2 x i64> @bitselect_v2i64(<2 x i64> %c, <2 x i64> %v1, <2 x i64> %v2) { 1040 %masked_v1 = and <2 x i64> %v1, %c 1041 %inv_mask = xor <2 x i64> <i64 -1, i64 -1>, %c 1042 %masked_v2 = and <2 x i64> %v2, %inv_mask 1043 %a = or <2 x i64> %masked_v2, %masked_v1 1044 ret <2 x i64> %a 1045} 1046 1047; ============================================================================== 1048; 4 x float 1049; ============================================================================== 1050; CHECK-LABEL: neg_v4f32: 1051; NO-SIMD128-NOT: f32x4 1052; SIMD128-NEXT: .functype neg_v4f32 (v128) -> (v128){{$}} 1053; SIMD128-NEXT: f32x4.neg $push[[R:[0-9]+]]=, $0{{$}} 1054; SIMD128-NEXT: return $pop[[R]]{{$}} 1055define <4 x float> @neg_v4f32(<4 x float> %x) { 1056 ; nsz makes this semantically equivalent to flipping sign bit 1057 %a = fsub nsz <4 x float> <float 0.0, float 0.0, float 0.0, float 0.0>, %x 1058 ret <4 x float> %a 1059} 1060 1061; CHECK-LABEL: abs_v4f32: 1062; NO-SIMD128-NOT: f32x4 1063; SIMD128-NEXT: .functype abs_v4f32 (v128) -> (v128){{$}} 1064; SIMD128-NEXT: f32x4.abs $push[[R:[0-9]+]]=, $0{{$}} 1065; SIMD128-NEXT: return $pop[[R]]{{$}} 1066declare <4 x float> @llvm.fabs.v4f32(<4 x float>) nounwind readnone 1067define <4 x float> @abs_v4f32(<4 x float> %x) { 1068 %a = call <4 x float> @llvm.fabs.v4f32(<4 x float> %x) 1069 ret <4 x float> %a 1070} 1071 1072; CHECK-LABEL: min_unordered_v4f32: 1073; NO-SIMD128-NOT: f32x4 1074; SIMD128-NEXT: .functype min_unordered_v4f32 (v128) -> (v128){{$}} 1075; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2 1076; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 1077; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 1078; SIMD128-NEXT: return $pop[[R]]{{$}} 1079define <4 x float> @min_unordered_v4f32(<4 x float> %x) { 1080 %cmps = fcmp ule <4 x float> %x, <float 5., float 5., float 5., float 5.> 1081 %a = select <4 x i1> %cmps, <4 x float> %x, 1082 <4 x float> <float 5., float 5., float 5., float 5.> 1083 ret <4 x float> %a 1084} 1085 1086; CHECK-LABEL: max_unordered_v4f32: 1087; NO-SIMD128-NOT: f32x4 1088; SIMD128-NEXT: .functype max_unordered_v4f32 (v128) -> (v128){{$}} 1089; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2 1090; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 1091; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 1092; SIMD128-NEXT: return $pop[[R]]{{$}} 1093define <4 x float> @max_unordered_v4f32(<4 x float> %x) { 1094 %cmps = fcmp uge <4 x float> %x, <float 5., float 5., float 5., float 5.> 1095 %a = select <4 x i1> %cmps, <4 x float> %x, 1096 <4 x float> <float 5., float 5., float 5., float 5.> 1097 ret <4 x float> %a 1098} 1099 1100; CHECK-LABEL: min_ordered_v4f32: 1101; NO-SIMD128-NOT: f32x4 1102; SIMD128-NEXT: .functype min_ordered_v4f32 (v128) -> (v128){{$}} 1103; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2 1104; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 1105; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 1106; SIMD128-NEXT: return $pop[[R]]{{$}} 1107define <4 x float> @min_ordered_v4f32(<4 x float> %x) { 1108 %cmps = fcmp ole <4 x float> <float 5., float 5., float 5., float 5.>, %x 1109 %a = select <4 x i1> %cmps, 1110 <4 x float> <float 5., float 5., float 5., float 5.>, <4 x float> %x 1111 ret <4 x float> %a 1112} 1113 1114; CHECK-LABEL: max_ordered_v4f32: 1115; NO-SIMD128-NOT: f32x4 1116; SIMD128-NEXT: .functype max_ordered_v4f32 (v128) -> (v128){{$}} 1117; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2 1118; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 1119; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 1120; SIMD128-NEXT: return $pop[[R]]{{$}} 1121define <4 x float> @max_ordered_v4f32(<4 x float> %x) { 1122 %cmps = fcmp oge <4 x float> <float 5., float 5., float 5., float 5.>, %x 1123 %a = select <4 x i1> %cmps, 1124 <4 x float> <float 5., float 5., float 5., float 5.>, <4 x float> %x 1125 ret <4 x float> %a 1126} 1127 1128; CHECK-LABEL: min_intrinsic_v4f32: 1129; NO-SIMD128-NOT: f32x4 1130; SIMD128-NEXT: .functype min_intrinsic_v4f32 (v128, v128) -> (v128){{$}} 1131; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $0, $1{{$}} 1132; SIMD128-NEXT: return $pop[[R]]{{$}} 1133declare <4 x float> @llvm.minimum.v4f32(<4 x float>, <4 x float>) 1134define <4 x float> @min_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) { 1135 %a = call <4 x float> @llvm.minimum.v4f32(<4 x float> %x, <4 x float> %y) 1136 ret <4 x float> %a 1137} 1138 1139; CHECK-LABEL: minnum_intrinsic_v4f32: 1140; NO-SIMD128-NOT: f32x4 1141; SIMD128-NEXT: .functype minnum_intrinsic_v4f32 (v128, v128) -> (v128){{$}} 1142; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $0, $1{{$}} 1143; SIMD128-NEXT: return $pop[[R]]{{$}} 1144declare <4 x float> @llvm.minnum.v4f32(<4 x float>, <4 x float>) 1145define <4 x float> @minnum_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) { 1146 %a = call nnan <4 x float> @llvm.minnum.v4f32(<4 x float> %x, <4 x float> %y) 1147 ret <4 x float> %a 1148} 1149 1150; CHECK-LABEL: max_intrinsic_v4f32: 1151; NO-SIMD128-NOT: f32x4 1152; SIMD128-NEXT: .functype max_intrinsic_v4f32 (v128, v128) -> (v128){{$}} 1153; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $0, $1{{$}} 1154; SIMD128-NEXT: return $pop[[R]]{{$}} 1155declare <4 x float> @llvm.maximum.v4f32(<4 x float>, <4 x float>) 1156define <4 x float> @max_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) { 1157 %a = call <4 x float> @llvm.maximum.v4f32(<4 x float> %x, <4 x float> %y) 1158 ret <4 x float> %a 1159} 1160 1161; CHECK-LABEL: maxnum_intrinsic_v4f32: 1162; NO-SIMD128-NOT: f32x4 1163; SIMD128-NEXT: .functype maxnum_intrinsic_v4f32 (v128, v128) -> (v128){{$}} 1164; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $0, $1{{$}} 1165; SIMD128-NEXT: return $pop[[R]]{{$}} 1166declare <4 x float> @llvm.maxnum.v4f32(<4 x float>, <4 x float>) 1167define <4 x float> @maxnum_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) { 1168 %a = call nnan <4 x float> @llvm.maxnum.v4f32(<4 x float> %x, <4 x float> %y) 1169 ret <4 x float> %a 1170} 1171 1172; CHECK-LABEL: min_const_intrinsic_v4f32: 1173; NO-SIMD128-NOT: f32x4 1174; SIMD128-NEXT: .functype min_const_intrinsic_v4f32 () -> (v128){{$}} 1175; SIMD128-NEXT: f32.const $push[[L:[0-9]+]]=, 0x1.4p2{{$}} 1176; SIMD128-NEXT: f32x4.splat $push[[R:[0-9]+]]=, $pop[[L]]{{$}} 1177; SIMD128-NEXT: return $pop[[R]]{{$}} 1178define <4 x float> @min_const_intrinsic_v4f32() { 1179 %a = call <4 x float> @llvm.minimum.v4f32( 1180 <4 x float> <float 42., float 42., float 42., float 42.>, 1181 <4 x float> <float 5., float 5., float 5., float 5.> 1182 ) 1183 ret <4 x float> %a 1184} 1185 1186; CHECK-LABEL: max_const_intrinsic_v4f32: 1187; NO-SIMD128-NOT: f32x4 1188; SIMD128-NEXT: .functype max_const_intrinsic_v4f32 () -> (v128){{$}} 1189; SIMD128-NEXT: f32.const $push[[L:[0-9]+]]=, 0x1.5p5{{$}} 1190; SIMD128-NEXT: f32x4.splat $push[[R:[0-9]+]]=, $pop[[L]]{{$}} 1191; SIMD128-NEXT: return $pop[[R]]{{$}} 1192define <4 x float> @max_const_intrinsic_v4f32() { 1193 %a = call <4 x float> @llvm.maximum.v4f32( 1194 <4 x float> <float 42., float 42., float 42., float 42.>, 1195 <4 x float> <float 5., float 5., float 5., float 5.> 1196 ) 1197 ret <4 x float> %a 1198} 1199 1200; CHECK-LABEL: add_v4f32: 1201; NO-SIMD128-NOT: f32x4 1202; SIMD128-NEXT: .functype add_v4f32 (v128, v128) -> (v128){{$}} 1203; SIMD128-NEXT: f32x4.add $push[[R:[0-9]+]]=, $0, $1{{$}} 1204; SIMD128-NEXT: return $pop[[R]]{{$}} 1205define <4 x float> @add_v4f32(<4 x float> %x, <4 x float> %y) { 1206 %a = fadd <4 x float> %x, %y 1207 ret <4 x float> %a 1208} 1209 1210; CHECK-LABEL: sub_v4f32: 1211; NO-SIMD128-NOT: f32x4 1212; SIMD128-NEXT: .functype sub_v4f32 (v128, v128) -> (v128){{$}} 1213; SIMD128-NEXT: f32x4.sub $push[[R:[0-9]+]]=, $0, $1{{$}} 1214; SIMD128-NEXT: return $pop[[R]]{{$}} 1215define <4 x float> @sub_v4f32(<4 x float> %x, <4 x float> %y) { 1216 %a = fsub <4 x float> %x, %y 1217 ret <4 x float> %a 1218} 1219 1220; CHECK-LABEL: div_v4f32: 1221; NO-SIMD128-NOT: f32x4 1222; SIMD128-VM-NOT: f32x4.div 1223; SIMD128-NEXT: .functype div_v4f32 (v128, v128) -> (v128){{$}} 1224; SIMD128-NEXT: f32x4.div $push[[R:[0-9]+]]=, $0, $1{{$}} 1225; SIMD128-NEXT: return $pop[[R]]{{$}} 1226define <4 x float> @div_v4f32(<4 x float> %x, <4 x float> %y) { 1227 %a = fdiv <4 x float> %x, %y 1228 ret <4 x float> %a 1229} 1230 1231; CHECK-LABEL: mul_v4f32: 1232; NO-SIMD128-NOT: f32x4 1233; SIMD128-NEXT: .functype mul_v4f32 (v128, v128) -> (v128){{$}} 1234; SIMD128-NEXT: f32x4.mul $push[[R:[0-9]+]]=, $0, $1{{$}} 1235; SIMD128-NEXT: return $pop[[R]]{{$}} 1236define <4 x float> @mul_v4f32(<4 x float> %x, <4 x float> %y) { 1237 %a = fmul <4 x float> %x, %y 1238 ret <4 x float> %a 1239} 1240 1241; CHECK-LABEL: sqrt_v4f32: 1242; NO-SIMD128-NOT: f32x4 1243; SIMD128-VM-NOT: f32x4.sqrt 1244; SIMD128-NEXT: .functype sqrt_v4f32 (v128) -> (v128){{$}} 1245; SIMD128-NEXT: f32x4.sqrt $push[[R:[0-9]+]]=, $0{{$}} 1246; SIMD128-NEXT: return $pop[[R]]{{$}} 1247declare <4 x float> @llvm.sqrt.v4f32(<4 x float> %x) 1248define <4 x float> @sqrt_v4f32(<4 x float> %x) { 1249 %a = call <4 x float> @llvm.sqrt.v4f32(<4 x float> %x) 1250 ret <4 x float> %a 1251} 1252 1253; ============================================================================== 1254; 2 x double 1255; ============================================================================== 1256; CHECK-LABEL: neg_v2f64: 1257; NO-SIMD128-NOT: f64x2 1258; SIMD128-NEXT: .functype neg_v2f64 (v128) -> (v128){{$}} 1259; SIMD128-NEXT: f64x2.neg $push[[R:[0-9]+]]=, $0{{$}} 1260; SIMD128-NEXT: return $pop[[R]]{{$}} 1261define <2 x double> @neg_v2f64(<2 x double> %x) { 1262 ; nsz makes this semantically equivalent to flipping sign bit 1263 %a = fsub nsz <2 x double> <double 0., double 0.>, %x 1264 ret <2 x double> %a 1265} 1266 1267; CHECK-LABEL: abs_v2f64: 1268; NO-SIMD128-NOT: f64x2 1269; SIMD128-NEXT: .functype abs_v2f64 (v128) -> (v128){{$}} 1270; SIMD128-NEXT: f64x2.abs $push[[R:[0-9]+]]=, $0{{$}} 1271; SIMD128-NEXT: return $pop[[R]]{{$}} 1272declare <2 x double> @llvm.fabs.v2f64(<2 x double>) nounwind readnone 1273define <2 x double> @abs_v2f64(<2 x double> %x) { 1274 %a = call <2 x double> @llvm.fabs.v2f64(<2 x double> %x) 1275 ret <2 x double> %a 1276} 1277 1278; CHECK-LABEL: min_unordered_v2f64: 1279; NO-SIMD128-NOT: f64x2 1280; SIMD128-NEXT: .functype min_unordered_v2f64 (v128) -> (v128){{$}} 1281; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2 1282; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 1283; SIMD128-NEXT: f64x2.min $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 1284; SIMD128-NEXT: return $pop[[R]]{{$}} 1285define <2 x double> @min_unordered_v2f64(<2 x double> %x) { 1286 %cmps = fcmp ule <2 x double> %x, <double 5., double 5.> 1287 %a = select <2 x i1> %cmps, <2 x double> %x, 1288 <2 x double> <double 5., double 5.> 1289 ret <2 x double> %a 1290} 1291 1292; CHECK-LABEL: max_unordered_v2f64: 1293; NO-SIMD128-NOT: f64x2 1294; SIMD128-NEXT: .functype max_unordered_v2f64 (v128) -> (v128){{$}} 1295; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2 1296; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 1297; SIMD128-NEXT: f64x2.max $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 1298; SIMD128-NEXT: return $pop[[R]]{{$}} 1299define <2 x double> @max_unordered_v2f64(<2 x double> %x) { 1300 %cmps = fcmp uge <2 x double> %x, <double 5., double 5.> 1301 %a = select <2 x i1> %cmps, <2 x double> %x, 1302 <2 x double> <double 5., double 5.> 1303 ret <2 x double> %a 1304} 1305 1306; CHECK-LABEL: min_ordered_v2f64: 1307; NO-SIMD128-NOT: f64x2 1308; SIMD128-NEXT: .functype min_ordered_v2f64 (v128) -> (v128){{$}} 1309; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2 1310; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 1311; SIMD128-NEXT: f64x2.min $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 1312; SIMD128-NEXT: return $pop[[R]]{{$}} 1313define <2 x double> @min_ordered_v2f64(<2 x double> %x) { 1314 %cmps = fcmp ole <2 x double> <double 5., double 5.>, %x 1315 %a = select <2 x i1> %cmps, <2 x double> <double 5., double 5.>, 1316 <2 x double> %x 1317 ret <2 x double> %a 1318} 1319 1320; CHECK-LABEL: max_ordered_v2f64: 1321; NO-SIMD128-NOT: f64x2 1322; SIMD128-NEXT: .functype max_ordered_v2f64 (v128) -> (v128){{$}} 1323; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2 1324; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 1325; SIMD128-NEXT: f64x2.max $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 1326; SIMD128-NEXT: return $pop[[R]]{{$}} 1327define <2 x double> @max_ordered_v2f64(<2 x double> %x) { 1328 %cmps = fcmp oge <2 x double> <double 5., double 5.>, %x 1329 %a = select <2 x i1> %cmps, <2 x double> <double 5., double 5.>, 1330 <2 x double> %x 1331 ret <2 x double> %a 1332} 1333 1334; CHECK-LABEL: min_intrinsic_v2f64: 1335; NO-SIMD128-NOT: f64x2 1336; SIMD128-NEXT: .functype min_intrinsic_v2f64 (v128, v128) -> (v128){{$}} 1337; SIMD128-NEXT: f64x2.min $push[[R:[0-9]+]]=, $0, $1{{$}} 1338; SIMD128-NEXT: return $pop[[R]]{{$}} 1339declare <2 x double> @llvm.minimum.v2f64(<2 x double>, <2 x double>) 1340define <2 x double> @min_intrinsic_v2f64(<2 x double> %x, <2 x double> %y) { 1341 %a = call <2 x double> @llvm.minimum.v2f64(<2 x double> %x, <2 x double> %y) 1342 ret <2 x double> %a 1343} 1344 1345; CHECK-LABEL: max_intrinsic_v2f64: 1346; NO-SIMD128-NOT: f64x2 1347; SIMD128-NEXT: .functype max_intrinsic_v2f64 (v128, v128) -> (v128){{$}} 1348; SIMD128-NEXT: f64x2.max $push[[R:[0-9]+]]=, $0, $1{{$}} 1349; SIMD128-NEXT: return $pop[[R]]{{$}} 1350declare <2 x double> @llvm.maximum.v2f64(<2 x double>, <2 x double>) 1351define <2 x double> @max_intrinsic_v2f64(<2 x double> %x, <2 x double> %y) { 1352 %a = call <2 x double> @llvm.maximum.v2f64(<2 x double> %x, <2 x double> %y) 1353 ret <2 x double> %a 1354} 1355 1356; CHECK-LABEL: min_const_intrinsic_v2f64: 1357; NO-SIMD128-NOT: f64x2 1358; SIMD128-NEXT: .functype min_const_intrinsic_v2f64 () -> (v128){{$}} 1359; SIMD128-NEXT: f64.const $push[[L:[0-9]+]]=, 0x1.4p2{{$}} 1360; SIMD128-NEXT: f64x2.splat $push[[R:[0-9]+]]=, $pop[[L]]{{$}} 1361; SIMD128-NEXT: return $pop[[R]]{{$}} 1362define <2 x double> @min_const_intrinsic_v2f64() { 1363 %a = call <2 x double> @llvm.minimum.v2f64( 1364 <2 x double> <double 42., double 42.>, 1365 <2 x double> <double 5., double 5.> 1366 ) 1367 ret <2 x double> %a 1368} 1369 1370; CHECK-LABEL: max_const_intrinsic_v2f64: 1371; NO-SIMD128-NOT: f64x2 1372; SIMD128-NEXT: .functype max_const_intrinsic_v2f64 () -> (v128){{$}} 1373; SIMD128-NEXT: f64.const $push[[L:[0-9]+]]=, 0x1.5p5{{$}} 1374; SIMD128-NEXT: f64x2.splat $push[[R:[0-9]+]]=, $pop[[L]]{{$}} 1375; SIMD128-NEXT: return $pop[[R]]{{$}} 1376define <2 x double> @max_const_intrinsic_v2f64() { 1377 %a = call <2 x double> @llvm.maximum.v2f64( 1378 <2 x double> <double 42., double 42.>, 1379 <2 x double> <double 5., double 5.> 1380 ) 1381 ret <2 x double> %a 1382} 1383 1384; CHECK-LABEL: add_v2f64: 1385; NO-SIMD128-NOT: f64x2 1386; SIMD128-VM-NOT: f62x2 1387; SIMD128-NEXT: .functype add_v2f64 (v128, v128) -> (v128){{$}} 1388; SIMD128-NEXT: f64x2.add $push[[R:[0-9]+]]=, $0, $1{{$}} 1389; SIMD128-NEXT: return $pop[[R]]{{$}} 1390define <2 x double> @add_v2f64(<2 x double> %x, <2 x double> %y) { 1391 %a = fadd <2 x double> %x, %y 1392 ret <2 x double> %a 1393} 1394 1395; CHECK-LABEL: sub_v2f64: 1396; NO-SIMD128-NOT: f64x2 1397; SIMD128-VM-NOT: f62x2 1398; SIMD128-NEXT: .functype sub_v2f64 (v128, v128) -> (v128){{$}} 1399; SIMD128-NEXT: f64x2.sub $push[[R:[0-9]+]]=, $0, $1{{$}} 1400; SIMD128-NEXT: return $pop[[R]]{{$}} 1401define <2 x double> @sub_v2f64(<2 x double> %x, <2 x double> %y) { 1402 %a = fsub <2 x double> %x, %y 1403 ret <2 x double> %a 1404} 1405 1406; CHECK-LABEL: div_v2f64: 1407; NO-SIMD128-NOT: f64x2 1408; SIMD128-VM-NOT: f62x2 1409; SIMD128-NEXT: .functype div_v2f64 (v128, v128) -> (v128){{$}} 1410; SIMD128-NEXT: f64x2.div $push[[R:[0-9]+]]=, $0, $1{{$}} 1411; SIMD128-NEXT: return $pop[[R]]{{$}} 1412define <2 x double> @div_v2f64(<2 x double> %x, <2 x double> %y) { 1413 %a = fdiv <2 x double> %x, %y 1414 ret <2 x double> %a 1415} 1416 1417; CHECK-LABEL: mul_v2f64: 1418; NO-SIMD128-NOT: f64x2 1419; SIMD128-VM-NOT: f62x2 1420; SIMD128-NEXT: .functype mul_v2f64 (v128, v128) -> (v128){{$}} 1421; SIMD128-NEXT: f64x2.mul $push[[R:[0-9]+]]=, $0, $1{{$}} 1422; SIMD128-NEXT: return $pop[[R]]{{$}} 1423define <2 x double> @mul_v2f64(<2 x double> %x, <2 x double> %y) { 1424 %a = fmul <2 x double> %x, %y 1425 ret <2 x double> %a 1426} 1427 1428; CHECK-LABEL: sqrt_v2f64: 1429; NO-SIMD128-NOT: f64x2 1430; SIMD128-NEXT: .functype sqrt_v2f64 (v128) -> (v128){{$}} 1431; SIMD128-NEXT: f64x2.sqrt $push[[R:[0-9]+]]=, $0{{$}} 1432; SIMD128-NEXT: return $pop[[R]]{{$}} 1433declare <2 x double> @llvm.sqrt.v2f64(<2 x double> %x) 1434define <2 x double> @sqrt_v2f64(<2 x double> %x) { 1435 %a = call <2 x double> @llvm.sqrt.v2f64(<2 x double> %x) 1436 ret <2 x double> %a 1437} 1438