1; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -wasm-enable-unimplemented-simd -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128 2; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -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 3 4; Test that SIMD128 intrinsics lower as expected. These intrinsics are 5; only expected to lower successfully if the simd128 attribute is 6; enabled and legal types are used. 7 8target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 9target triple = "wasm32-unknown-unknown" 10 11; ============================================================================== 12; 16 x i8 13; ============================================================================== 14; CHECK-LABEL: add_sat_s_v16i8: 15; SIMD128-NEXT: .functype add_sat_s_v16i8 (v128, v128) -> (v128){{$}} 16; SIMD128-NEXT: i8x16.add_saturate_s $push[[R:[0-9]+]]=, $0, $1{{$}} 17; SIMD128-NEXT: return $pop[[R]]{{$}} 18declare <16 x i8> @llvm.sadd.sat.v16i8(<16 x i8>, <16 x i8>) 19define <16 x i8> @add_sat_s_v16i8(<16 x i8> %x, <16 x i8> %y) { 20 %a = call <16 x i8> @llvm.sadd.sat.v16i8(<16 x i8> %x, <16 x i8> %y) 21 ret <16 x i8> %a 22} 23 24; CHECK-LABEL: add_sat_u_v16i8: 25; SIMD128-NEXT: .functype add_sat_u_v16i8 (v128, v128) -> (v128){{$}} 26; SIMD128-NEXT: i8x16.add_saturate_u $push[[R:[0-9]+]]=, $0, $1{{$}} 27; SIMD128-NEXT: return $pop[[R]]{{$}} 28declare <16 x i8> @llvm.uadd.sat.v16i8(<16 x i8>, <16 x i8>) 29define <16 x i8> @add_sat_u_v16i8(<16 x i8> %x, <16 x i8> %y) { 30 %a = call <16 x i8> @llvm.uadd.sat.v16i8(<16 x i8> %x, <16 x i8> %y) 31 ret <16 x i8> %a 32} 33 34; CHECK-LABEL: sub_sat_s_v16i8: 35; SIMD128-NEXT: .functype sub_sat_s_v16i8 (v128, v128) -> (v128){{$}} 36; SIMD128-NEXT: i8x16.sub_saturate_s $push[[R:[0-9]+]]=, $0, $1{{$}} 37; SIMD128-NEXT: return $pop[[R]]{{$}} 38declare <16 x i8> @llvm.wasm.sub.saturate.signed.v16i8(<16 x i8>, <16 x i8>) 39define <16 x i8> @sub_sat_s_v16i8(<16 x i8> %x, <16 x i8> %y) { 40 %a = call <16 x i8> @llvm.wasm.sub.saturate.signed.v16i8( 41 <16 x i8> %x, <16 x i8> %y 42 ) 43 ret <16 x i8> %a 44} 45 46; CHECK-LABEL: sub_sat_u_v16i8: 47; SIMD128-NEXT: .functype sub_sat_u_v16i8 (v128, v128) -> (v128){{$}} 48; SIMD128-NEXT: i8x16.sub_saturate_u $push[[R:[0-9]+]]=, $0, $1{{$}} 49; SIMD128-NEXT: return $pop[[R]]{{$}} 50declare <16 x i8> @llvm.wasm.sub.saturate.unsigned.v16i8(<16 x i8>, <16 x i8>) 51define <16 x i8> @sub_sat_u_v16i8(<16 x i8> %x, <16 x i8> %y) { 52 %a = call <16 x i8> @llvm.wasm.sub.saturate.unsigned.v16i8( 53 <16 x i8> %x, <16 x i8> %y 54 ) 55 ret <16 x i8> %a 56} 57 58; CHECK-LABEL: any_v16i8: 59; SIMD128-NEXT: .functype any_v16i8 (v128) -> (i32){{$}} 60; SIMD128-NEXT: i8x16.any_true $push[[R:[0-9]+]]=, $0{{$}} 61; SIMD128-NEXT: return $pop[[R]]{{$}} 62declare i32 @llvm.wasm.anytrue.v16i8(<16 x i8>) 63define i32 @any_v16i8(<16 x i8> %x) { 64 %a = call i32 @llvm.wasm.anytrue.v16i8(<16 x i8> %x) 65 ret i32 %a 66} 67 68; CHECK-LABEL: all_v16i8: 69; SIMD128-NEXT: .functype all_v16i8 (v128) -> (i32){{$}} 70; SIMD128-NEXT: i8x16.all_true $push[[R:[0-9]+]]=, $0{{$}} 71; SIMD128-NEXT: return $pop[[R]]{{$}} 72declare i32 @llvm.wasm.alltrue.v16i8(<16 x i8>) 73define i32 @all_v16i8(<16 x i8> %x) { 74 %a = call i32 @llvm.wasm.alltrue.v16i8(<16 x i8> %x) 75 ret i32 %a 76} 77 78; CHECK-LABEL: bitselect_v16i8: 79; SIMD128-NEXT: .functype bitselect_v16i8 (v128, v128, v128) -> (v128){{$}} 80; SIMD128-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}} 81; SIMD128-NEXT: return $pop[[R]]{{$}} 82declare <16 x i8> @llvm.wasm.bitselect.v16i8(<16 x i8>, <16 x i8>, <16 x i8>) 83define <16 x i8> @bitselect_v16i8(<16 x i8> %c, <16 x i8> %v1, <16 x i8> %v2) { 84 %a = call <16 x i8> @llvm.wasm.bitselect.v16i8( 85 <16 x i8> %c, <16 x i8> %v1, <16 x i8> %v2 86 ) 87 ret <16 x i8> %a 88} 89 90; ============================================================================== 91; 8 x i16 92; ============================================================================== 93; CHECK-LABEL: add_sat_s_v8i16: 94; SIMD128-NEXT: .functype add_sat_s_v8i16 (v128, v128) -> (v128){{$}} 95; SIMD128-NEXT: i16x8.add_saturate_s $push[[R:[0-9]+]]=, $0, $1{{$}} 96; SIMD128-NEXT: return $pop[[R]]{{$}} 97declare <8 x i16> @llvm.sadd.sat.v8i16(<8 x i16>, <8 x i16>) 98define <8 x i16> @add_sat_s_v8i16(<8 x i16> %x, <8 x i16> %y) { 99 %a = call <8 x i16> @llvm.sadd.sat.v8i16(<8 x i16> %x, <8 x i16> %y) 100 ret <8 x i16> %a 101} 102 103; CHECK-LABEL: add_sat_u_v8i16: 104; SIMD128-NEXT: .functype add_sat_u_v8i16 (v128, v128) -> (v128){{$}} 105; SIMD128-NEXT: i16x8.add_saturate_u $push[[R:[0-9]+]]=, $0, $1{{$}} 106; SIMD128-NEXT: return $pop[[R]]{{$}} 107declare <8 x i16> @llvm.uadd.sat.v8i16(<8 x i16>, <8 x i16>) 108define <8 x i16> @add_sat_u_v8i16(<8 x i16> %x, <8 x i16> %y) { 109 %a = call <8 x i16> @llvm.uadd.sat.v8i16(<8 x i16> %x, <8 x i16> %y) 110 ret <8 x i16> %a 111} 112 113; CHECK-LABEL: sub_sat_s_v8i16: 114; SIMD128-NEXT: .functype sub_sat_s_v8i16 (v128, v128) -> (v128){{$}} 115; SIMD128-NEXT: i16x8.sub_saturate_s $push[[R:[0-9]+]]=, $0, $1{{$}} 116; SIMD128-NEXT: return $pop[[R]]{{$}} 117declare <8 x i16> @llvm.wasm.sub.saturate.signed.v8i16(<8 x i16>, <8 x i16>) 118define <8 x i16> @sub_sat_s_v8i16(<8 x i16> %x, <8 x i16> %y) { 119 %a = call <8 x i16> @llvm.wasm.sub.saturate.signed.v8i16( 120 <8 x i16> %x, <8 x i16> %y 121 ) 122 ret <8 x i16> %a 123} 124 125; CHECK-LABEL: sub_sat_u_v8i16: 126; SIMD128-NEXT: .functype sub_sat_u_v8i16 (v128, v128) -> (v128){{$}} 127; SIMD128-NEXT: i16x8.sub_saturate_u $push[[R:[0-9]+]]=, $0, $1{{$}} 128; SIMD128-NEXT: return $pop[[R]]{{$}} 129declare <8 x i16> @llvm.wasm.sub.saturate.unsigned.v8i16(<8 x i16>, <8 x i16>) 130define <8 x i16> @sub_sat_u_v8i16(<8 x i16> %x, <8 x i16> %y) { 131 %a = call <8 x i16> @llvm.wasm.sub.saturate.unsigned.v8i16( 132 <8 x i16> %x, <8 x i16> %y 133 ) 134 ret <8 x i16> %a 135} 136 137; CHECK-LABEL: any_v8i16: 138; SIMD128-NEXT: .functype any_v8i16 (v128) -> (i32){{$}} 139; SIMD128-NEXT: i16x8.any_true $push[[R:[0-9]+]]=, $0{{$}} 140; SIMD128-NEXT: return $pop[[R]]{{$}} 141declare i32 @llvm.wasm.anytrue.v8i16(<8 x i16>) 142define i32 @any_v8i16(<8 x i16> %x) { 143 %a = call i32 @llvm.wasm.anytrue.v8i16(<8 x i16> %x) 144 ret i32 %a 145} 146 147; CHECK-LABEL: all_v8i16: 148; SIMD128-NEXT: .functype all_v8i16 (v128) -> (i32){{$}} 149; SIMD128-NEXT: i16x8.all_true $push[[R:[0-9]+]]=, $0{{$}} 150; SIMD128-NEXT: return $pop[[R]]{{$}} 151declare i32 @llvm.wasm.alltrue.v8i16(<8 x i16>) 152define i32 @all_v8i16(<8 x i16> %x) { 153 %a = call i32 @llvm.wasm.alltrue.v8i16(<8 x i16> %x) 154 ret i32 %a 155} 156 157; CHECK-LABEL: bitselect_v8i16: 158; SIMD128-NEXT: .functype bitselect_v8i16 (v128, v128, v128) -> (v128){{$}} 159; SIMD128-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}} 160; SIMD128-NEXT: return $pop[[R]]{{$}} 161declare <8 x i16> @llvm.wasm.bitselect.v8i16(<8 x i16>, <8 x i16>, <8 x i16>) 162define <8 x i16> @bitselect_v8i16(<8 x i16> %c, <8 x i16> %v1, <8 x i16> %v2) { 163 %a = call <8 x i16> @llvm.wasm.bitselect.v8i16( 164 <8 x i16> %c, <8 x i16> %v1, <8 x i16> %v2 165 ) 166 ret <8 x i16> %a 167} 168 169; ============================================================================== 170; 4 x i32 171; ============================================================================== 172; CHECK-LABEL: any_v4i32: 173; SIMD128-NEXT: .functype any_v4i32 (v128) -> (i32){{$}} 174; SIMD128-NEXT: i32x4.any_true $push[[R:[0-9]+]]=, $0{{$}} 175; SIMD128-NEXT: return $pop[[R]]{{$}} 176declare i32 @llvm.wasm.anytrue.v4i32(<4 x i32>) 177define i32 @any_v4i32(<4 x i32> %x) { 178 %a = call i32 @llvm.wasm.anytrue.v4i32(<4 x i32> %x) 179 ret i32 %a 180} 181 182; CHECK-LABEL: all_v4i32: 183; SIMD128-NEXT: .functype all_v4i32 (v128) -> (i32){{$}} 184; SIMD128-NEXT: i32x4.all_true $push[[R:[0-9]+]]=, $0{{$}} 185; SIMD128-NEXT: return $pop[[R]]{{$}} 186declare i32 @llvm.wasm.alltrue.v4i32(<4 x i32>) 187define i32 @all_v4i32(<4 x i32> %x) { 188 %a = call i32 @llvm.wasm.alltrue.v4i32(<4 x i32> %x) 189 ret i32 %a 190} 191 192; CHECK-LABEL: bitselect_v4i32: 193; SIMD128-NEXT: .functype bitselect_v4i32 (v128, v128, v128) -> (v128){{$}} 194; SIMD128-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}} 195; SIMD128-NEXT: return $pop[[R]]{{$}} 196declare <4 x i32> @llvm.wasm.bitselect.v4i32(<4 x i32>, <4 x i32>, <4 x i32>) 197define <4 x i32> @bitselect_v4i32(<4 x i32> %c, <4 x i32> %v1, <4 x i32> %v2) { 198 %a = call <4 x i32> @llvm.wasm.bitselect.v4i32( 199 <4 x i32> %c, <4 x i32> %v1, <4 x i32> %v2 200 ) 201 ret <4 x i32> %a 202} 203 204; CHECK-LABEL: trunc_sat_s_v4i32: 205; NO-SIMD128-NOT: f32x4 206; SIMD128-NEXT: .functype trunc_sat_s_v4i32 (v128) -> (v128){{$}} 207; SIMD128-NEXT: i32x4.trunc_sat_f32x4_s $push[[R:[0-9]+]]=, $0 208; SIMD128-NEXT: return $pop[[R]] 209declare <4 x i32> @llvm.wasm.trunc.saturate.signed.v4i32.v4f32(<4 x float>) 210define <4 x i32> @trunc_sat_s_v4i32(<4 x float> %x) { 211 %a = call <4 x i32> @llvm.wasm.trunc.saturate.signed.v4i32.v4f32(<4 x float> %x) 212 ret <4 x i32> %a 213} 214 215; CHECK-LABEL: trunc_sat_u_v4i32: 216; NO-SIMD128-NOT: f32x4 217; SIMD128-NEXT: .functype trunc_sat_u_v4i32 (v128) -> (v128){{$}} 218; SIMD128-NEXT: i32x4.trunc_sat_f32x4_u $push[[R:[0-9]+]]=, $0 219; SIMD128-NEXT: return $pop[[R]] 220declare <4 x i32> @llvm.wasm.trunc.saturate.unsigned.v4i32.v4f32(<4 x float>) 221define <4 x i32> @trunc_sat_u_v4i32(<4 x float> %x) { 222 %a = call <4 x i32> @llvm.wasm.trunc.saturate.unsigned.v4i32.v4f32(<4 x float> %x) 223 ret <4 x i32> %a 224} 225 226; ============================================================================== 227; 2 x i64 228; ============================================================================== 229; CHECK-LABEL: any_v2i64: 230; SIMD128-NEXT: .functype any_v2i64 (v128) -> (i32){{$}} 231; SIMD128-NEXT: i64x2.any_true $push[[R:[0-9]+]]=, $0{{$}} 232; SIMD128-NEXT: return $pop[[R]]{{$}} 233declare i32 @llvm.wasm.anytrue.v2i64(<2 x i64>) 234define i32 @any_v2i64(<2 x i64> %x) { 235 %a = call i32 @llvm.wasm.anytrue.v2i64(<2 x i64> %x) 236 ret i32 %a 237} 238 239; CHECK-LABEL: all_v2i64: 240; SIMD128-NEXT: .functype all_v2i64 (v128) -> (i32){{$}} 241; SIMD128-NEXT: i64x2.all_true $push[[R:[0-9]+]]=, $0{{$}} 242; SIMD128-NEXT: return $pop[[R]]{{$}} 243declare i32 @llvm.wasm.alltrue.v2i64(<2 x i64>) 244define i32 @all_v2i64(<2 x i64> %x) { 245 %a = call i32 @llvm.wasm.alltrue.v2i64(<2 x i64> %x) 246 ret i32 %a 247} 248 249; CHECK-LABEL: bitselect_v2i64: 250; SIMD128-NEXT: .functype bitselect_v2i64 (v128, v128, v128) -> (v128){{$}} 251; SIMD128-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}} 252; SIMD128-NEXT: return $pop[[R]]{{$}} 253declare <2 x i64> @llvm.wasm.bitselect.v2i64(<2 x i64>, <2 x i64>, <2 x i64>) 254define <2 x i64> @bitselect_v2i64(<2 x i64> %c, <2 x i64> %v1, <2 x i64> %v2) { 255 %a = call <2 x i64> @llvm.wasm.bitselect.v2i64( 256 <2 x i64> %c, <2 x i64> %v1, <2 x i64> %v2 257 ) 258 ret <2 x i64> %a 259} 260 261; CHECK-LABEL: trunc_sat_s_v2i64: 262; NO-SIMD128-NOT: f32x4 263; SIMD128-NEXT: .functype trunc_sat_s_v2i64 (v128) -> (v128){{$}} 264; SIMD128-NEXT: i64x2.trunc_sat_f64x2_s $push[[R:[0-9]+]]=, $0 265; SIMD128-NEXT: return $pop[[R]] 266declare <2 x i64> @llvm.wasm.trunc.saturate.signed.v2i64.v2f64(<2 x double>) 267define <2 x i64> @trunc_sat_s_v2i64(<2 x double> %x) { 268 %a = call <2 x i64> @llvm.wasm.trunc.saturate.signed.v2i64.v2f64(<2 x double> %x) 269 ret <2 x i64> %a 270} 271 272; CHECK-LABEL: trunc_sat_u_v2i64: 273; NO-SIMD128-NOT: f32x4 274; SIMD128-NEXT: .functype trunc_sat_u_v2i64 (v128) -> (v128){{$}} 275; SIMD128-NEXT: i64x2.trunc_sat_f64x2_u $push[[R:[0-9]+]]=, $0 276; SIMD128-NEXT: return $pop[[R]] 277declare <2 x i64> @llvm.wasm.trunc.saturate.unsigned.v2i64.v2f64(<2 x double>) 278define <2 x i64> @trunc_sat_u_v2i64(<2 x double> %x) { 279 %a = call <2 x i64> @llvm.wasm.trunc.saturate.unsigned.v2i64.v2f64(<2 x double> %x) 280 ret <2 x i64> %a 281} 282 283; ============================================================================== 284; 4 x f32 285; ============================================================================== 286; CHECK-LABEL: bitselect_v4f32: 287; SIMD128-NEXT: .functype bitselect_v4f32 (v128, v128, v128) -> (v128){{$}} 288; SIMD128-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}} 289; SIMD128-NEXT: return $pop[[R]]{{$}} 290declare <4 x float> @llvm.wasm.bitselect.v4f32(<4 x float>, <4 x float>, <4 x float>) 291define <4 x float> @bitselect_v4f32(<4 x float> %c, <4 x float> %v1, <4 x float> %v2) { 292 %a = call <4 x float> @llvm.wasm.bitselect.v4f32( 293 <4 x float> %c, <4 x float> %v1, <4 x float> %v2 294 ) 295 ret <4 x float> %a 296} 297 298; ============================================================================== 299; 2 x f64 300; ============================================================================== 301; CHECK-LABEL: bitselect_v2f64: 302; SIMD128-NEXT: .functype bitselect_v2f64 (v128, v128, v128) -> (v128){{$}} 303; SIMD128-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $1, $2, $0{{$}} 304; SIMD128-NEXT: return $pop[[R]]{{$}} 305declare <2 x double> @llvm.wasm.bitselect.v2f64(<2 x double>, <2 x double>, <2 x double>) 306define <2 x double> @bitselect_v2f64(<2 x double> %c, <2 x double> %v1, <2 x double> %v2) { 307 %a = call <2 x double> @llvm.wasm.bitselect.v2f64( 308 <2 x double> %c, <2 x double> %v1, <2 x double> %v2 309 ) 310 ret <2 x double> %a 311} 312