1; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -wasm-enable-unimplemented-simd -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128,SIMD128-SLOW 2; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -wasm-enable-unimplemented-simd -mattr=+simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,SIMD128,SIMD128-FAST 3; RUN: llc < %s -asm-verbose=false -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 -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 -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=-simd128 | FileCheck %s --check-prefixes CHECK,NO-SIMD128 6; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=-simd128 -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 -wasm-enable-unimplemented-simd -mattr=+simd128,+sign-ext 10; RUN: llc < %s -O2 -wasm-enable-unimplemented-simd -mattr=+simd128,+sign-ext 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: .param v128, v128{{$}} 23; SIMD128-NEXT: .result v128{{$}} 24; SIMD128-NEXT: i8x16.add $push[[R:[0-9]+]]=, $0, $1{{$}} 25; SIMD128-NEXT: return $pop[[R]]{{$}} 26define <16 x i8> @add_v16i8(<16 x i8> %x, <16 x i8> %y) { 27 %a = add <16 x i8> %x, %y 28 ret <16 x i8> %a 29} 30 31; CHECK-LABEL: sub_v16i8: 32; NO-SIMD128-NOT: i8x16 33; SIMD128-NEXT: .param v128, v128{{$}} 34; SIMD128-NEXT: .result v128{{$}} 35; SIMD128-NEXT: i8x16.sub $push[[R:[0-9]+]]=, $0, $1{{$}} 36; SIMD128-NEXT: return $pop[[R]]{{$}} 37define <16 x i8> @sub_v16i8(<16 x i8> %x, <16 x i8> %y) { 38 %a = sub <16 x i8> %x, %y 39 ret <16 x i8> %a 40} 41 42; CHECK-LABEL: mul_v16i8: 43; NO-SIMD128-NOT: i8x16 44; SIMD128-NEXT: .param v128, v128{{$}} 45; SIMD128-NEXT: .result v128{{$}} 46; SIMD128-NEXT: i8x16.mul $push[[R:[0-9]+]]=, $0, $1{{$}} 47; SIMD128-NEXT: return $pop[[R]]{{$}} 48define <16 x i8> @mul_v16i8(<16 x i8> %x, <16 x i8> %y) { 49 %a = mul <16 x i8> %x, %y 50 ret <16 x i8> %a 51} 52 53; CHECK-LABEL: neg_v16i8: 54; NO-SIMD128-NOT: i8x16 55; SIMD128-NEXT: .param v128{{$}} 56; SIMD128-NEXT: .result v128{{$}} 57; SIMD128-NEXT: i8x16.neg $push[[R:[0-9]+]]=, $0{{$}} 58; SIMD128-NEXT: return $pop[[R]]{{$}} 59define <16 x i8> @neg_v16i8(<16 x i8> %x) { 60 %a = sub <16 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, 61 i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>, 62 %x 63 ret <16 x i8> %a 64} 65 66; CHECK-LABEL: shl_v16i8: 67; NO-SIMD128-NOT: i8x16 68; SIMD128-NEXT: .param v128, i32{{$}} 69; SIMD128-NEXT: .result v128{{$}} 70; SIMD128-NEXT: i8x16.shl $push[[R:[0-9]+]]=, $0, $1{{$}} 71; SIMD128-NEXT: return $pop[[R]]{{$}} 72define <16 x i8> @shl_v16i8(<16 x i8> %v, i8 %x) { 73 %t = insertelement <16 x i8> undef, i8 %x, i32 0 74 %s = shufflevector <16 x i8> %t, <16 x i8> undef, 75 <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, 76 i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 77 %a = shl <16 x i8> %v, %s 78 ret <16 x i8> %a 79} 80 81; CHECK-LABEL: shl_const_v16i8: 82; NO-SIMD128-NOT: i8x16 83; SIMD128-NEXT: .param v128{{$}} 84; SIMD128-NEXT: .result v128{{$}} 85; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5 86; SIMD128-NEXT: i8x16.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 87; SIMD128-NEXT: return $pop[[R]]{{$}} 88define <16 x i8> @shl_const_v16i8(<16 x i8> %v) { 89 %a = shl <16 x i8> %v, 90 <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, 91 i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5> 92 ret <16 x i8> %a 93} 94 95; CHECK-LABEL: shr_s_v16i8: 96; NO-SIMD128-NOT: i8x16 97; SIMD128-NEXT: .param v128, i32{{$}} 98; SIMD128-NEXT: .result v128{{$}} 99; SIMD128-NEXT: i8x16.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}} 100; SIMD128-NEXT: return $pop[[R]]{{$}} 101define <16 x i8> @shr_s_v16i8(<16 x i8> %v, i8 %x) { 102 %t = insertelement <16 x i8> undef, i8 %x, i32 0 103 %s = shufflevector <16 x i8> %t, <16 x i8> undef, 104 <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, 105 i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 106 %a = ashr <16 x i8> %v, %s 107 ret <16 x i8> %a 108} 109 110; CHECK-LABEL: shr_u_v16i8: 111; NO-SIMD128-NOT: i8x16 112; SIMD128-NEXT: .param v128, i32{{$}} 113; SIMD128-NEXT: .result v128{{$}} 114; SIMD128-NEXT: i8x16.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}} 115; SIMD128-NEXT: return $pop[[R]]{{$}} 116define <16 x i8> @shr_u_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 = lshr <16 x i8> %v, %s 122 ret <16 x i8> %a 123} 124 125; CHECK-LABEL: and_v16i8: 126; NO-SIMD128-NOT: v128 127; SIMD128-NEXT: .param v128, v128{{$}} 128; SIMD128-NEXT: .result v128{{$}} 129; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}} 130; SIMD128-NEXT: return $pop[[R]]{{$}} 131define <16 x i8> @and_v16i8(<16 x i8> %x, <16 x i8> %y) { 132 %a = and <16 x i8> %x, %y 133 ret <16 x i8> %a 134} 135 136; CHECK-LABEL: or_v16i8: 137; NO-SIMD128-NOT: v128 138; SIMD128-NEXT: .param v128, v128{{$}} 139; SIMD128-NEXT: .result v128{{$}} 140; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}} 141; SIMD128-NEXT: return $pop[[R]]{{$}} 142define <16 x i8> @or_v16i8(<16 x i8> %x, <16 x i8> %y) { 143 %a = or <16 x i8> %x, %y 144 ret <16 x i8> %a 145} 146 147; CHECK-LABEL: xor_v16i8: 148; NO-SIMD128-NOT: v128 149; SIMD128-NEXT: .param v128, v128{{$}} 150; SIMD128-NEXT: .result v128{{$}} 151; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}} 152; SIMD128-NEXT: return $pop[[R]]{{$}} 153define <16 x i8> @xor_v16i8(<16 x i8> %x, <16 x i8> %y) { 154 %a = xor <16 x i8> %x, %y 155 ret <16 x i8> %a 156} 157 158; CHECK-LABEL: not_v16i8: 159; NO-SIMD128-NOT: v128 160; SIMD128-NEXT: .param v128{{$}} 161; SIMD128-NEXT: .result v128{{$}} 162; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}} 163; SIMD128-NEXT: return $pop[[R]]{{$}} 164define <16 x i8> @not_v16i8(<16 x i8> %x) { 165 %a = xor <16 x i8> %x, <i8 -1, i8 -1, i8 -1, i8 -1, 166 i8 -1, i8 -1, i8 -1, i8 -1, 167 i8 -1, i8 -1, i8 -1, i8 -1, 168 i8 -1, i8 -1, i8 -1, i8 -1> 169 ret <16 x i8> %a 170} 171 172; CHECK-LABEL: bitselect_v16i8: 173; NO-SIMD128-NOT: v128 174; SIMD128-NEXT: .param v128, v128, v128{{$}} 175; SIMD128-NEXT: .result v128{{$}} 176; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}} 177; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}} 178; SIMD128-FAST-NEXT: v128.and 179; SIMD128-FAST-NEXT: v128.not 180; SIMD128-FAST-NEXT: v128.and 181; SIMD128-FAST-NEXT: v128.or 182; SIMD128-FAST-NEXT: return 183define <16 x i8> @bitselect_v16i8(<16 x i8> %c, <16 x i8> %v1, <16 x i8> %v2) { 184 %masked_v1 = and <16 x i8> %c, %v1 185 %inv_mask = xor <16 x i8> %c, 186 <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, 187 i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1> 188 %masked_v2 = and <16 x i8> %inv_mask, %v2 189 %a = or <16 x i8> %masked_v1, %masked_v2 190 ret <16 x i8> %a 191} 192 193; ============================================================================== 194; 8 x i16 195; ============================================================================== 196; CHECK-LABEL: add_v8i16: 197; NO-SIMD128-NOT: i16x8 198; SIMD128-NEXT: .param v128, v128{{$}} 199; SIMD128-NEXT: .result v128{{$}} 200; SIMD128-NEXT: i16x8.add $push[[R:[0-9]+]]=, $0, $1{{$}} 201; SIMD128-NEXT: return $pop[[R]]{{$}} 202define <8 x i16> @add_v8i16(<8 x i16> %x, <8 x i16> %y) { 203 %a = add <8 x i16> %x, %y 204 ret <8 x i16> %a 205} 206 207; CHECK-LABEL: sub_v8i16: 208; NO-SIMD128-NOT: i16x8 209; SIMD128-NEXT: .param v128, v128{{$}} 210; SIMD128-NEXT: .result v128{{$}} 211; SIMD128-NEXT: i16x8.sub $push[[R:[0-9]+]]=, $0, $1{{$}} 212; SIMD128-NEXT: return $pop[[R]]{{$}} 213define <8 x i16> @sub_v8i16(<8 x i16> %x, <8 x i16> %y) { 214 %a = sub <8 x i16> %x, %y 215 ret <8 x i16> %a 216} 217 218; CHECK-LABEL: mul_v8i16: 219; NO-SIMD128-NOT: i16x8 220; SIMD128-NEXT: .param v128, v128{{$}} 221; SIMD128-NEXT: .result v128{{$}} 222; SIMD128-NEXT: i16x8.mul $push[[R:[0-9]+]]=, $0, $1{{$}} 223; SIMD128-NEXT: return $pop[[R]]{{$}} 224define <8 x i16> @mul_v8i16(<8 x i16> %x, <8 x i16> %y) { 225 %a = mul <8 x i16> %x, %y 226 ret <8 x i16> %a 227} 228 229; CHECK-LABEL: neg_v8i16: 230; NO-SIMD128-NOT: i16x8 231; SIMD128-NEXT: .param v128{{$}} 232; SIMD128-NEXT: .result v128{{$}} 233; SIMD128-NEXT: i16x8.neg $push[[R:[0-9]+]]=, $0{{$}} 234; SIMD128-NEXT: return $pop[[R]]{{$}} 235define <8 x i16> @neg_v8i16(<8 x i16> %x) { 236 %a = sub <8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>, 237 %x 238 ret <8 x i16> %a 239} 240 241; CHECK-LABEL: shl_v8i16: 242; NO-SIMD128-NOT: i16x8 243; SIMD128-NEXT: .param v128, i32{{$}} 244; SIMD128-NEXT: .result v128{{$}} 245; SIMD128-NEXT: i16x8.shl $push[[R:[0-9]+]]=, $0, $1{{$}} 246; SIMD128-NEXT: return $pop[[R]]{{$}} 247define <8 x i16> @shl_v8i16(<8 x i16> %v, i16 %x) { 248 %t = insertelement <8 x i16> undef, i16 %x, i32 0 249 %s = shufflevector <8 x i16> %t, <8 x i16> undef, 250 <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 251 %a = shl <8 x i16> %v, %s 252 ret <8 x i16> %a 253} 254 255; CHECK-LABEL: shl_const_v8i16: 256; NO-SIMD128-NOT: i16x8 257; SIMD128-NEXT: .param v128{{$}} 258; SIMD128-NEXT: .result v128{{$}} 259; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5 260; SIMD128-NEXT: i16x8.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 261; SIMD128-NEXT: return $pop[[R]]{{$}} 262define <8 x i16> @shl_const_v8i16(<8 x i16> %v) { 263 %a = shl <8 x i16> %v, 264 <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5> 265 ret <8 x i16> %a 266} 267 268; CHECK-LABEL: shr_s_v8i16: 269; NO-SIMD128-NOT: i16x8 270; SIMD128-NEXT: .param v128, i32{{$}} 271; SIMD128-NEXT: .result v128{{$}} 272; SIMD128-NEXT: i16x8.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}} 273; SIMD128-NEXT: return $pop[[R]]{{$}} 274define <8 x i16> @shr_s_v8i16(<8 x i16> %v, i16 %x) { 275 %t = insertelement <8 x i16> undef, i16 %x, i32 0 276 %s = shufflevector <8 x i16> %t, <8 x i16> undef, 277 <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 278 %a = ashr <8 x i16> %v, %s 279 ret <8 x i16> %a 280} 281 282; CHECK-LABEL: shr_u_v8i16: 283; NO-SIMD128-NOT: i16x8 284; SIMD128-NEXT: .param v128, i32{{$}} 285; SIMD128-NEXT: .result v128{{$}} 286; SIMD128-NEXT: i16x8.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}} 287; SIMD128-NEXT: return $pop[[R]]{{$}} 288define <8 x i16> @shr_u_v8i16(<8 x i16> %v, i16 %x) { 289 %t = insertelement <8 x i16> undef, i16 %x, i32 0 290 %s = shufflevector <8 x i16> %t, <8 x i16> undef, 291 <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0> 292 %a = lshr <8 x i16> %v, %s 293 ret <8 x i16> %a 294} 295 296; CHECK-LABEL: and_v8i16: 297; NO-SIMD128-NOT: v128 298; SIMD128-NEXT: .param v128, v128{{$}} 299; SIMD128-NEXT: .result v128{{$}} 300; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}} 301; SIMD128-NEXT: return $pop[[R]]{{$}} 302define <8 x i16> @and_v8i16(<8 x i16> %x, <8 x i16> %y) { 303 %a = and <8 x i16> %x, %y 304 ret <8 x i16> %a 305} 306 307; CHECK-LABEL: or_v8i16: 308; NO-SIMD128-NOT: v128 309; SIMD128-NEXT: .param v128, v128{{$}} 310; SIMD128-NEXT: .result v128{{$}} 311; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}} 312; SIMD128-NEXT: return $pop[[R]]{{$}} 313define <8 x i16> @or_v8i16(<8 x i16> %x, <8 x i16> %y) { 314 %a = or <8 x i16> %x, %y 315 ret <8 x i16> %a 316} 317 318; CHECK-LABEL: xor_v8i16: 319; NO-SIMD128-NOT: v128 320; SIMD128-NEXT: .param v128, v128{{$}} 321; SIMD128-NEXT: .result v128{{$}} 322; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}} 323; SIMD128-NEXT: return $pop[[R]]{{$}} 324define <8 x i16> @xor_v8i16(<8 x i16> %x, <8 x i16> %y) { 325 %a = xor <8 x i16> %x, %y 326 ret <8 x i16> %a 327} 328 329; CHECK-LABEL: not_v8i16: 330; NO-SIMD128-NOT: v128 331; SIMD128-NEXT: .param v128{{$}} 332; SIMD128-NEXT: .result v128{{$}} 333; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}} 334; SIMD128-NEXT: return $pop[[R]]{{$}} 335define <8 x i16> @not_v8i16(<8 x i16> %x) { 336 %a = xor <8 x i16> %x, <i16 -1, i16 -1, i16 -1, i16 -1, 337 i16 -1, i16 -1, i16 -1, i16 -1> 338 ret <8 x i16> %a 339} 340 341; CHECK-LABEL: bitselect_v8i16: 342; NO-SIMD128-NOT: v128 343; SIMD128-NEXT: .param v128, v128, v128{{$}} 344; SIMD128-NEXT: .result v128{{$}} 345; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}} 346; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}} 347; SIMD128-FAST-NEXT: v128.and 348; SIMD128-FAST-NEXT: v128.not 349; SIMD128-FAST-NEXT: v128.and 350; SIMD128-FAST-NEXT: v128.or 351; SIMD128-FAST-NEXT: return 352define <8 x i16> @bitselect_v8i16(<8 x i16> %c, <8 x i16> %v1, <8 x i16> %v2) { 353 %masked_v1 = and <8 x i16> %v1, %c 354 %inv_mask = xor <8 x i16> 355 <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>, 356 %c 357 %masked_v2 = and <8 x i16> %v2, %inv_mask 358 %a = or <8 x i16> %masked_v1, %masked_v2 359 ret <8 x i16> %a 360} 361 362; ============================================================================== 363; 4 x i32 364; ============================================================================== 365; CHECK-LABEL: add_v4i32: 366; NO-SIMD128-NOT: i32x4 367; SIMD128-NEXT: .param v128, v128{{$}} 368; SIMD128-NEXT: .result v128{{$}} 369; SIMD128-NEXT: i32x4.add $push[[R:[0-9]+]]=, $0, $1{{$}} 370; SIMD128-NEXT: return $pop[[R]]{{$}} 371define <4 x i32> @add_v4i32(<4 x i32> %x, <4 x i32> %y) { 372 %a = add <4 x i32> %x, %y 373 ret <4 x i32> %a 374} 375 376; CHECK-LABEL: sub_v4i32: 377; NO-SIMD128-NOT: i32x4 378; SIMD128-NEXT: .param v128, v128{{$}} 379; SIMD128-NEXT: .result v128{{$}} 380; SIMD128-NEXT: i32x4.sub $push[[R:[0-9]+]]=, $0, $1{{$}} 381; SIMD128-NEXT: return $pop[[R]]{{$}} 382define <4 x i32> @sub_v4i32(<4 x i32> %x, <4 x i32> %y) { 383 %a = sub <4 x i32> %x, %y 384 ret <4 x i32> %a 385} 386 387; CHECK-LABEL: mul_v4i32: 388; NO-SIMD128-NOT: i32x4 389; SIMD128-NEXT: .param v128, v128{{$}} 390; SIMD128-NEXT: .result v128{{$}} 391; SIMD128-NEXT: i32x4.mul $push[[R:[0-9]+]]=, $0, $1{{$}} 392; SIMD128-NEXT: return $pop[[R]]{{$}} 393define <4 x i32> @mul_v4i32(<4 x i32> %x, <4 x i32> %y) { 394 %a = mul <4 x i32> %x, %y 395 ret <4 x i32> %a 396} 397 398; CHECK-LABEL: neg_v4i32: 399; NO-SIMD128-NOT: i32x4 400; SIMD128-NEXT: .param v128{{$}} 401; SIMD128-NEXT: .result v128{{$}} 402; SIMD128-NEXT: i32x4.neg $push[[R:[0-9]+]]=, $0{{$}} 403; SIMD128-NEXT: return $pop[[R]]{{$}} 404define <4 x i32> @neg_v4i32(<4 x i32> %x) { 405 %a = sub <4 x i32> <i32 0, i32 0, i32 0, i32 0>, %x 406 ret <4 x i32> %a 407} 408 409; CHECK-LABEL: shl_v4i32: 410; NO-SIMD128-NOT: i32x4 411; SIMD128-NEXT: .param v128, i32{{$}} 412; SIMD128-NEXT: .result v128{{$}} 413; SIMD128-NEXT: i32x4.shl $push[[R:[0-9]+]]=, $0, $1{{$}} 414; SIMD128-NEXT: return $pop[[R]]{{$}} 415define <4 x i32> @shl_v4i32(<4 x i32> %v, i32 %x) { 416 %t = insertelement <4 x i32> undef, i32 %x, i32 0 417 %s = shufflevector <4 x i32> %t, <4 x i32> undef, 418 <4 x i32> <i32 0, i32 0, i32 0, i32 0> 419 %a = shl <4 x i32> %v, %s 420 ret <4 x i32> %a 421} 422 423; CHECK-LABEL: shl_const_v4i32: 424; NO-SIMD128-NOT: i32x4 425; SIMD128-NEXT: .param v128{{$}} 426; SIMD128-NEXT: .result v128{{$}} 427; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5 428; SIMD128-NEXT: i32x4.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 429; SIMD128-NEXT: return $pop[[R]]{{$}} 430define <4 x i32> @shl_const_v4i32(<4 x i32> %v) { 431 %a = shl <4 x i32> %v, <i32 5, i32 5, i32 5, i32 5> 432 ret <4 x i32> %a 433} 434 435; CHECK-LABEL: shr_s_v4i32: 436; NO-SIMD128-NOT: i32x4 437; SIMD128-NEXT: .param v128, i32{{$}} 438; SIMD128-NEXT: .result v128{{$}} 439; SIMD128-NEXT: i32x4.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}} 440; SIMD128-NEXT: return $pop[[R]]{{$}} 441define <4 x i32> @shr_s_v4i32(<4 x i32> %v, i32 %x) { 442 %t = insertelement <4 x i32> undef, i32 %x, i32 0 443 %s = shufflevector <4 x i32> %t, <4 x i32> undef, 444 <4 x i32> <i32 0, i32 0, i32 0, i32 0> 445 %a = ashr <4 x i32> %v, %s 446 ret <4 x i32> %a 447} 448 449; CHECK-LABEL: shr_u_v4i32: 450; NO-SIMD128-NOT: i32x4 451; SIMD128-NEXT: .param v128, i32{{$}} 452; SIMD128-NEXT: .result v128{{$}} 453; SIMD128-NEXT: i32x4.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}} 454; SIMD128-NEXT: return $pop[[R]]{{$}} 455define <4 x i32> @shr_u_v4i32(<4 x i32> %v, i32 %x) { 456 %t = insertelement <4 x i32> undef, i32 %x, i32 0 457 %s = shufflevector <4 x i32> %t, <4 x i32> undef, 458 <4 x i32> <i32 0, i32 0, i32 0, i32 0> 459 %a = lshr <4 x i32> %v, %s 460 ret <4 x i32> %a 461} 462 463; CHECK-LABEL: and_v4i32: 464; NO-SIMD128-NOT: v128 465; SIMD128-NEXT: .param v128, v128{{$}} 466; SIMD128-NEXT: .result v128{{$}} 467; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}} 468; SIMD128-NEXT: return $pop[[R]]{{$}} 469define <4 x i32> @and_v4i32(<4 x i32> %x, <4 x i32> %y) { 470 %a = and <4 x i32> %x, %y 471 ret <4 x i32> %a 472} 473 474; CHECK-LABEL: or_v4i32: 475; NO-SIMD128-NOT: v128 476; SIMD128-NEXT: .param v128, v128{{$}} 477; SIMD128-NEXT: .result v128{{$}} 478; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}} 479; SIMD128-NEXT: return $pop[[R]]{{$}} 480define <4 x i32> @or_v4i32(<4 x i32> %x, <4 x i32> %y) { 481 %a = or <4 x i32> %x, %y 482 ret <4 x i32> %a 483} 484 485; CHECK-LABEL: xor_v4i32: 486; NO-SIMD128-NOT: v128 487; SIMD128-NEXT: .param v128, v128{{$}} 488; SIMD128-NEXT: .result v128{{$}} 489; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}} 490; SIMD128-NEXT: return $pop[[R]]{{$}} 491define <4 x i32> @xor_v4i32(<4 x i32> %x, <4 x i32> %y) { 492 %a = xor <4 x i32> %x, %y 493 ret <4 x i32> %a 494} 495 496; CHECK-LABEL: not_v4i32: 497; NO-SIMD128-NOT: v128 498; SIMD128-NEXT: .param v128{{$}} 499; SIMD128-NEXT: .result v128{{$}} 500; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}} 501; SIMD128-NEXT: return $pop[[R]]{{$}} 502define <4 x i32> @not_v4i32(<4 x i32> %x) { 503 %a = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1> 504 ret <4 x i32> %a 505} 506 507; CHECK-LABEL: bitselect_v4i32: 508; NO-SIMD128-NOT: v128 509; SIMD128-NEXT: .param v128, v128, v128{{$}} 510; SIMD128-NEXT: .result v128{{$}} 511; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}} 512; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}} 513; SIMD128-FAST-NEXT: v128.not 514; SIMD128-FAST-NEXT: v128.and 515; SIMD128-FAST-NEXT: v128.and 516; SIMD128-FAST-NEXT: v128.or 517; SIMD128-FAST-NEXT: return 518define <4 x i32> @bitselect_v4i32(<4 x i32> %c, <4 x i32> %v1, <4 x i32> %v2) { 519 %masked_v1 = and <4 x i32> %c, %v1 520 %inv_mask = xor <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>, %c 521 %masked_v2 = and <4 x i32> %inv_mask, %v2 522 %a = or <4 x i32> %masked_v2, %masked_v1 523 ret <4 x i32> %a 524} 525 526; ============================================================================== 527; 2 x i64 528; ============================================================================== 529; CHECK-LABEL: add_v2i64: 530; NO-SIMD128-NOT: i64x2 531; SIMD128-VM-NOT: i64x2 532; SIMD128-NEXT: .param v128, v128{{$}} 533; SIMD128-NEXT: .result v128{{$}} 534; SIMD128-NEXT: i64x2.add $push[[R:[0-9]+]]=, $0, $1{{$}} 535; SIMD128-NEXT: return $pop[[R]]{{$}} 536define <2 x i64> @add_v2i64(<2 x i64> %x, <2 x i64> %y) { 537 %a = add <2 x i64> %x, %y 538 ret <2 x i64> %a 539} 540 541; CHECK-LABEL: sub_v2i64: 542; NO-SIMD128-NOT: i64x2 543; SIMD128-VM-NOT: i64x2 544; SIMD128-NEXT: .param v128, v128{{$}} 545; SIMD128-NEXT: .result v128{{$}} 546; SIMD128-NEXT: i64x2.sub $push[[R:[0-9]+]]=, $0, $1{{$}} 547; SIMD128-NEXT: return $pop[[R]]{{$}} 548define <2 x i64> @sub_v2i64(<2 x i64> %x, <2 x i64> %y) { 549 %a = sub <2 x i64> %x, %y 550 ret <2 x i64> %a 551} 552 553; v2i64.mul is not in spec 554; CHECK-LABEL: mul_v2i64: 555; NO-SIMD128-NOT: i64x2 556; SIMD128-VM-NOT: i64x2 557; SIMD128-NOT: i64x2.mul 558; SIMD128: i64x2.extract_lane 559; SIMD128: i64.mul 560define <2 x i64> @mul_v2i64(<2 x i64> %x, <2 x i64> %y) { 561 %a = mul <2 x i64> %x, %y 562 ret <2 x i64> %a 563} 564 565; CHECK-LABEL: neg_v2i64: 566; NO-SIMD128-NOT: i64x2 567; SIMD128-NEXT: .param v128{{$}} 568; SIMD128-NEXT: .result v128{{$}} 569; SIMD128-NEXT: i64x2.neg $push[[R:[0-9]+]]=, $0{{$}} 570; SIMD128-NEXT: return $pop[[R]]{{$}} 571define <2 x i64> @neg_v2i64(<2 x i64> %x) { 572 %a = sub <2 x i64> <i64 0, i64 0>, %x 573 ret <2 x i64> %a 574} 575 576; CHECK-LABEL: shl_v2i64: 577; NO-SIMD128-NOT: i64x2 578; SIMD128-NEXT: .param v128, i32{{$}} 579; SIMD128-NEXT: .result v128{{$}} 580; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $1{{$}} 581; SIMD128-NEXT: return $pop[[R]]{{$}} 582define <2 x i64> @shl_v2i64(<2 x i64> %v, i32 %x) { 583 %x2 = zext i32 %x to i64 584 %t = insertelement <2 x i64> undef, i64 %x2, i32 0 585 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 586 %a = shl <2 x i64> %v, %s 587 ret <2 x i64> %a 588} 589 590; CHECK-LABEL: shl_nozext_v2i64: 591; NO-SIMD128-NOT: i64x2 592; SIMD128-NEXT: .param v128, i64{{$}} 593; SIMD128-NEXT: .result v128{{$}} 594; SIMD128-NEXT: i32.wrap/i64 $push[[L0:[0-9]+]]=, $1{{$}} 595; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 596; SIMD128-NEXT: return $pop[[R]]{{$}} 597define <2 x i64> @shl_nozext_v2i64(<2 x i64> %v, i64 %x) { 598 %t = insertelement <2 x i64> undef, i64 %x, i32 0 599 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 600 %a = shl <2 x i64> %v, %s 601 ret <2 x i64> %a 602} 603 604; CHECK-LABEL: shl_const_v2i64: 605; NO-SIMD128-NOT: i64x2 606; SIMD128-NEXT: .param v128{{$}} 607; SIMD128-NEXT: .result v128{{$}} 608; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5{{$}} 609; SIMD128-NEXT: i64x2.shl $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 610; SIMD128-NEXT: return $pop[[R]]{{$}} 611define <2 x i64> @shl_const_v2i64(<2 x i64> %v) { 612 %a = shl <2 x i64> %v, <i64 5, i64 5> 613 ret <2 x i64> %a 614} 615 616; CHECK-LABEL: shr_s_v2i64: 617; NO-SIMD128-NOT: i64x2 618; SIMD128-NEXT: .param v128, i32{{$}} 619; SIMD128-NEXT: .result v128{{$}} 620; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $1{{$}} 621; SIMD128-NEXT: return $pop[[R]]{{$}} 622define <2 x i64> @shr_s_v2i64(<2 x i64> %v, i32 %x) { 623 %x2 = zext i32 %x to i64 624 %t = insertelement <2 x i64> undef, i64 %x2, i32 0 625 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 626 %a = ashr <2 x i64> %v, %s 627 ret <2 x i64> %a 628} 629 630; CHECK-LABEL: shr_s_nozext_v2i64: 631; NO-SIMD128-NOT: i64x2 632; SIMD128-NEXT: .param v128, i64{{$}} 633; SIMD128-NEXT: .result v128{{$}} 634; SIMD128-NEXT: i32.wrap/i64 $push[[L0:[0-9]+]]=, $1{{$}} 635; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 636; SIMD128-NEXT: return $pop[[R]]{{$}} 637define <2 x i64> @shr_s_nozext_v2i64(<2 x i64> %v, i64 %x) { 638 %t = insertelement <2 x i64> undef, i64 %x, i32 0 639 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 640 %a = ashr <2 x i64> %v, %s 641 ret <2 x i64> %a 642} 643 644; CHECK-LABEL: shr_s_const_v2i64: 645; NO-SIMD128-NOT: i64x2 646; SIMD128-NEXT: .param v128{{$}} 647; SIMD128-NEXT: .result v128{{$}} 648; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5{{$}} 649; SIMD128-NEXT: i64x2.shr_s $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 650; SIMD128-NEXT: return $pop[[R]]{{$}} 651define <2 x i64> @shr_s_const_v2i64(<2 x i64> %v) { 652 %a = ashr <2 x i64> %v, <i64 5, i64 5> 653 ret <2 x i64> %a 654} 655 656; CHECK-LABEL: shr_u_v2i64: 657; NO-SIMD128-NOT: i64x2 658; SIMD128-NEXT: .param v128, i32{{$}} 659; SIMD128-NEXT: .result v128{{$}} 660; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $1{{$}} 661; SIMD128-NEXT: return $pop[[R]]{{$}} 662define <2 x i64> @shr_u_v2i64(<2 x i64> %v, i32 %x) { 663 %x2 = zext i32 %x to i64 664 %t = insertelement <2 x i64> undef, i64 %x2, i32 0 665 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 666 %a = lshr <2 x i64> %v, %s 667 ret <2 x i64> %a 668} 669 670; CHECK-LABEL: shr_u_nozext_v2i64: 671; NO-SIMD128-NOT: i64x2 672; SIMD128-NEXT: .param v128, i64{{$}} 673; SIMD128-NEXT: .result v128{{$}} 674; SIMD128-NEXT: i32.wrap/i64 $push[[L0:[0-9]+]]=, $1{{$}} 675; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 676; SIMD128-NEXT: return $pop[[R]]{{$}} 677define <2 x i64> @shr_u_nozext_v2i64(<2 x i64> %v, i64 %x) { 678 %t = insertelement <2 x i64> undef, i64 %x, i32 0 679 %s = shufflevector <2 x i64> %t, <2 x i64> undef, <2 x i32> <i32 0, i32 0> 680 %a = lshr <2 x i64> %v, %s 681 ret <2 x i64> %a 682} 683 684; CHECK-LABEL: shr_u_const_v2i64: 685; NO-SIMD128-NOT: i64x2 686; SIMD128-NEXT: .param v128{{$}} 687; SIMD128-NEXT: .result v128{{$}} 688; SIMD128-NEXT: i32.const $push[[L0:[0-9]+]]=, 5{{$}} 689; SIMD128-NEXT: i64x2.shr_u $push[[R:[0-9]+]]=, $0, $pop[[L0]]{{$}} 690; SIMD128-NEXT: return $pop[[R]]{{$}} 691define <2 x i64> @shr_u_const_v2i64(<2 x i64> %v) { 692 %a = lshr <2 x i64> %v, <i64 5, i64 5> 693 ret <2 x i64> %a 694} 695 696; CHECK-LABEL: and_v2i64: 697; NO-SIMD128-NOT: v128 698; SIMD128-VM-NOT: v128 699; SIMD128-NEXT: .param v128, v128{{$}} 700; SIMD128-NEXT: .result v128{{$}} 701; SIMD128-NEXT: v128.and $push[[R:[0-9]+]]=, $0, $1{{$}} 702; SIMD128-NEXT: return $pop[[R]]{{$}} 703define <2 x i64> @and_v2i64(<2 x i64> %x, <2 x i64> %y) { 704 %a = and <2 x i64> %x, %y 705 ret <2 x i64> %a 706} 707 708; CHECK-LABEL: or_v2i64: 709; NO-SIMD128-NOT: v128 710; SIMD128-VM-NOT: v128 711; SIMD128-NEXT: .param v128, v128{{$}} 712; SIMD128-NEXT: .result v128{{$}} 713; SIMD128-NEXT: v128.or $push[[R:[0-9]+]]=, $0, $1{{$}} 714; SIMD128-NEXT: return $pop[[R]]{{$}} 715define <2 x i64> @or_v2i64(<2 x i64> %x, <2 x i64> %y) { 716 %a = or <2 x i64> %x, %y 717 ret <2 x i64> %a 718} 719 720; CHECK-LABEL: xor_v2i64: 721; NO-SIMD128-NOT: v128 722; SIMD128-VM-NOT: v128 723; SIMD128-NEXT: .param v128, v128{{$}} 724; SIMD128-NEXT: .result v128{{$}} 725; SIMD128-NEXT: v128.xor $push[[R:[0-9]+]]=, $0, $1{{$}} 726; SIMD128-NEXT: return $pop[[R]]{{$}} 727define <2 x i64> @xor_v2i64(<2 x i64> %x, <2 x i64> %y) { 728 %a = xor <2 x i64> %x, %y 729 ret <2 x i64> %a 730} 731 732; CHECK-LABEL: not_v2i64: 733; NO-SIMD128-NOT: v128 734; SIMD128-VM-NOT: v128 735; SIMD128-NEXT: .param v128{{$}} 736; SIMD128-NEXT: .result v128{{$}} 737; SIMD128-NEXT: v128.not $push[[R:[0-9]+]]=, $0{{$}} 738; SIMD128-NEXT: return $pop[[R]]{{$}} 739define <2 x i64> @not_v2i64(<2 x i64> %x) { 740 %a = xor <2 x i64> %x, <i64 -1, i64 -1> 741 ret <2 x i64> %a 742} 743 744; CHECK-LABEL: bitselect_v2i64: 745; NO-SIMD128-NOT: v128 746; SIMD128-VM-NOT: v128 747; SIMD128-NEXT: .param v128, v128, v128{{$}} 748; SIMD128-NEXT: .result v128{{$}} 749; SIMD128-SLOW-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}} 750; SIMD128-SLOW-NEXT: return $pop[[R]]{{$}} 751; SIMD128-FAST-NEXT: v128.not 752; SIMD128-FAST-NEXT: v128.and 753; SIMD128-FAST-NEXT: v128.and 754; SIMD128-FAST-NEXT: v128.or 755; SIMD128-FAST-NEXT: return 756define <2 x i64> @bitselect_v2i64(<2 x i64> %c, <2 x i64> %v1, <2 x i64> %v2) { 757 %masked_v1 = and <2 x i64> %v1, %c 758 %inv_mask = xor <2 x i64> <i64 -1, i64 -1>, %c 759 %masked_v2 = and <2 x i64> %v2, %inv_mask 760 %a = or <2 x i64> %masked_v2, %masked_v1 761 ret <2 x i64> %a 762} 763 764; ============================================================================== 765; 4 x float 766; ============================================================================== 767; CHECK-LABEL: neg_v4f32: 768; NO-SIMD128-NOT: f32x4 769; SIMD128-NEXT: .param v128{{$}} 770; SIMD128-NEXT: .result v128{{$}} 771; SIMD128-NEXT: f32x4.neg $push[[R:[0-9]+]]=, $0{{$}} 772; SIMD128-NEXT: return $pop[[R]]{{$}} 773define <4 x float> @neg_v4f32(<4 x float> %x) { 774 ; nsz makes this semantically equivalent to flipping sign bit 775 %a = fsub nsz <4 x float> <float 0.0, float 0.0, float 0.0, float 0.0>, %x 776 ret <4 x float> %a 777} 778 779; CHECK-LABEL: abs_v4f32: 780; NO-SIMD128-NOT: f32x4 781; SIMD128-NEXT: .param v128{{$}} 782; SIMD128-NEXT: .result v128{{$}} 783; SIMD128-NEXT: f32x4.abs $push[[R:[0-9]+]]=, $0{{$}} 784; SIMD128-NEXT: return $pop[[R]]{{$}} 785declare <4 x float> @llvm.fabs.v4f32(<4 x float>) nounwind readnone 786define <4 x float> @abs_v4f32(<4 x float> %x) { 787 %a = call <4 x float> @llvm.fabs.v4f32(<4 x float> %x) 788 ret <4 x float> %a 789} 790 791; CHECK-LABEL: min_unordered_v4f32: 792; NO-SIMD128-NOT: f32x4 793; SIMD128-NEXT: .param v128{{$}} 794; SIMD128-NEXT: .result v128{{$}} 795; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2 796; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 797; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 798; SIMD128-NEXT: return $pop[[R]]{{$}} 799define <4 x float> @min_unordered_v4f32(<4 x float> %x) { 800 %cmps = fcmp ule <4 x float> %x, <float 5., float 5., float 5., float 5.> 801 %a = select <4 x i1> %cmps, <4 x float> %x, 802 <4 x float> <float 5., float 5., float 5., float 5.> 803 ret <4 x float> %a 804} 805 806; CHECK-LABEL: max_unordered_v4f32: 807; NO-SIMD128-NOT: f32x4 808; SIMD128-NEXT: .param v128{{$}} 809; SIMD128-NEXT: .result v128{{$}} 810; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2 811; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 812; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 813; SIMD128-NEXT: return $pop[[R]]{{$}} 814define <4 x float> @max_unordered_v4f32(<4 x float> %x) { 815 %cmps = fcmp uge <4 x float> %x, <float 5., float 5., float 5., float 5.> 816 %a = select <4 x i1> %cmps, <4 x float> %x, 817 <4 x float> <float 5., float 5., float 5., float 5.> 818 ret <4 x float> %a 819} 820 821; CHECK-LABEL: min_ordered_v4f32: 822; NO-SIMD128-NOT: f32x4 823; SIMD128-NEXT: .param v128{{$}} 824; SIMD128-NEXT: .result v128{{$}} 825; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2 826; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 827; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $pop[[L1]], $0{{$}} 828; SIMD128-NEXT: return $pop[[R]]{{$}} 829define <4 x float> @min_ordered_v4f32(<4 x float> %x) { 830 %cmps = fcmp ole <4 x float> <float 5., float 5., float 5., float 5.>, %x 831 %a = select <4 x i1> %cmps, 832 <4 x float> <float 5., float 5., float 5., float 5.>, <4 x float> %x 833 ret <4 x float> %a 834} 835 836; CHECK-LABEL: max_ordered_v4f32: 837; NO-SIMD128-NOT: f32x4 838; SIMD128-NEXT: .param v128{{$}} 839; SIMD128-NEXT: .result v128{{$}} 840; SIMD128-NEXT: f32.const $push[[L0:[0-9]+]]=, 0x1.4p2 841; SIMD128-NEXT: f32x4.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 842; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $pop[[L1]], $0{{$}} 843; SIMD128-NEXT: return $pop[[R]]{{$}} 844define <4 x float> @max_ordered_v4f32(<4 x float> %x) { 845 %cmps = fcmp oge <4 x float> <float 5., float 5., float 5., float 5.>, %x 846 %a = select <4 x i1> %cmps, 847 <4 x float> <float 5., float 5., float 5., float 5.>, <4 x float> %x 848 ret <4 x float> %a 849} 850 851; CHECK-LABEL: min_intrinsic_v4f32: 852; NO-SIMD128-NOT: f32x4 853; SIMD128-NEXT: .param v128, v128{{$}} 854; SIMD128-NEXT: .result v128{{$}} 855; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $0, $1{{$}} 856; SIMD128-NEXT: return $pop[[R]]{{$}} 857declare <4 x float> @llvm.minimum.v4f32(<4 x float>, <4 x float>) 858define <4 x float> @min_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) { 859 %a = call <4 x float> @llvm.minimum.v4f32(<4 x float> %x, <4 x float> %y) 860 ret <4 x float> %a 861} 862 863; CHECK-LABEL: max_intrinsic_v4f32: 864; NO-SIMD128-NOT: f32x4 865; SIMD128-NEXT: .param v128, v128{{$}} 866; SIMD128-NEXT: .result v128{{$}} 867; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $0, $1{{$}} 868; SIMD128-NEXT: return $pop[[R]]{{$}} 869declare <4 x float> @llvm.maximum.v4f32(<4 x float>, <4 x float>) 870define <4 x float> @max_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) { 871 %a = call <4 x float> @llvm.maximum.v4f32(<4 x float> %x, <4 x float> %y) 872 ret <4 x float> %a 873} 874 875; CHECK-LABEL: add_v4f32: 876; NO-SIMD128-NOT: f32x4 877; SIMD128-NEXT: .param v128, v128{{$}} 878; SIMD128-NEXT: .result v128{{$}} 879; SIMD128-NEXT: f32x4.add $push[[R:[0-9]+]]=, $0, $1{{$}} 880; SIMD128-NEXT: return $pop[[R]]{{$}} 881define <4 x float> @add_v4f32(<4 x float> %x, <4 x float> %y) { 882 %a = fadd <4 x float> %x, %y 883 ret <4 x float> %a 884} 885 886; CHECK-LABEL: sub_v4f32: 887; NO-SIMD128-NOT: f32x4 888; SIMD128-NEXT: .param v128, v128{{$}} 889; SIMD128-NEXT: .result v128{{$}} 890; SIMD128-NEXT: f32x4.sub $push[[R:[0-9]+]]=, $0, $1{{$}} 891; SIMD128-NEXT: return $pop[[R]]{{$}} 892define <4 x float> @sub_v4f32(<4 x float> %x, <4 x float> %y) { 893 %a = fsub <4 x float> %x, %y 894 ret <4 x float> %a 895} 896 897; CHECK-LABEL: div_v4f32: 898; NO-SIMD128-NOT: f32x4 899; SIMD128-NEXT: .param v128, v128{{$}} 900; SIMD128-NEXT: .result v128{{$}} 901; SIMD128-NEXT: f32x4.div $push[[R:[0-9]+]]=, $0, $1{{$}} 902; SIMD128-NEXT: return $pop[[R]]{{$}} 903define <4 x float> @div_v4f32(<4 x float> %x, <4 x float> %y) { 904 %a = fdiv <4 x float> %x, %y 905 ret <4 x float> %a 906} 907 908; CHECK-LABEL: mul_v4f32: 909; NO-SIMD128-NOT: f32x4 910; SIMD128-NEXT: .param v128, v128{{$}} 911; SIMD128-NEXT: .result v128{{$}} 912; SIMD128-NEXT: f32x4.mul $push[[R:[0-9]+]]=, $0, $1{{$}} 913; SIMD128-NEXT: return $pop[[R]]{{$}} 914define <4 x float> @mul_v4f32(<4 x float> %x, <4 x float> %y) { 915 %a = fmul <4 x float> %x, %y 916 ret <4 x float> %a 917} 918 919; CHECK-LABEL: sqrt_v4f32: 920; NO-SIMD128-NOT: f32x4 921; SIMD128-NEXT: .param v128{{$}} 922; SIMD128-NEXT: .result v128{{$}} 923; SIMD128-NEXT: f32x4.sqrt $push[[R:[0-9]+]]=, $0{{$}} 924; SIMD128-NEXT: return $pop[[R]]{{$}} 925declare <4 x float> @llvm.sqrt.v4f32(<4 x float> %x) 926define <4 x float> @sqrt_v4f32(<4 x float> %x) { 927 %a = call <4 x float> @llvm.sqrt.v4f32(<4 x float> %x) 928 ret <4 x float> %a 929} 930 931; ============================================================================== 932; 2 x double 933; ============================================================================== 934; CHECK-LABEL: neg_v2f64: 935; NO-SIMD128-NOT: f64x2 936; SIMD128-NEXT: .param v128{{$}} 937; SIMD128-NEXT: .result v128{{$}} 938; SIMD128-NEXT: f64x2.neg $push[[R:[0-9]+]]=, $0{{$}} 939; SIMD128-NEXT: return $pop[[R]]{{$}} 940define <2 x double> @neg_v2f64(<2 x double> %x) { 941 ; nsz makes this semantically equivalent to flipping sign bit 942 %a = fsub nsz <2 x double> <double 0., double 0.>, %x 943 ret <2 x double> %a 944} 945 946; CHECK-LABEL: abs_v2f64: 947; NO-SIMD128-NOT: f64x2 948; SIMD128-NEXT: .param v128{{$}} 949; SIMD128-NEXT: .result v128{{$}} 950; SIMD128-NEXT: f64x2.abs $push[[R:[0-9]+]]=, $0{{$}} 951; SIMD128-NEXT: return $pop[[R]]{{$}} 952declare <2 x double> @llvm.fabs.v2f64(<2 x double>) nounwind readnone 953define <2 x double> @abs_v2f64(<2 x double> %x) { 954 %a = call <2 x double> @llvm.fabs.v2f64(<2 x double> %x) 955 ret <2 x double> %a 956} 957 958; CHECK-LABEL: min_unordered_v2f64: 959; NO-SIMD128-NOT: f64x2 960; SIMD128-NEXT: .param v128{{$}} 961; SIMD128-NEXT: .result v128{{$}} 962; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2 963; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 964; SIMD128-NEXT: f64x2.min $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 965; SIMD128-NEXT: return $pop[[R]]{{$}} 966define <2 x double> @min_unordered_v2f64(<2 x double> %x) { 967 %cmps = fcmp ule <2 x double> %x, <double 5., double 5.> 968 %a = select <2 x i1> %cmps, <2 x double> %x, 969 <2 x double> <double 5., double 5.> 970 ret <2 x double> %a 971} 972 973; CHECK-LABEL: max_unordered_v2f64: 974; NO-SIMD128-NOT: f64x2 975; SIMD128-NEXT: .param v128{{$}} 976; SIMD128-NEXT: .result v128{{$}} 977; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2 978; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 979; SIMD128-NEXT: f64x2.max $push[[R:[0-9]+]]=, $0, $pop[[L1]]{{$}} 980; SIMD128-NEXT: return $pop[[R]]{{$}} 981define <2 x double> @max_unordered_v2f64(<2 x double> %x) { 982 %cmps = fcmp uge <2 x double> %x, <double 5., double 5.> 983 %a = select <2 x i1> %cmps, <2 x double> %x, 984 <2 x double> <double 5., double 5.> 985 ret <2 x double> %a 986} 987 988; CHECK-LABEL: min_ordered_v2f64: 989; NO-SIMD128-NOT: f64x2 990; SIMD128-NEXT: .param v128{{$}} 991; SIMD128-NEXT: .result v128{{$}} 992; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2 993; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 994; SIMD128-NEXT: f64x2.min $push[[R:[0-9]+]]=, $pop[[L1]], $0{{$}} 995; SIMD128-NEXT: return $pop[[R]]{{$}} 996define <2 x double> @min_ordered_v2f64(<2 x double> %x) { 997 %cmps = fcmp ole <2 x double> <double 5., double 5.>, %x 998 %a = select <2 x i1> %cmps, <2 x double> <double 5., double 5.>, 999 <2 x double> %x 1000 ret <2 x double> %a 1001} 1002 1003; CHECK-LABEL: max_ordered_v2f64: 1004; NO-SIMD128-NOT: f64x2 1005; SIMD128-NEXT: .param v128{{$}} 1006; SIMD128-NEXT: .result v128{{$}} 1007; SIMD128-NEXT: f64.const $push[[L0:[0-9]+]]=, 0x1.4p2 1008; SIMD128-NEXT: f64x2.splat $push[[L1:[0-9]+]]=, $pop[[L0]] 1009; SIMD128-NEXT: f64x2.max $push[[R:[0-9]+]]=, $pop[[L1]], $0{{$}} 1010; SIMD128-NEXT: return $pop[[R]]{{$}} 1011define <2 x double> @max_ordered_v2f64(<2 x double> %x) { 1012 %cmps = fcmp oge <2 x double> <double 5., double 5.>, %x 1013 %a = select <2 x i1> %cmps, <2 x double> <double 5., double 5.>, 1014 <2 x double> %x 1015 ret <2 x double> %a 1016} 1017 1018; CHECK-LABEL: min_intrinsic_v2f64: 1019; NO-SIMD128-NOT: f64x2 1020; SIMD128-NEXT: .param v128, v128{{$}} 1021; SIMD128-NEXT: .result v128{{$}} 1022; SIMD128-NEXT: f64x2.min $push[[R:[0-9]+]]=, $0, $1{{$}} 1023; SIMD128-NEXT: return $pop[[R]]{{$}} 1024declare <2 x double> @llvm.minimum.v2f64(<2 x double>, <2 x double>) 1025define <2 x double> @min_intrinsic_v2f64(<2 x double> %x, <2 x double> %y) { 1026 %a = call <2 x double> @llvm.minimum.v2f64(<2 x double> %x, <2 x double> %y) 1027 ret <2 x double> %a 1028} 1029 1030; CHECK-LABEL: max_intrinsic_v2f64: 1031; NO-SIMD128-NOT: f64x2 1032; SIMD128-NEXT: .param v128, v128{{$}} 1033; SIMD128-NEXT: .result v128{{$}} 1034; SIMD128-NEXT: f64x2.max $push[[R:[0-9]+]]=, $0, $1{{$}} 1035; SIMD128-NEXT: return $pop[[R]]{{$}} 1036declare <2 x double> @llvm.maximum.v2f64(<2 x double>, <2 x double>) 1037define <2 x double> @max_intrinsic_v2f64(<2 x double> %x, <2 x double> %y) { 1038 %a = call <2 x double> @llvm.maximum.v2f64(<2 x double> %x, <2 x double> %y) 1039 ret <2 x double> %a 1040} 1041 1042; CHECK-LABEL: add_v2f64: 1043; NO-SIMD128-NOT: f64x2 1044; SIMD128-VM-NOT: f62x2 1045; SIMD128-NEXT: .param v128, v128{{$}} 1046; SIMD128-NEXT: .result v128{{$}} 1047; SIMD128-NEXT: f64x2.add $push[[R:[0-9]+]]=, $0, $1{{$}} 1048; SIMD128-NEXT: return $pop[[R]]{{$}} 1049define <2 x double> @add_v2f64(<2 x double> %x, <2 x double> %y) { 1050 %a = fadd <2 x double> %x, %y 1051 ret <2 x double> %a 1052} 1053 1054; CHECK-LABEL: sub_v2f64: 1055; NO-SIMD128-NOT: f64x2 1056; SIMD128-VM-NOT: f62x2 1057; SIMD128-NEXT: .param v128, v128{{$}} 1058; SIMD128-NEXT: .result v128{{$}} 1059; SIMD128-NEXT: f64x2.sub $push[[R:[0-9]+]]=, $0, $1{{$}} 1060; SIMD128-NEXT: return $pop[[R]]{{$}} 1061define <2 x double> @sub_v2f64(<2 x double> %x, <2 x double> %y) { 1062 %a = fsub <2 x double> %x, %y 1063 ret <2 x double> %a 1064} 1065 1066; CHECK-LABEL: div_v2f64: 1067; NO-SIMD128-NOT: f64x2 1068; SIMD128-VM-NOT: f62x2 1069; SIMD128-NEXT: .param v128, v128{{$}} 1070; SIMD128-NEXT: .result v128{{$}} 1071; SIMD128-NEXT: f64x2.div $push[[R:[0-9]+]]=, $0, $1{{$}} 1072; SIMD128-NEXT: return $pop[[R]]{{$}} 1073define <2 x double> @div_v2f64(<2 x double> %x, <2 x double> %y) { 1074 %a = fdiv <2 x double> %x, %y 1075 ret <2 x double> %a 1076} 1077 1078; CHECK-LABEL: mul_v2f64: 1079; NO-SIMD128-NOT: f64x2 1080; SIMD128-VM-NOT: f62x2 1081; SIMD128-NEXT: .param v128, v128{{$}} 1082; SIMD128-NEXT: .result v128{{$}} 1083; SIMD128-NEXT: f64x2.mul $push[[R:[0-9]+]]=, $0, $1{{$}} 1084; SIMD128-NEXT: return $pop[[R]]{{$}} 1085define <2 x double> @mul_v2f64(<2 x double> %x, <2 x double> %y) { 1086 %a = fmul <2 x double> %x, %y 1087 ret <2 x double> %a 1088} 1089 1090; CHECK-LABEL: sqrt_v2f64: 1091; NO-SIMD128-NOT: f64x2 1092; SIMD128-NEXT: .param v128{{$}} 1093; SIMD128-NEXT: .result v128{{$}} 1094; SIMD128-NEXT: f64x2.sqrt $push[[R:[0-9]+]]=, $0{{$}} 1095; SIMD128-NEXT: return $pop[[R]]{{$}} 1096declare <2 x double> @llvm.sqrt.v2f64(<2 x double> %x) 1097define <2 x double> @sqrt_v2f64(<2 x double> %x) { 1098 %a = call <2 x double> @llvm.sqrt.v2f64(<2 x double> %x) 1099 ret <2 x double> %a 1100} 1101