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: bitselect_v16i8: 227; NO-SIMD128-NOT: v128 228; SIMD128-NEXT: .functype bitselect_v16i8 (v128, v128, v128) -> (v128){{$}} 229; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}} 230; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}} 231; SIMD128-FAST-NEXT: v128.and 232; SIMD128-FAST-NEXT: v128.not 233; SIMD128-FAST-NEXT: v128.and 234; SIMD128-FAST-NEXT: v128.or 235; SIMD128-FAST-NEXT: return 236define <16 x i8> @bitselect_v16i8(<16 x i8> %c, <16 x i8> %v1, <16 x i8> %v2) { 237 %masked_v1 = and <16 x i8> %c, %v1 238 %inv_mask = xor <16 x i8> %c, 239 <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, 240 i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> 241 %masked_v2 = and <16 x i8> %inv_mask, %v2 242 %a = or <16 x i8> %masked_v1, %masked_v2 243 ret <16 x i8> %a 244} 245 246; ============================================================================== 247; 8 x i16 248; ============================================================================== 249; CHECK-LABEL: add_v8i16: 250; NO-SIMD128-NOT: i16x8 251; SIMD128-NEXT: .functype add_v8i16 (v128, v128) -> (v128){{$}} 252; SIMD128-NEXT: i16x8.add $push[[R:[0-9]+]]=, $0, $1{{$}} 253; SIMD128-NEXT: return $pop[[R]]{{$}} 254define <8 x i16> @add_v8i16(<8 x i16> %x, <8 x i16> %y) { 255 %a = add <8 x i16> %x, %y 256 ret <8 x i16> %a 257} 258 259; CHECK-LABEL: sub_v8i16: 260; NO-SIMD128-NOT: i16x8 261; SIMD128-NEXT: .functype sub_v8i16 (v128, v128) -> (v128){{$}} 262; SIMD128-NEXT: i16x8.sub $push[[R:[0-9]+]]=, $0, $1{{$}} 263; SIMD128-NEXT: return $pop[[R]]{{$}} 264define <8 x i16> @sub_v8i16(<8 x i16> %x, <8 x i16> %y) { 265 %a = sub <8 x i16> %x, %y 266 ret <8 x i16> %a 267} 268 269; CHECK-LABEL: mul_v8i16: 270; NO-SIMD128-NOT: i16x8 271; SIMD128-NEXT: .functype mul_v8i16 (v128, v128) -> (v128){{$}} 272; SIMD128-NEXT: i16x8.mul $push[[R:[0-9]+]]=, $0, $1{{$}} 273; SIMD128-NEXT: return $pop[[R]]{{$}} 274define <8 x i16> @mul_v8i16(<8 x i16> %x, <8 x i16> %y) { 275 %a = mul <8 x i16> %x, %y 276 ret <8 x i16> %a 277} 278 279; CHECK-LABEL: neg_v8i16: 280; NO-SIMD128-NOT: i16x8 281; SIMD128-NEXT: .functype neg_v8i16 (v128) -> (v128){{$}} 282; SIMD128-NEXT: i16x8.neg $push[[R:[0-9]+]]=, $0{{$}} 283; SIMD128-NEXT: return $pop[[R]]{{$}} 284define <8 x i16> @neg_v8i16(<8 x i16> %x) { 285 %a = sub <8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>, 286 %x 287 ret <8 x i16> %a 288} 289 290; CHECK-LABEL: shl_v8i16: 291; NO-SIMD128-NOT: i16x8 292; SIMD128-NEXT: .functype shl_v8i16 (v128, i32) -> (v128){{$}} 293; SIMD128-NEXT: i16x8.shl $push[[R:[0-9]+]]=, $0, $1{{$}} 294; SIMD128-NEXT: return $pop[[R]]{{$}} 295define <8 x i16> @shl_v8i16(<8 x i16> %v, i16 %x) { 296 %t = insertelement <8 x i16> undef, i16 %x, i32 0 297 %s = shufflevector <8 x i16> %t, <8 x i16> undef, 298 <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 299 %a = shl <8 x i16> %v, %s 300 ret <8 x i16> %a 301} 302 303; CHECK-LABEL: shl_const_v8i16: 304; NO-SIMD128-NOT: i16x8 305; SIMD128-NEXT: .functype shl_const_v8i16 (v128) -> (v128){{$}} 306; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5 307; SIMD128-NEXT: i16x8.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 308; SIMD128-NEXT: return $pop[[R]]{{$}} 309define <8 x i16> @shl_const_v8i16(<8 x i16> %v) { 310 %a = shl <8 x i16> %v, 311 <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5> 312 ret <8 x i16> %a 313} 314 315; CHECK-LABEL: shl_vec_v8i16: 316; NO-SIMD128-NOT: i16x8 317; SIMD128-NEXT: .functype shl_vec_v8i16 (v128, v128) -> (v128){{$}} 318; SIMD128-NEXT: i16x8.extract_lane_s $push[[L0:[0-9]+]]=, $0, 0{{$}} 319; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 15{{$}} 320; SIMD128-NEXT: i16x8.splat $push[[M1:[0-9]+]]=, $pop[[M0]]{{$}} 321; SIMD128-NEXT: v128.and $push[[M2:[0-9]+]]=, $1, $pop[[M1]]{{$}} 322; SIMD128-NEXT: local.tee $push[[M:[0-9]+]]=, $1=, $pop[[M2]]{{$}} 323; SIMD128-NEXT: i16x8.extract_lane_u $push[[L1:[0-9]+]]=, $pop[[M]], 0{{$}} 324; SIMD128-NEXT: i32.shl $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 325; SIMD128-NEXT: i16x8.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 326; Skip 6 lanes 327; SIMD128: i16x8.extract_lane_s $push[[L4:[0-9]+]]=, $0, 7{{$}} 328; SIMD128-NEXT: i16x8.extract_lane_u $push[[L5:[0-9]+]]=, $1, 7{{$}} 329; SIMD128-NEXT: i32.shl $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 330; SIMD128-NEXT: i16x8.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 7, $pop[[L6]]{{$}} 331; SIMD128-NEXT: return $pop[[R]]{{$}} 332define <8 x i16> @shl_vec_v8i16(<8 x i16> %v, <8 x i16> %x) { 333 %a = shl <8 x i16> %v, %x 334 ret <8 x i16> %a 335} 336 337; CHECK-LABEL: shr_s_v8i16: 338; NO-SIMD128-NOT: i16x8 339; SIMD128-NEXT: .functype shr_s_v8i16 (v128, i32) -> (v128){{$}} 340; SIMD128-NEXT: i16x8.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}} 341; SIMD128-NEXT: return $pop[[R]]{{$}} 342define <8 x i16> @shr_s_v8i16(<8 x i16> %v, i16 %x) { 343 %t = insertelement <8 x i16> undef, i16 %x, i32 0 344 %s = shufflevector <8 x i16> %t, <8 x i16> undef, 345 <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 346 %a = ashr <8 x i16> %v, %s 347 ret <8 x i16> %a 348} 349 350; CHECK-LABEL: shr_s_vec_v8i16: 351; NO-SIMD128-NOT: i16x8 352; SIMD128-NEXT: .functype shr_s_vec_v8i16 (v128, v128) -> (v128){{$}} 353; SIMD128-NEXT: i16x8.extract_lane_s $push[[L0:[0-9]+]]=, $0, 0{{$}} 354; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 15{{$}} 355; SIMD128-NEXT: i16x8.splat $push[[M1:[0-9]+]]=, $pop[[M0]]{{$}} 356; SIMD128-NEXT: v128.and $push[[M2:[0-9]+]]=, $1, $pop[[M1]]{{$}} 357; SIMD128-NEXT: local.tee $push[[M:[0-9]+]]=, $1=, $pop[[M2]]{{$}} 358; SIMD128-NEXT: i16x8.extract_lane_u $push[[L1:[0-9]+]]=, $pop[[M]], 0{{$}} 359; SIMD128-NEXT: i32.shr_s $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 360; SIMD128-NEXT: i16x8.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 361; Skip 6 lanes 362; SIMD128: i16x8.extract_lane_s $push[[L0:[0-9]+]]=, $0, 7{{$}} 363; SIMD128-NEXT: i16x8.extract_lane_u $push[[L1:[0-9]+]]=, $1, 7{{$}} 364; SIMD128-NEXT: i32.shr_s $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 365; SIMD128-NEXT: i16x8.replace_lane $push[[R:[0-9]+]]=, $pop{{[0-9]+}}, 7, $pop[[L2]]{{$}} 366; SIMD128-NEXT: return $pop[[R]]{{$}} 367define <8 x i16> @shr_s_vec_v8i16(<8 x i16> %v, <8 x i16> %x) { 368 %a = ashr <8 x i16> %v, %x 369 ret <8 x i16> %a 370} 371 372; CHECK-LABEL: shr_u_v8i16: 373; NO-SIMD128-NOT: i16x8 374; SIMD128-NEXT: .functype shr_u_v8i16 (v128, i32) -> (v128){{$}} 375; SIMD128-NEXT: i16x8.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}} 376; SIMD128-NEXT: return $pop[[R]]{{$}} 377define <8 x i16> @shr_u_v8i16(<8 x i16> %v, i16 %x) { 378 %t = insertelement <8 x i16> undef, i16 %x, i32 0 379 %s = shufflevector <8 x i16> %t, <8 x i16> undef, 380 <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 381 %a = lshr <8 x i16> %v, %s 382 ret <8 x i16> %a 383} 384 385; CHECK-LABEL: shr_u_vec_v8i16: 386; NO-SIMD128-NOT: i16x8 387; SIMD128-NEXT: .functype shr_u_vec_v8i16 (v128, v128) -> (v128){{$}} 388; SIMD128-NEXT: i16x8.extract_lane_u $push[[L0:[0-9]+]]=, $0, 0{{$}} 389; SIMD128-NEXT: i32.const $push[[M0:[0-9]+]]=, 15{{$}} 390; SIMD128-NEXT: i16x8.splat $push[[M1:[0-9]+]]=, $pop[[M0]]{{$}} 391; SIMD128-NEXT: v128.and $push[[M2:[0-9]+]]=, $1, $pop[[M1]]{{$}} 392; SIMD128-NEXT: local.tee $push[[M:[0-9]+]]=, $1=, $pop[[M2]]{{$}} 393; SIMD128-NEXT: i16x8.extract_lane_u $push[[L1:[0-9]+]]=, $pop[[M]], 0{{$}} 394; SIMD128-NEXT: i32.shr_u $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 395; SIMD128-NEXT: i16x8.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 396; Skip 6 lanes 397; SIMD128: i16x8.extract_lane_u $push[[L4:[0-9]+]]=, $0, 7{{$}} 398; SIMD128-NEXT: i16x8.extract_lane_u $push[[L5:[0-9]+]]=, $1, 7{{$}} 399; SIMD128-NEXT: i32.shr_u $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 400; SIMD128-NEXT: i16x8.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 7, $pop[[L6]]{{$}} 401; SIMD128-NEXT: return $pop[[R]]{{$}} 402define <8 x i16> @shr_u_vec_v8i16(<8 x i16> %v, <8 x i16> %x) { 403 %a = lshr <8 x i16> %v, %x 404 ret <8 x i16> %a 405} 406 407; CHECK-LABEL: and_v8i16: 408; NO-SIMD128-NOT: v128 409; SIMD128-NEXT: .functype and_v8i16 (v128, v128) -> (v128){{$}} 410; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}} 411; SIMD128-NEXT: return $pop[[R]]{{$}} 412define <8 x i16> @and_v8i16(<8 x i16> %x, <8 x i16> %y) { 413 %a = and <8 x i16> %x, %y 414 ret <8 x i16> %a 415} 416 417; CHECK-LABEL: or_v8i16: 418; NO-SIMD128-NOT: v128 419; SIMD128-NEXT: .functype or_v8i16 (v128, v128) -> (v128){{$}} 420; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}} 421; SIMD128-NEXT: return $pop[[R]]{{$}} 422define <8 x i16> @or_v8i16(<8 x i16> %x, <8 x i16> %y) { 423 %a = or <8 x i16> %x, %y 424 ret <8 x i16> %a 425} 426 427; CHECK-LABEL: xor_v8i16: 428; NO-SIMD128-NOT: v128 429; SIMD128-NEXT: .functype xor_v8i16 (v128, v128) -> (v128){{$}} 430; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}} 431; SIMD128-NEXT: return $pop[[R]]{{$}} 432define <8 x i16> @xor_v8i16(<8 x i16> %x, <8 x i16> %y) { 433 %a = xor <8 x i16> %x, %y 434 ret <8 x i16> %a 435} 436 437; CHECK-LABEL: not_v8i16: 438; NO-SIMD128-NOT: v128 439; SIMD128-NEXT: .functype not_v8i16 (v128) -> (v128){{$}} 440; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}} 441; SIMD128-NEXT: return $pop[[R]]{{$}} 442define <8 x i16> @not_v8i16(<8 x i16> %x) { 443 %a = xor <8 x i16> %x, <i16 -1, i16 -1, i16 -1, i16 -1, 444 i16 -1, i16 -1, i16 -1, i16 -1> 445 ret <8 x i16> %a 446} 447 448; CHECK-LABEL: bitselect_v8i16: 449; NO-SIMD128-NOT: v128 450; SIMD128-NEXT: .functype bitselect_v8i16 (v128, v128, v128) -> (v128){{$}} 451; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}} 452; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}} 453; SIMD128-FAST-NEXT: v128.and 454; SIMD128-FAST-NEXT: v128.not 455; SIMD128-FAST-NEXT: v128.and 456; SIMD128-FAST-NEXT: v128.or 457; SIMD128-FAST-NEXT: return 458define <8 x i16> @bitselect_v8i16(<8 x i16> %c, <8 x i16> %v1, <8 x i16> %v2) { 459 %masked_v1 = and <8 x i16> %v1, %c 460 %inv_mask = xor <8 x i16> 461 <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>, 462 %c 463 %masked_v2 = and <8 x i16> %v2, %inv_mask 464 %a = or <8 x i16> %masked_v1, %masked_v2 465 ret <8 x i16> %a 466} 467 468; ============================================================================== 469; 4 x i32 470; ============================================================================== 471; CHECK-LABEL: add_v4i32: 472; NO-SIMD128-NOT: i32x4 473; SIMD128-NEXT: .functype add_v4i32 (v128, v128) -> (v128){{$}} 474; SIMD128-NEXT: i32x4.add $push[[R:[0-9]+]]=, $0, $1{{$}} 475; SIMD128-NEXT: return $pop[[R]]{{$}} 476define <4 x i32> @add_v4i32(<4 x i32> %x, <4 x i32> %y) { 477 %a = add <4 x i32> %x, %y 478 ret <4 x i32> %a 479} 480 481; CHECK-LABEL: sub_v4i32: 482; NO-SIMD128-NOT: i32x4 483; SIMD128-NEXT: .functype sub_v4i32 (v128, v128) -> (v128){{$}} 484; SIMD128-NEXT: i32x4.sub $push[[R:[0-9]+]]=, $0, $1{{$}} 485; SIMD128-NEXT: return $pop[[R]]{{$}} 486define <4 x i32> @sub_v4i32(<4 x i32> %x, <4 x i32> %y) { 487 %a = sub <4 x i32> %x, %y 488 ret <4 x i32> %a 489} 490 491; CHECK-LABEL: mul_v4i32: 492; NO-SIMD128-NOT: i32x4 493; SIMD128-NEXT: .functype mul_v4i32 (v128, v128) -> (v128){{$}} 494; SIMD128-NEXT: i32x4.mul $push[[R:[0-9]+]]=, $0, $1{{$}} 495; SIMD128-NEXT: return $pop[[R]]{{$}} 496define <4 x i32> @mul_v4i32(<4 x i32> %x, <4 x i32> %y) { 497 %a = mul <4 x i32> %x, %y 498 ret <4 x i32> %a 499} 500 501; CHECK-LABEL: neg_v4i32: 502; NO-SIMD128-NOT: i32x4 503; SIMD128-NEXT: .functype neg_v4i32 (v128) -> (v128){{$}} 504; SIMD128-NEXT: i32x4.neg $push[[R:[0-9]+]]=, $0{{$}} 505; SIMD128-NEXT: return $pop[[R]]{{$}} 506define <4 x i32> @neg_v4i32(<4 x i32> %x) { 507 %a = sub <4 x i32> <i32 0, i32 0, i32 0, i32 0>, %x 508 ret <4 x i32> %a 509} 510 511; CHECK-LABEL: shl_v4i32: 512; NO-SIMD128-NOT: i32x4 513; SIMD128-NEXT: .functype shl_v4i32 (v128, i32) -> (v128){{$}} 514; SIMD128-NEXT: i32x4.shl $push[[R:[0-9]+]]=, $0, $1{{$}} 515; SIMD128-NEXT: return $pop[[R]]{{$}} 516define <4 x i32> @shl_v4i32(<4 x i32> %v, i32 %x) { 517 %t = insertelement <4 x i32> undef, i32 %x, i32 0 518 %s = shufflevector <4 x i32> %t, <4 x i32> undef, 519 <4 x i32> <i32 0, i32 0, i32 0, i32 0> 520 %a = shl <4 x i32> %v, %s 521 ret <4 x i32> %a 522} 523 524; CHECK-LABEL: shl_const_v4i32: 525; NO-SIMD128-NOT: i32x4 526; SIMD128-NEXT: .functype shl_const_v4i32 (v128) -> (v128){{$}} 527; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5 528; SIMD128-NEXT: i32x4.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 529; SIMD128-NEXT: return $pop[[R]]{{$}} 530define <4 x i32> @shl_const_v4i32(<4 x i32> %v) { 531 %a = shl <4 x i32> %v, <i32 5, i32 5, i32 5, i32 5> 532 ret <4 x i32> %a 533} 534 535; CHECK-LABEL: shl_vec_v4i32: 536; NO-SIMD128-NOT: i32x4 537; SIMD128-NEXT: .functype shl_vec_v4i32 (v128, v128) -> (v128){{$}} 538; SIMD128-NEXT: i32x4.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}} 539; SIMD128-NEXT: i32x4.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}} 540; SIMD128-NEXT: i32.shl $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 541; SIMD128-NEXT: i32x4.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 542; Skip 2 lanes 543; SIMD128: i32x4.extract_lane $push[[L4:[0-9]+]]=, $0, 3{{$}} 544; SIMD128-NEXT: i32x4.extract_lane $push[[L5:[0-9]+]]=, $1, 3{{$}} 545; SIMD128-NEXT: i32.shl $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 546; SIMD128-NEXT: i32x4.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 3, $pop[[L6]]{{$}} 547; SIMD128-NEXT: return $pop[[R]]{{$}} 548define <4 x i32> @shl_vec_v4i32(<4 x i32> %v, <4 x i32> %x) { 549 %a = shl <4 x i32> %v, %x 550 ret <4 x i32> %a 551} 552 553; CHECK-LABEL: shr_s_v4i32: 554; NO-SIMD128-NOT: i32x4 555; SIMD128-NEXT: .functype shr_s_v4i32 (v128, i32) -> (v128){{$}} 556; SIMD128-NEXT: i32x4.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}} 557; SIMD128-NEXT: return $pop[[R]]{{$}} 558define <4 x i32> @shr_s_v4i32(<4 x i32> %v, i32 %x) { 559 %t = insertelement <4 x i32> undef, i32 %x, i32 0 560 %s = shufflevector <4 x i32> %t, <4 x i32> undef, 561 <4 x i32> <i32 0, i32 0, i32 0, i32 0> 562 %a = ashr <4 x i32> %v, %s 563 ret <4 x i32> %a 564} 565 566; CHECK-LABEL: shr_s_vec_v4i32: 567; NO-SIMD128-NOT: i32x4 568; SIMD128-NEXT: .functype shr_s_vec_v4i32 (v128, v128) -> (v128){{$}} 569; SIMD128-NEXT: i32x4.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}} 570; SIMD128-NEXT: i32x4.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}} 571; SIMD128-NEXT: i32.shr_s $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 572; SIMD128-NEXT: i32x4.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 573; Skip 2 lanes 574; SIMD128: i32x4.extract_lane $push[[L4:[0-9]+]]=, $0, 3{{$}} 575; SIMD128-NEXT: i32x4.extract_lane $push[[L5:[0-9]+]]=, $1, 3{{$}} 576; SIMD128-NEXT: i32.shr_s $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 577; SIMD128-NEXT: i32x4.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 3, $pop[[L6]]{{$}} 578; SIMD128-NEXT: return $pop[[R]]{{$}} 579define <4 x i32> @shr_s_vec_v4i32(<4 x i32> %v, <4 x i32> %x) { 580 %a = ashr <4 x i32> %v, %x 581 ret <4 x i32> %a 582} 583 584; CHECK-LABEL: shr_u_v4i32: 585; NO-SIMD128-NOT: i32x4 586; SIMD128-NEXT: .functype shr_u_v4i32 (v128, i32) -> (v128){{$}} 587; SIMD128-NEXT: i32x4.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}} 588; SIMD128-NEXT: return $pop[[R]]{{$}} 589define <4 x i32> @shr_u_v4i32(<4 x i32> %v, i32 %x) { 590 %t = insertelement <4 x i32> undef, i32 %x, i32 0 591 %s = shufflevector <4 x i32> %t, <4 x i32> undef, 592 <4 x i32> <i32 0, i32 0, i32 0, i32 0> 593 %a = lshr <4 x i32> %v, %s 594 ret <4 x i32> %a 595} 596 597; CHECK-LABEL: shr_u_vec_v4i32: 598; NO-SIMD128-NOT: i32x4 599; SIMD128-NEXT: .functype shr_u_vec_v4i32 (v128, v128) -> (v128){{$}} 600; SIMD128-NEXT: i32x4.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}} 601; SIMD128-NEXT: i32x4.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}} 602; SIMD128-NEXT: i32.shr_u $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 603; SIMD128-NEXT: i32x4.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 604; Skip 2 lanes 605; SIMD128: i32x4.extract_lane $push[[L4:[0-9]+]]=, $0, 3{{$}} 606; SIMD128-NEXT: i32x4.extract_lane $push[[L5:[0-9]+]]=, $1, 3{{$}} 607; SIMD128-NEXT: i32.shr_u $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 608; SIMD128-NEXT: i32x4.replace_lane $push[[R:[0-9]+]]=, $pop[[L7:[0-9]+]], 3, $pop[[L6]]{{$}} 609; SIMD128-NEXT: return $pop[[R]]{{$}} 610define <4 x i32> @shr_u_vec_v4i32(<4 x i32> %v, <4 x i32> %x) { 611 %a = lshr <4 x i32> %v, %x 612 ret <4 x i32> %a 613} 614 615; CHECK-LABEL: and_v4i32: 616; NO-SIMD128-NOT: v128 617; SIMD128-NEXT: .functype and_v4i32 (v128, v128) -> (v128){{$}} 618; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}} 619; SIMD128-NEXT: return $pop[[R]]{{$}} 620define <4 x i32> @and_v4i32(<4 x i32> %x, <4 x i32> %y) { 621 %a = and <4 x i32> %x, %y 622 ret <4 x i32> %a 623} 624 625; CHECK-LABEL: or_v4i32: 626; NO-SIMD128-NOT: v128 627; SIMD128-NEXT: .functype or_v4i32 (v128, v128) -> (v128){{$}} 628; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}} 629; SIMD128-NEXT: return $pop[[R]]{{$}} 630define <4 x i32> @or_v4i32(<4 x i32> %x, <4 x i32> %y) { 631 %a = or <4 x i32> %x, %y 632 ret <4 x i32> %a 633} 634 635; CHECK-LABEL: xor_v4i32: 636; NO-SIMD128-NOT: v128 637; SIMD128-NEXT: .functype xor_v4i32 (v128, v128) -> (v128){{$}} 638; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}} 639; SIMD128-NEXT: return $pop[[R]]{{$}} 640define <4 x i32> @xor_v4i32(<4 x i32> %x, <4 x i32> %y) { 641 %a = xor <4 x i32> %x, %y 642 ret <4 x i32> %a 643} 644 645; CHECK-LABEL: not_v4i32: 646; NO-SIMD128-NOT: v128 647; SIMD128-NEXT: .functype not_v4i32 (v128) -> (v128){{$}} 648; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}} 649; SIMD128-NEXT: return $pop[[R]]{{$}} 650define <4 x i32> @not_v4i32(<4 x i32> %x) { 651 %a = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1> 652 ret <4 x i32> %a 653} 654 655; CHECK-LABEL: bitselect_v4i32: 656; NO-SIMD128-NOT: v128 657; SIMD128-NEXT: .functype bitselect_v4i32 (v128, v128, v128) -> (v128){{$}} 658; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}} 659; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}} 660; SIMD128-FAST-NEXT: v128.not 661; SIMD128-FAST-NEXT: v128.and 662; SIMD128-FAST-NEXT: v128.and 663; SIMD128-FAST-NEXT: v128.or 664; SIMD128-FAST-NEXT: return 665define <4 x i32> @bitselect_v4i32(<4 x i32> %c, <4 x i32> %v1, <4 x i32> %v2) { 666 %masked_v1 = and <4 x i32> %c, %v1 667 %inv_mask = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %c 668 %masked_v2 = and <4 x i32> %inv_mask, %v2 669 %a = or <4 x i32> %masked_v2, %masked_v1 670 ret <4 x i32> %a 671} 672 673; ============================================================================== 674; 2 x i64 675; ============================================================================== 676; CHECK-LABEL: add_v2i64: 677; NO-SIMD128-NOT: i64x2 678; SIMD128-VM-NOT: i64x2 679; SIMD128-NEXT: .functype add_v2i64 (v128, v128) -> (v128){{$}} 680; SIMD128-NEXT: i64x2.add $push[[R:[0-9]+]]=, $0, $1{{$}} 681; SIMD128-NEXT: return $pop[[R]]{{$}} 682define <2 x i64> @add_v2i64(<2 x i64> %x, <2 x i64> %y) { 683 %a = add <2 x i64> %x, %y 684 ret <2 x i64> %a 685} 686 687; CHECK-LABEL: sub_v2i64: 688; NO-SIMD128-NOT: i64x2 689; SIMD128-VM-NOT: i64x2 690; SIMD128-NEXT: .functype sub_v2i64 (v128, v128) -> (v128){{$}} 691; SIMD128-NEXT: i64x2.sub $push[[R:[0-9]+]]=, $0, $1{{$}} 692; SIMD128-NEXT: return $pop[[R]]{{$}} 693define <2 x i64> @sub_v2i64(<2 x i64> %x, <2 x i64> %y) { 694 %a = sub <2 x i64> %x, %y 695 ret <2 x i64> %a 696} 697 698; v2i64.mul is not in spec 699; CHECK-LABEL: mul_v2i64: 700; NO-SIMD128-NOT: i64x2 701; SIMD128-VM-NOT: i64x2 702; SIMD128-NOT: i64x2.mul 703; SIMD128: i64x2.extract_lane 704; SIMD128: i64.mul 705define <2 x i64> @mul_v2i64(<2 x i64> %x, <2 x i64> %y) { 706 %a = mul <2 x i64> %x, %y 707 ret <2 x i64> %a 708} 709 710; CHECK-LABEL: neg_v2i64: 711; NO-SIMD128-NOT: i64x2 712; SIMD128-NEXT: .functype neg_v2i64 (v128) -> (v128){{$}} 713; SIMD128-NEXT: i64x2.neg $push[[R:[0-9]+]]=, $0{{$}} 714; SIMD128-NEXT: return $pop[[R]]{{$}} 715define <2 x i64> @neg_v2i64(<2 x i64> %x) { 716 %a = sub <2 x i64> <i64 0, i64 0>, %x 717 ret <2 x i64> %a 718} 719 720; CHECK-LABEL: shl_v2i64: 721; NO-SIMD128-NOT: i64x2 722; SIMD128-NEXT: .functype shl_v2i64 (v128, i32) -> (v128){{$}} 723; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $1{{$}} 724; SIMD128-NEXT: return $pop[[R]]{{$}} 725define <2 x i64> @shl_v2i64(<2 x i64> %v, i32 %x) { 726 %x2 = zext i32 %x to i64 727 %t = insertelement <2 x i64> undef, i64 %x2, i32 0 728 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 729 %a = shl <2 x i64> %v, %s 730 ret <2 x i64> %a 731} 732 733; CHECK-LABEL: shl_sext_v2i64: 734; NO-SIMD128-NOT: i64x2 735; SIMD128-NEXT: .functype shl_sext_v2i64 (v128, i32) -> (v128){{$}} 736; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $1{{$}} 737; SIMD128-NEXT: return $pop[[R]]{{$}} 738define <2 x i64> @shl_sext_v2i64(<2 x i64> %v, i32 %x) { 739 %x2 = sext i32 %x to i64 740 %t = insertelement <2 x i64> undef, i64 %x2, i32 0 741 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 742 %a = shl <2 x i64> %v, %s 743 ret <2 x i64> %a 744} 745 746; CHECK-LABEL: shl_noext_v2i64: 747; NO-SIMD128-NOT: i64x2 748; SIMD128-NEXT: .functype shl_noext_v2i64 (v128, i64) -> (v128){{$}} 749; SIMD128-NEXT: i32.wrap_i64 $push[[L0:[0-9]+]]=, $1{{$}} 750; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 751; SIMD128-NEXT: return $pop[[R]]{{$}} 752define <2 x i64> @shl_noext_v2i64(<2 x i64> %v, i64 %x) { 753 %t = insertelement <2 x i64> undef, i64 %x, i32 0 754 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 755 %a = shl <2 x i64> %v, %s 756 ret <2 x i64> %a 757} 758 759; CHECK-LABEL: shl_const_v2i64: 760; NO-SIMD128-NOT: i64x2 761; SIMD128-NEXT: .functype shl_const_v2i64 (v128) -> (v128){{$}} 762; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5{{$}} 763; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 764; SIMD128-NEXT: return $pop[[R]]{{$}} 765define <2 x i64> @shl_const_v2i64(<2 x i64> %v) { 766 %a = shl <2 x i64> %v, <i64 5, i64 5> 767 ret <2 x i64> %a 768} 769 770; CHECK-LABEL: shl_vec_v2i64: 771; NO-SIMD128-NOT: i64x2 772; SIMD128-NEXT: .functype shl_vec_v2i64 (v128, v128) -> (v128){{$}} 773; SIMD128-NEXT: i64x2.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}} 774; SIMD128-NEXT: i64x2.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}} 775; SIMD128-NEXT: i64.shl $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 776; SIMD128-NEXT: i64x2.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 777; SIMD128-NEXT: i64x2.extract_lane $push[[L4:[0-9]+]]=, $0, 1{{$}} 778; SIMD128-NEXT: i64x2.extract_lane $push[[L5:[0-9]+]]=, $1, 1{{$}} 779; SIMD128-NEXT: i64.shl $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 780; SIMD128-NEXT: i64x2.replace_lane $push[[R:[0-9]+]]=, $pop[[L3]], 1, $pop[[L6]]{{$}} 781; SIMD128-NEXT: return $pop[[R]]{{$}} 782define <2 x i64> @shl_vec_v2i64(<2 x i64> %v, <2 x i64> %x) { 783 %a = shl <2 x i64> %v, %x 784 ret <2 x i64> %a 785} 786 787; CHECK-LABEL: shr_s_v2i64: 788; NO-SIMD128-NOT: i64x2 789; SIMD128-NEXT: .functype shr_s_v2i64 (v128, i32) -> (v128){{$}} 790; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}} 791; SIMD128-NEXT: return $pop[[R]]{{$}} 792define <2 x i64> @shr_s_v2i64(<2 x i64> %v, i32 %x) { 793 %x2 = zext i32 %x to i64 794 %t = insertelement <2 x i64> undef, i64 %x2, i32 0 795 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 796 %a = ashr <2 x i64> %v, %s 797 ret <2 x i64> %a 798} 799 800; CHECK-LABEL: shr_s_sext_v2i64: 801; NO-SIMD128-NOT: i64x2 802; SIMD128-NEXT: .functype shr_s_sext_v2i64 (v128, i32) -> (v128){{$}} 803; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}} 804; SIMD128-NEXT: return $pop[[R]]{{$}} 805define <2 x i64> @shr_s_sext_v2i64(<2 x i64> %v, i32 %x) { 806 %x2 = sext i32 %x to i64 807 %t = insertelement <2 x i64> undef, i64 %x2, i32 0 808 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 809 %a = ashr <2 x i64> %v, %s 810 ret <2 x i64> %a 811} 812 813; CHECK-LABEL: shr_s_noext_v2i64: 814; NO-SIMD128-NOT: i64x2 815; SIMD128-NEXT: .functype shr_s_noext_v2i64 (v128, i64) -> (v128){{$}} 816; SIMD128-NEXT: i32.wrap_i64 $push[[L0:[0-9]+]]=, $1{{$}} 817; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 818; SIMD128-NEXT: return $pop[[R]]{{$}} 819define <2 x i64> @shr_s_noext_v2i64(<2 x i64> %v, i64 %x) { 820 %t = insertelement <2 x i64> undef, i64 %x, i32 0 821 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 822 %a = ashr <2 x i64> %v, %s 823 ret <2 x i64> %a 824} 825 826; CHECK-LABEL: shr_s_const_v2i64: 827; NO-SIMD128-NOT: i64x2 828; SIMD128-NEXT: .functype shr_s_const_v2i64 (v128) -> (v128){{$}} 829; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5{{$}} 830; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 831; SIMD128-NEXT: return $pop[[R]]{{$}} 832define <2 x i64> @shr_s_const_v2i64(<2 x i64> %v) { 833 %a = ashr <2 x i64> %v, <i64 5, i64 5> 834 ret <2 x i64> %a 835} 836 837; CHECK-LABEL: shr_s_vec_v2i64: 838; NO-SIMD128-NOT: i64x2 839; SIMD128-NEXT: .functype shr_s_vec_v2i64 (v128, v128) -> (v128){{$}} 840; SIMD128-NEXT: i64x2.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}} 841; SIMD128-NEXT: i64x2.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}} 842; SIMD128-NEXT: i64.shr_s $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 843; SIMD128-NEXT: i64x2.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 844; SIMD128-NEXT: i64x2.extract_lane $push[[L4:[0-9]+]]=, $0, 1{{$}} 845; SIMD128-NEXT: i64x2.extract_lane $push[[L5:[0-9]+]]=, $1, 1{{$}} 846; SIMD128-NEXT: i64.shr_s $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 847; SIMD128-NEXT: i64x2.replace_lane $push[[R:[0-9]+]]=, $pop[[L3]], 1, $pop[[L6]]{{$}} 848; SIMD128-NEXT: return $pop[[R]]{{$}} 849define <2 x i64> @shr_s_vec_v2i64(<2 x i64> %v, <2 x i64> %x) { 850 %a = ashr <2 x i64> %v, %x 851 ret <2 x i64> %a 852} 853 854; CHECK-LABEL: shr_u_v2i64: 855; NO-SIMD128-NOT: i64x2 856; SIMD128-NEXT: .functype shr_u_v2i64 (v128, i32) -> (v128){{$}} 857; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}} 858; SIMD128-NEXT: return $pop[[R]]{{$}} 859define <2 x i64> @shr_u_v2i64(<2 x i64> %v, i32 %x) { 860 %x2 = zext i32 %x to i64 861 %t = insertelement <2 x i64> undef, i64 %x2, i32 0 862 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 863 %a = lshr <2 x i64> %v, %s 864 ret <2 x i64> %a 865} 866 867; CHECK-LABEL: shr_u_sext_v2i64: 868; NO-SIMD128-NOT: i64x2 869; SIMD128-NEXT: .functype shr_u_sext_v2i64 (v128, i32) -> (v128){{$}} 870; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}} 871; SIMD128-NEXT: return $pop[[R]]{{$}} 872define <2 x i64> @shr_u_sext_v2i64(<2 x i64> %v, i32 %x) { 873 %x2 = sext i32 %x to i64 874 %t = insertelement <2 x i64> undef, i64 %x2, i32 0 875 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 876 %a = lshr <2 x i64> %v, %s 877 ret <2 x i64> %a 878} 879 880; CHECK-LABEL: shr_u_noext_v2i64: 881; NO-SIMD128-NOT: i64x2 882; SIMD128-NEXT: .functype shr_u_noext_v2i64 (v128, i64) -> (v128){{$}} 883; SIMD128-NEXT: i32.wrap_i64 $push[[L0:[0-9]+]]=, $1{{$}} 884; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 885; SIMD128-NEXT: return $pop[[R]]{{$}} 886define <2 x i64> @shr_u_noext_v2i64(<2 x i64> %v, i64 %x) { 887 %t = insertelement <2 x i64> undef, i64 %x, i32 0 888 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 889 %a = lshr <2 x i64> %v, %s 890 ret <2 x i64> %a 891} 892 893; CHECK-LABEL: shr_u_const_v2i64: 894; NO-SIMD128-NOT: i64x2 895; SIMD128-NEXT: .functype shr_u_const_v2i64 (v128) -> (v128){{$}} 896; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5{{$}} 897; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 898; SIMD128-NEXT: return $pop[[R]]{{$}} 899define <2 x i64> @shr_u_const_v2i64(<2 x i64> %v) { 900 %a = lshr <2 x i64> %v, <i64 5, i64 5> 901 ret <2 x i64> %a 902} 903 904; CHECK-LABEL: shr_u_vec_v2i64: 905; NO-SIMD128-NOT: i64x2 906; SIMD128-NEXT: .functype shr_u_vec_v2i64 (v128, v128) -> (v128){{$}} 907; SIMD128-NEXT: i64x2.extract_lane $push[[L0:[0-9]+]]=, $0, 0{{$}} 908; SIMD128-NEXT: i64x2.extract_lane $push[[L1:[0-9]+]]=, $1, 0{{$}} 909; SIMD128-NEXT: i64.shr_u $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}} 910; SIMD128-NEXT: i64x2.splat $push[[L3:[0-9]+]]=, $pop[[L2]]{{$}} 911; SIMD128-NEXT: i64x2.extract_lane $push[[L4:[0-9]+]]=, $0, 1{{$}} 912; SIMD128-NEXT: i64x2.extract_lane $push[[L5:[0-9]+]]=, $1, 1{{$}} 913; SIMD128-NEXT: i64.shr_u $push[[L6:[0-9]+]]=, $pop[[L4]], $pop[[L5]]{{$}} 914; SIMD128-NEXT: i64x2.replace_lane $push[[R:[0-9]+]]=, $pop[[L3]], 1, $pop[[L6]]{{$}} 915; SIMD128-NEXT: return $pop[[R]]{{$}} 916define <2 x i64> @shr_u_vec_v2i64(<2 x i64> %v, <2 x i64> %x) { 917 %a = lshr <2 x i64> %v, %x 918 ret <2 x i64> %a 919} 920 921; CHECK-LABEL: and_v2i64: 922; NO-SIMD128-NOT: v128 923; SIMD128-VM-NOT: v128 924; SIMD128-NEXT: .functype and_v2i64 (v128, v128) -> (v128){{$}} 925; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}} 926; SIMD128-NEXT: return $pop[[R]]{{$}} 927define <2 x i64> @and_v2i64(<2 x i64> %x, <2 x i64> %y) { 928 %a = and <2 x i64> %x, %y 929 ret <2 x i64> %a 930} 931 932; CHECK-LABEL: or_v2i64: 933; NO-SIMD128-NOT: v128 934; SIMD128-VM-NOT: v128 935; SIMD128-NEXT: .functype or_v2i64 (v128, v128) -> (v128){{$}} 936; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}} 937; SIMD128-NEXT: return $pop[[R]]{{$}} 938define <2 x i64> @or_v2i64(<2 x i64> %x, <2 x i64> %y) { 939 %a = or <2 x i64> %x, %y 940 ret <2 x i64> %a 941} 942 943; CHECK-LABEL: xor_v2i64: 944; NO-SIMD128-NOT: v128 945; SIMD128-VM-NOT: v128 946; SIMD128-NEXT: .functype xor_v2i64 (v128, v128) -> (v128){{$}} 947; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}} 948; SIMD128-NEXT: return $pop[[R]]{{$}} 949define <2 x i64> @xor_v2i64(<2 x i64> %x, <2 x i64> %y) { 950 %a = xor <2 x i64> %x, %y 951 ret <2 x i64> %a 952} 953 954; CHECK-LABEL: not_v2i64: 955; NO-SIMD128-NOT: v128 956; SIMD128-VM-NOT: v128 957; SIMD128-NEXT: .functype not_v2i64 (v128) -> (v128){{$}} 958; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}} 959; SIMD128-NEXT: return $pop[[R]]{{$}} 960define <2 x i64> @not_v2i64(<2 x i64> %x) { 961 %a = xor <2 x i64> %x, <i64 -1, i64 -1> 962 ret <2 x i64> %a 963} 964 965; CHECK-LABEL: bitselect_v2i64: 966; NO-SIMD128-NOT: v128 967; SIMD128-VM-NOT: v128 968; SIMD128-NEXT: .functype bitselect_v2i64 (v128, v128, v128) -> (v128){{$}} 969; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}} 970; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}} 971; SIMD128-FAST-NEXT: v128.not 972; SIMD128-FAST-NEXT: v128.and 973; SIMD128-FAST-NEXT: v128.and 974; SIMD128-FAST-NEXT: v128.or 975; SIMD128-FAST-NEXT: return 976define <2 x i64> @bitselect_v2i64(<2 x i64> %c, <2 x i64> %v1, <2 x i64> %v2) { 977 %masked_v1 = and <2 x i64> %v1, %c 978 %inv_mask = xor <2 x i64> <i64 -1, i64 -1>, %c 979 %masked_v2 = and <2 x i64> %v2, %inv_mask 980 %a = or <2 x i64> %masked_v2, %masked_v1 981 ret <2 x i64> %a 982} 983 984; ============================================================================== 985; 4 x float 986; ============================================================================== 987; CHECK-LABEL: neg_v4f32: 988; NO-SIMD128-NOT: f32x4 989; SIMD128-NEXT: .functype neg_v4f32 (v128) -> (v128){{$}} 990; SIMD128-NEXT: f32x4.neg $push[[R:[0-9]+]]=, $0{{$}} 991; SIMD128-NEXT: return $pop[[R]]{{$}} 992define <4 x float> @neg_v4f32(<4 x float> %x) { 993 ; nsz makes this semantically equivalent to flipping sign bit 994 %a = fsub nsz <4 x float> <float 0.0, float 0.0, float 0.0, float 0.0>, %x 995 ret <4 x float> %a 996} 997 998; CHECK-LABEL: abs_v4f32: 999; NO-SIMD128-NOT: f32x4 1000; SIMD128-NEXT: .functype abs_v4f32 (v128) -> (v128){{$}} 1001; SIMD128-NEXT: f32x4.abs $push[[R:[0-9]+]]=, $0{{$}} 1002; SIMD128-NEXT: return $pop[[R]]{{$}} 1003declare <4 x float> @llvm.fabs.v4f32(<4 x float>) nounwind readnone 1004define <4 x float> @abs_v4f32(<4 x float> %x) { 1005 %a = call <4 x float> @llvm.fabs.v4f32(<4 x float> %x) 1006 ret <4 x float> %a 1007} 1008 1009; CHECK-LABEL: min_unordered_v4f32: 1010; NO-SIMD128-NOT: f32x4 1011; SIMD128-NEXT: .functype min_unordered_v4f32 (v128) -> (v128){{$}} 1012; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2 1013; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 1014; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 1015; SIMD128-NEXT: return $pop[[R]]{{$}} 1016define <4 x float> @min_unordered_v4f32(<4 x float> %x) { 1017 %cmps = fcmp ule <4 x float> %x, <float 5., float 5., float 5., float 5.> 1018 %a = select <4 x i1> %cmps, <4 x float> %x, 1019 <4 x float> <float 5., float 5., float 5., float 5.> 1020 ret <4 x float> %a 1021} 1022 1023; CHECK-LABEL: max_unordered_v4f32: 1024; NO-SIMD128-NOT: f32x4 1025; SIMD128-NEXT: .functype max_unordered_v4f32 (v128) -> (v128){{$}} 1026; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2 1027; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 1028; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 1029; SIMD128-NEXT: return $pop[[R]]{{$}} 1030define <4 x float> @max_unordered_v4f32(<4 x float> %x) { 1031 %cmps = fcmp uge <4 x float> %x, <float 5., float 5., float 5., float 5.> 1032 %a = select <4 x i1> %cmps, <4 x float> %x, 1033 <4 x float> <float 5., float 5., float 5., float 5.> 1034 ret <4 x float> %a 1035} 1036 1037; CHECK-LABEL: min_ordered_v4f32: 1038; NO-SIMD128-NOT: f32x4 1039; SIMD128-NEXT: .functype min_ordered_v4f32 (v128) -> (v128){{$}} 1040; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2 1041; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 1042; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 1043; SIMD128-NEXT: return $pop[[R]]{{$}} 1044define <4 x float> @min_ordered_v4f32(<4 x float> %x) { 1045 %cmps = fcmp ole <4 x float> <float 5., float 5., float 5., float 5.>, %x 1046 %a = select <4 x i1> %cmps, 1047 <4 x float> <float 5., float 5., float 5., float 5.>, <4 x float> %x 1048 ret <4 x float> %a 1049} 1050 1051; CHECK-LABEL: max_ordered_v4f32: 1052; NO-SIMD128-NOT: f32x4 1053; SIMD128-NEXT: .functype max_ordered_v4f32 (v128) -> (v128){{$}} 1054; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2 1055; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 1056; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 1057; SIMD128-NEXT: return $pop[[R]]{{$}} 1058define <4 x float> @max_ordered_v4f32(<4 x float> %x) { 1059 %cmps = fcmp oge <4 x float> <float 5., float 5., float 5., float 5.>, %x 1060 %a = select <4 x i1> %cmps, 1061 <4 x float> <float 5., float 5., float 5., float 5.>, <4 x float> %x 1062 ret <4 x float> %a 1063} 1064 1065; CHECK-LABEL: min_intrinsic_v4f32: 1066; NO-SIMD128-NOT: f32x4 1067; SIMD128-NEXT: .functype min_intrinsic_v4f32 (v128, v128) -> (v128){{$}} 1068; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $0, $1{{$}} 1069; SIMD128-NEXT: return $pop[[R]]{{$}} 1070declare <4 x float> @llvm.minimum.v4f32(<4 x float>, <4 x float>) 1071define <4 x float> @min_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) { 1072 %a = call <4 x float> @llvm.minimum.v4f32(<4 x float> %x, <4 x float> %y) 1073 ret <4 x float> %a 1074} 1075 1076; CHECK-LABEL: max_intrinsic_v4f32: 1077; NO-SIMD128-NOT: f32x4 1078; SIMD128-NEXT: .functype max_intrinsic_v4f32 (v128, v128) -> (v128){{$}} 1079; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $0, $1{{$}} 1080; SIMD128-NEXT: return $pop[[R]]{{$}} 1081declare <4 x float> @llvm.maximum.v4f32(<4 x float>, <4 x float>) 1082define <4 x float> @max_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) { 1083 %a = call <4 x float> @llvm.maximum.v4f32(<4 x float> %x, <4 x float> %y) 1084 ret <4 x float> %a 1085} 1086 1087; CHECK-LABEL: min_const_intrinsic_v4f32: 1088; NO-SIMD128-NOT: f32x4 1089; SIMD128-NEXT: .functype min_const_intrinsic_v4f32 () -> (v128){{$}} 1090; SIMD128-NEXT: f32.const $push[[L:[0-9]+]]=, 0x1.4p2{{$}} 1091; SIMD128-NEXT: f32x4.splat $push[[R:[0-9]+]]=, $pop[[L]]{{$}} 1092; SIMD128-NEXT: return $pop[[R]]{{$}} 1093define <4 x float> @min_const_intrinsic_v4f32() { 1094 %a = call <4 x float> @llvm.minimum.v4f32( 1095 <4 x float> <float 42., float 42., float 42., float 42.>, 1096 <4 x float> <float 5., float 5., float 5., float 5.> 1097 ) 1098 ret <4 x float> %a 1099} 1100 1101; CHECK-LABEL: max_const_intrinsic_v4f32: 1102; NO-SIMD128-NOT: f32x4 1103; SIMD128-NEXT: .functype max_const_intrinsic_v4f32 () -> (v128){{$}} 1104; SIMD128-NEXT: f32.const $push[[L:[0-9]+]]=, 0x1.5p5{{$}} 1105; SIMD128-NEXT: f32x4.splat $push[[R:[0-9]+]]=, $pop[[L]]{{$}} 1106; SIMD128-NEXT: return $pop[[R]]{{$}} 1107define <4 x float> @max_const_intrinsic_v4f32() { 1108 %a = call <4 x float> @llvm.maximum.v4f32( 1109 <4 x float> <float 42., float 42., float 42., float 42.>, 1110 <4 x float> <float 5., float 5., float 5., float 5.> 1111 ) 1112 ret <4 x float> %a 1113} 1114 1115; CHECK-LABEL: add_v4f32: 1116; NO-SIMD128-NOT: f32x4 1117; SIMD128-NEXT: .functype add_v4f32 (v128, v128) -> (v128){{$}} 1118; SIMD128-NEXT: f32x4.add $push[[R:[0-9]+]]=, $0, $1{{$}} 1119; SIMD128-NEXT: return $pop[[R]]{{$}} 1120define <4 x float> @add_v4f32(<4 x float> %x, <4 x float> %y) { 1121 %a = fadd <4 x float> %x, %y 1122 ret <4 x float> %a 1123} 1124 1125; CHECK-LABEL: sub_v4f32: 1126; NO-SIMD128-NOT: f32x4 1127; SIMD128-NEXT: .functype sub_v4f32 (v128, v128) -> (v128){{$}} 1128; SIMD128-NEXT: f32x4.sub $push[[R:[0-9]+]]=, $0, $1{{$}} 1129; SIMD128-NEXT: return $pop[[R]]{{$}} 1130define <4 x float> @sub_v4f32(<4 x float> %x, <4 x float> %y) { 1131 %a = fsub <4 x float> %x, %y 1132 ret <4 x float> %a 1133} 1134 1135; CHECK-LABEL: div_v4f32: 1136; NO-SIMD128-NOT: f32x4 1137; SIMD128-VM-NOT: f32x4.div 1138; SIMD128-NEXT: .functype div_v4f32 (v128, v128) -> (v128){{$}} 1139; SIMD128-NEXT: f32x4.div $push[[R:[0-9]+]]=, $0, $1{{$}} 1140; SIMD128-NEXT: return $pop[[R]]{{$}} 1141define <4 x float> @div_v4f32(<4 x float> %x, <4 x float> %y) { 1142 %a = fdiv <4 x float> %x, %y 1143 ret <4 x float> %a 1144} 1145 1146; CHECK-LABEL: mul_v4f32: 1147; NO-SIMD128-NOT: f32x4 1148; SIMD128-NEXT: .functype mul_v4f32 (v128, v128) -> (v128){{$}} 1149; SIMD128-NEXT: f32x4.mul $push[[R:[0-9]+]]=, $0, $1{{$}} 1150; SIMD128-NEXT: return $pop[[R]]{{$}} 1151define <4 x float> @mul_v4f32(<4 x float> %x, <4 x float> %y) { 1152 %a = fmul <4 x float> %x, %y 1153 ret <4 x float> %a 1154} 1155 1156; CHECK-LABEL: sqrt_v4f32: 1157; NO-SIMD128-NOT: f32x4 1158; SIMD128-VM-NOT: f32x4.sqrt 1159; SIMD128-NEXT: .functype sqrt_v4f32 (v128) -> (v128){{$}} 1160; SIMD128-NEXT: f32x4.sqrt $push[[R:[0-9]+]]=, $0{{$}} 1161; SIMD128-NEXT: return $pop[[R]]{{$}} 1162declare <4 x float> @llvm.sqrt.v4f32(<4 x float> %x) 1163define <4 x float> @sqrt_v4f32(<4 x float> %x) { 1164 %a = call <4 x float> @llvm.sqrt.v4f32(<4 x float> %x) 1165 ret <4 x float> %a 1166} 1167 1168; ============================================================================== 1169; 2 x double 1170; ============================================================================== 1171; CHECK-LABEL: neg_v2f64: 1172; NO-SIMD128-NOT: f64x2 1173; SIMD128-NEXT: .functype neg_v2f64 (v128) -> (v128){{$}} 1174; SIMD128-NEXT: f64x2.neg $push[[R:[0-9]+]]=, $0{{$}} 1175; SIMD128-NEXT: return $pop[[R]]{{$}} 1176define <2 x double> @neg_v2f64(<2 x double> %x) { 1177 ; nsz makes this semantically equivalent to flipping sign bit 1178 %a = fsub nsz <2 x double> <double 0., double 0.>, %x 1179 ret <2 x double> %a 1180} 1181 1182; CHECK-LABEL: abs_v2f64: 1183; NO-SIMD128-NOT: f64x2 1184; SIMD128-NEXT: .functype abs_v2f64 (v128) -> (v128){{$}} 1185; SIMD128-NEXT: f64x2.abs $push[[R:[0-9]+]]=, $0{{$}} 1186; SIMD128-NEXT: return $pop[[R]]{{$}} 1187declare <2 x double> @llvm.fabs.v2f64(<2 x double>) nounwind readnone 1188define <2 x double> @abs_v2f64(<2 x double> %x) { 1189 %a = call <2 x double> @llvm.fabs.v2f64(<2 x double> %x) 1190 ret <2 x double> %a 1191} 1192 1193; CHECK-LABEL: min_unordered_v2f64: 1194; NO-SIMD128-NOT: f64x2 1195; SIMD128-NEXT: .functype min_unordered_v2f64 (v128) -> (v128){{$}} 1196; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2 1197; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 1198; SIMD128-NEXT: f64x2.min $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 1199; SIMD128-NEXT: return $pop[[R]]{{$}} 1200define <2 x double> @min_unordered_v2f64(<2 x double> %x) { 1201 %cmps = fcmp ule <2 x double> %x, <double 5., double 5.> 1202 %a = select <2 x i1> %cmps, <2 x double> %x, 1203 <2 x double> <double 5., double 5.> 1204 ret <2 x double> %a 1205} 1206 1207; CHECK-LABEL: max_unordered_v2f64: 1208; NO-SIMD128-NOT: f64x2 1209; SIMD128-NEXT: .functype max_unordered_v2f64 (v128) -> (v128){{$}} 1210; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2 1211; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 1212; SIMD128-NEXT: f64x2.max $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 1213; SIMD128-NEXT: return $pop[[R]]{{$}} 1214define <2 x double> @max_unordered_v2f64(<2 x double> %x) { 1215 %cmps = fcmp uge <2 x double> %x, <double 5., double 5.> 1216 %a = select <2 x i1> %cmps, <2 x double> %x, 1217 <2 x double> <double 5., double 5.> 1218 ret <2 x double> %a 1219} 1220 1221; CHECK-LABEL: min_ordered_v2f64: 1222; NO-SIMD128-NOT: f64x2 1223; SIMD128-NEXT: .functype min_ordered_v2f64 (v128) -> (v128){{$}} 1224; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2 1225; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 1226; SIMD128-NEXT: f64x2.min $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 1227; SIMD128-NEXT: return $pop[[R]]{{$}} 1228define <2 x double> @min_ordered_v2f64(<2 x double> %x) { 1229 %cmps = fcmp ole <2 x double> <double 5., double 5.>, %x 1230 %a = select <2 x i1> %cmps, <2 x double> <double 5., double 5.>, 1231 <2 x double> %x 1232 ret <2 x double> %a 1233} 1234 1235; CHECK-LABEL: max_ordered_v2f64: 1236; NO-SIMD128-NOT: f64x2 1237; SIMD128-NEXT: .functype max_ordered_v2f64 (v128) -> (v128){{$}} 1238; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2 1239; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 1240; SIMD128-NEXT: f64x2.max $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 1241; SIMD128-NEXT: return $pop[[R]]{{$}} 1242define <2 x double> @max_ordered_v2f64(<2 x double> %x) { 1243 %cmps = fcmp oge <2 x double> <double 5., double 5.>, %x 1244 %a = select <2 x i1> %cmps, <2 x double> <double 5., double 5.>, 1245 <2 x double> %x 1246 ret <2 x double> %a 1247} 1248 1249; CHECK-LABEL: min_intrinsic_v2f64: 1250; NO-SIMD128-NOT: f64x2 1251; SIMD128-NEXT: .functype min_intrinsic_v2f64 (v128, v128) -> (v128){{$}} 1252; SIMD128-NEXT: f64x2.min $push[[R:[0-9]+]]=, $0, $1{{$}} 1253; SIMD128-NEXT: return $pop[[R]]{{$}} 1254declare <2 x double> @llvm.minimum.v2f64(<2 x double>, <2 x double>) 1255define <2 x double> @min_intrinsic_v2f64(<2 x double> %x, <2 x double> %y) { 1256 %a = call <2 x double> @llvm.minimum.v2f64(<2 x double> %x, <2 x double> %y) 1257 ret <2 x double> %a 1258} 1259 1260; CHECK-LABEL: max_intrinsic_v2f64: 1261; NO-SIMD128-NOT: f64x2 1262; SIMD128-NEXT: .functype max_intrinsic_v2f64 (v128, v128) -> (v128){{$}} 1263; SIMD128-NEXT: f64x2.max $push[[R:[0-9]+]]=, $0, $1{{$}} 1264; SIMD128-NEXT: return $pop[[R]]{{$}} 1265declare <2 x double> @llvm.maximum.v2f64(<2 x double>, <2 x double>) 1266define <2 x double> @max_intrinsic_v2f64(<2 x double> %x, <2 x double> %y) { 1267 %a = call <2 x double> @llvm.maximum.v2f64(<2 x double> %x, <2 x double> %y) 1268 ret <2 x double> %a 1269} 1270 1271; CHECK-LABEL: min_const_intrinsic_v2f64: 1272; NO-SIMD128-NOT: f64x2 1273; SIMD128-NEXT: .functype min_const_intrinsic_v2f64 () -> (v128){{$}} 1274; SIMD128-NEXT: f64.const $push[[L:[0-9]+]]=, 0x1.4p2{{$}} 1275; SIMD128-NEXT: f64x2.splat $push[[R:[0-9]+]]=, $pop[[L]]{{$}} 1276; SIMD128-NEXT: return $pop[[R]]{{$}} 1277define <2 x double> @min_const_intrinsic_v2f64() { 1278 %a = call <2 x double> @llvm.minimum.v2f64( 1279 <2 x double> <double 42., double 42.>, 1280 <2 x double> <double 5., double 5.> 1281 ) 1282 ret <2 x double> %a 1283} 1284 1285; CHECK-LABEL: max_const_intrinsic_v2f64: 1286; NO-SIMD128-NOT: f64x2 1287; SIMD128-NEXT: .functype max_const_intrinsic_v2f64 () -> (v128){{$}} 1288; SIMD128-NEXT: f64.const $push[[L:[0-9]+]]=, 0x1.5p5{{$}} 1289; SIMD128-NEXT: f64x2.splat $push[[R:[0-9]+]]=, $pop[[L]]{{$}} 1290; SIMD128-NEXT: return $pop[[R]]{{$}} 1291define <2 x double> @max_const_intrinsic_v2f64() { 1292 %a = call <2 x double> @llvm.maximum.v2f64( 1293 <2 x double> <double 42., double 42.>, 1294 <2 x double> <double 5., double 5.> 1295 ) 1296 ret <2 x double> %a 1297} 1298 1299; CHECK-LABEL: add_v2f64: 1300; NO-SIMD128-NOT: f64x2 1301; SIMD128-VM-NOT: f62x2 1302; SIMD128-NEXT: .functype add_v2f64 (v128, v128) -> (v128){{$}} 1303; SIMD128-NEXT: f64x2.add $push[[R:[0-9]+]]=, $0, $1{{$}} 1304; SIMD128-NEXT: return $pop[[R]]{{$}} 1305define <2 x double> @add_v2f64(<2 x double> %x, <2 x double> %y) { 1306 %a = fadd <2 x double> %x, %y 1307 ret <2 x double> %a 1308} 1309 1310; CHECK-LABEL: sub_v2f64: 1311; NO-SIMD128-NOT: f64x2 1312; SIMD128-VM-NOT: f62x2 1313; SIMD128-NEXT: .functype sub_v2f64 (v128, v128) -> (v128){{$}} 1314; SIMD128-NEXT: f64x2.sub $push[[R:[0-9]+]]=, $0, $1{{$}} 1315; SIMD128-NEXT: return $pop[[R]]{{$}} 1316define <2 x double> @sub_v2f64(<2 x double> %x, <2 x double> %y) { 1317 %a = fsub <2 x double> %x, %y 1318 ret <2 x double> %a 1319} 1320 1321; CHECK-LABEL: div_v2f64: 1322; NO-SIMD128-NOT: f64x2 1323; SIMD128-VM-NOT: f62x2 1324; SIMD128-NEXT: .functype div_v2f64 (v128, v128) -> (v128){{$}} 1325; SIMD128-NEXT: f64x2.div $push[[R:[0-9]+]]=, $0, $1{{$}} 1326; SIMD128-NEXT: return $pop[[R]]{{$}} 1327define <2 x double> @div_v2f64(<2 x double> %x, <2 x double> %y) { 1328 %a = fdiv <2 x double> %x, %y 1329 ret <2 x double> %a 1330} 1331 1332; CHECK-LABEL: mul_v2f64: 1333; NO-SIMD128-NOT: f64x2 1334; SIMD128-VM-NOT: f62x2 1335; SIMD128-NEXT: .functype mul_v2f64 (v128, v128) -> (v128){{$}} 1336; SIMD128-NEXT: f64x2.mul $push[[R:[0-9]+]]=, $0, $1{{$}} 1337; SIMD128-NEXT: return $pop[[R]]{{$}} 1338define <2 x double> @mul_v2f64(<2 x double> %x, <2 x double> %y) { 1339 %a = fmul <2 x double> %x, %y 1340 ret <2 x double> %a 1341} 1342 1343; CHECK-LABEL: sqrt_v2f64: 1344; NO-SIMD128-NOT: f64x2 1345; SIMD128-NEXT: .functype sqrt_v2f64 (v128) -> (v128){{$}} 1346; SIMD128-NEXT: f64x2.sqrt $push[[R:[0-9]+]]=, $0{{$}} 1347; SIMD128-NEXT: return $pop[[R]]{{$}} 1348declare <2 x double> @llvm.sqrt.v2f64(<2 x double> %x) 1349define <2 x double> @sqrt_v2f64(<2 x double> %x) { 1350 %a = call <2 x double> @llvm.sqrt.v2f64(<2 x double> %x) 1351 ret <2 x double> %a 1352} 1353