1; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+simd128 | FileCheck %s 2 3; Tests that redundant masking and conversions are folded out 4; following SIMD reduction instructions. 5 6target triple = "wasm32-unknown-unknown" 7 8; ============================================================================== 9; 16 x i8 10; ============================================================================== 11declare i32 @llvm.wasm.anytrue.v16i8(<16 x i8>) 12declare i32 @llvm.wasm.alltrue.v16i8(<16 x i8>) 13 14; CHECK-LABEL: any_v16i8_trunc: 15; CHECK-NEXT: .functype any_v16i8_trunc (v128) -> (i32){{$}} 16; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}} 17; CHECK-NEXT: return $pop[[R]]{{$}} 18define i32 @any_v16i8_trunc(<16 x i8> %x) { 19 %a = call i32 @llvm.wasm.anytrue.v16i8(<16 x i8> %x) 20 %b = trunc i32 %a to i1 21 %c = zext i1 %b to i32 22 ret i32 %c 23} 24 25; CHECK-LABEL: any_v16i8_ne: 26; CHECK-NEXT: .functype any_v16i8_ne (v128) -> (i32){{$}} 27; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}} 28; CHECK-NEXT: return $pop[[R]]{{$}} 29define i32 @any_v16i8_ne(<16 x i8> %x) { 30 %a = call i32 @llvm.wasm.anytrue.v16i8(<16 x i8> %x) 31 %b = icmp ne i32 %a, 0 32 %c = zext i1 %b to i32 33 ret i32 %c 34} 35 36; CHECK-LABEL: any_v16i8_eq: 37; CHECK-NEXT: .functype any_v16i8_eq (v128) -> (i32){{$}} 38; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}} 39; CHECK-NEXT: return $pop[[R]]{{$}} 40define i32 @any_v16i8_eq(<16 x i8> %x) { 41 %a = call i32 @llvm.wasm.anytrue.v16i8(<16 x i8> %x) 42 %b = icmp eq i32 %a, 1 43 %c = zext i1 %b to i32 44 ret i32 %c 45} 46 47; CHECK-LABEL: all_v16i8_trunc: 48; CHECK-NEXT: .functype all_v16i8_trunc (v128) -> (i32){{$}} 49; CHECK-NEXT: i8x16.all_true $push[[R:[0-9]+]]=, $0{{$}} 50; CHECK-NEXT: return $pop[[R]]{{$}} 51define i32 @all_v16i8_trunc(<16 x i8> %x) { 52 %a = call i32 @llvm.wasm.alltrue.v16i8(<16 x i8> %x) 53 %b = trunc i32 %a to i1 54 %c = zext i1 %b to i32 55 ret i32 %c 56} 57 58; CHECK-LABEL: all_v16i8_ne: 59; CHECK-NEXT: .functype all_v16i8_ne (v128) -> (i32){{$}} 60; CHECK-NEXT: i8x16.all_true $push[[R:[0-9]+]]=, $0{{$}} 61; CHECK-NEXT: return $pop[[R]]{{$}} 62define i32 @all_v16i8_ne(<16 x i8> %x) { 63 %a = call i32 @llvm.wasm.alltrue.v16i8(<16 x i8> %x) 64 %b = icmp ne i32 %a, 0 65 %c = zext i1 %b to i32 66 ret i32 %c 67} 68 69; CHECK-LABEL: all_v16i8_eq: 70; CHECK-NEXT: .functype all_v16i8_eq (v128) -> (i32){{$}} 71; CHECK-NEXT: i8x16.all_true $push[[R:[0-9]+]]=, $0{{$}} 72; CHECK-NEXT: return $pop[[R]]{{$}} 73define i32 @all_v16i8_eq(<16 x i8> %x) { 74 %a = call i32 @llvm.wasm.alltrue.v16i8(<16 x i8> %x) 75 %b = icmp eq i32 %a, 1 76 %c = zext i1 %b to i32 77 ret i32 %c 78} 79 80; ============================================================================== 81; 8 x i16 82; ============================================================================== 83declare i32 @llvm.wasm.anytrue.v8i16(<8 x i16>) 84declare i32 @llvm.wasm.alltrue.v8i16(<8 x i16>) 85 86; CHECK-LABEL: any_v8i16_trunc: 87; CHECK-NEXT: .functype any_v8i16_trunc (v128) -> (i32){{$}} 88; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}} 89; CHECK-NEXT: return $pop[[R]]{{$}} 90define i32 @any_v8i16_trunc(<8 x i16> %x) { 91 %a = call i32 @llvm.wasm.anytrue.v8i16(<8 x i16> %x) 92 %b = trunc i32 %a to i1 93 %c = zext i1 %b to i32 94 ret i32 %c 95} 96 97; CHECK-LABEL: any_v8i16_ne: 98; CHECK-NEXT: .functype any_v8i16_ne (v128) -> (i32){{$}} 99; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}} 100; CHECK-NEXT: return $pop[[R]]{{$}} 101define i32 @any_v8i16_ne(<8 x i16> %x) { 102 %a = call i32 @llvm.wasm.anytrue.v8i16(<8 x i16> %x) 103 %b = icmp ne i32 %a, 0 104 %c = zext i1 %b to i32 105 ret i32 %c 106} 107 108; CHECK-LABEL: any_v8i16_eq: 109; CHECK-NEXT: .functype any_v8i16_eq (v128) -> (i32){{$}} 110; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}} 111; CHECK-NEXT: return $pop[[R]]{{$}} 112define i32 @any_v8i16_eq(<8 x i16> %x) { 113 %a = call i32 @llvm.wasm.anytrue.v8i16(<8 x i16> %x) 114 %b = icmp eq i32 %a, 1 115 %c = zext i1 %b to i32 116 ret i32 %c 117} 118 119; CHECK-LABEL: all_v8i16_trunc: 120; CHECK-NEXT: .functype all_v8i16_trunc (v128) -> (i32){{$}} 121; CHECK-NEXT: i16x8.all_true $push[[R:[0-9]+]]=, $0{{$}} 122; CHECK-NEXT: return $pop[[R]]{{$}} 123define i32 @all_v8i16_trunc(<8 x i16> %x) { 124 %a = call i32 @llvm.wasm.alltrue.v8i16(<8 x i16> %x) 125 %b = trunc i32 %a to i1 126 %c = zext i1 %b to i32 127 ret i32 %c 128} 129 130; CHECK-LABEL: all_v8i16_ne: 131; CHECK-NEXT: .functype all_v8i16_ne (v128) -> (i32){{$}} 132; CHECK-NEXT: i16x8.all_true $push[[R:[0-9]+]]=, $0{{$}} 133; CHECK-NEXT: return $pop[[R]]{{$}} 134define i32 @all_v8i16_ne(<8 x i16> %x) { 135 %a = call i32 @llvm.wasm.alltrue.v8i16(<8 x i16> %x) 136 %b = icmp ne i32 %a, 0 137 %c = zext i1 %b to i32 138 ret i32 %c 139} 140 141; CHECK-LABEL: all_v8i16_eq: 142; CHECK-NEXT: .functype all_v8i16_eq (v128) -> (i32){{$}} 143; CHECK-NEXT: i16x8.all_true $push[[R:[0-9]+]]=, $0{{$}} 144; CHECK-NEXT: return $pop[[R]]{{$}} 145define i32 @all_v8i16_eq(<8 x i16> %x) { 146 %a = call i32 @llvm.wasm.alltrue.v8i16(<8 x i16> %x) 147 %b = icmp eq i32 %a, 1 148 %c = zext i1 %b to i32 149 ret i32 %c 150} 151 152; ============================================================================== 153; 4 x i32 154; ============================================================================== 155declare i32 @llvm.wasm.anytrue.v4i32(<4 x i32>) 156declare i32 @llvm.wasm.alltrue.v4i32(<4 x i32>) 157 158; CHECK-LABEL: any_v4i32_trunc: 159; CHECK-NEXT: .functype any_v4i32_trunc (v128) -> (i32){{$}} 160; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}} 161; CHECK-NEXT: return $pop[[R]]{{$}} 162define i32 @any_v4i32_trunc(<4 x i32> %x) { 163 %a = call i32 @llvm.wasm.anytrue.v4i32(<4 x i32> %x) 164 %b = trunc i32 %a to i1 165 %c = zext i1 %b to i32 166 ret i32 %c 167} 168 169; CHECK-LABEL: any_v4i32_ne: 170; CHECK-NEXT: .functype any_v4i32_ne (v128) -> (i32){{$}} 171; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}} 172; CHECK-NEXT: return $pop[[R]]{{$}} 173define i32 @any_v4i32_ne(<4 x i32> %x) { 174 %a = call i32 @llvm.wasm.anytrue.v4i32(<4 x i32> %x) 175 %b = icmp ne i32 %a, 0 176 %c = zext i1 %b to i32 177 ret i32 %c 178} 179 180; CHECK-LABEL: any_v4i32_eq: 181; CHECK-NEXT: .functype any_v4i32_eq (v128) -> (i32){{$}} 182; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}} 183; CHECK-NEXT: return $pop[[R]]{{$}} 184define i32 @any_v4i32_eq(<4 x i32> %x) { 185 %a = call i32 @llvm.wasm.anytrue.v4i32(<4 x i32> %x) 186 %b = icmp eq i32 %a, 1 187 %c = zext i1 %b to i32 188 ret i32 %c 189} 190 191; CHECK-LABEL: all_v4i32_trunc: 192; CHECK-NEXT: .functype all_v4i32_trunc (v128) -> (i32){{$}} 193; CHECK-NEXT: i32x4.all_true $push[[R:[0-9]+]]=, $0{{$}} 194; CHECK-NEXT: return $pop[[R]]{{$}} 195define i32 @all_v4i32_trunc(<4 x i32> %x) { 196 %a = call i32 @llvm.wasm.alltrue.v4i32(<4 x i32> %x) 197 %b = trunc i32 %a to i1 198 %c = zext i1 %b to i32 199 ret i32 %c 200} 201 202; CHECK-LABEL: all_v4i32_ne: 203; CHECK-NEXT: .functype all_v4i32_ne (v128) -> (i32){{$}} 204; CHECK-NEXT: i32x4.all_true $push[[R:[0-9]+]]=, $0{{$}} 205; CHECK-NEXT: return $pop[[R]]{{$}} 206define i32 @all_v4i32_ne(<4 x i32> %x) { 207 %a = call i32 @llvm.wasm.alltrue.v4i32(<4 x i32> %x) 208 %b = icmp ne i32 %a, 0 209 %c = zext i1 %b to i32 210 ret i32 %c 211} 212 213; CHECK-LABEL: all_v4i32_eq: 214; CHECK-NEXT: .functype all_v4i32_eq (v128) -> (i32){{$}} 215; CHECK-NEXT: i32x4.all_true $push[[R:[0-9]+]]=, $0{{$}} 216; CHECK-NEXT: return $pop[[R]]{{$}} 217define i32 @all_v4i32_eq(<4 x i32> %x) { 218 %a = call i32 @llvm.wasm.alltrue.v4i32(<4 x i32> %x) 219 %b = icmp eq i32 %a, 1 220 %c = zext i1 %b to i32 221 ret i32 %c 222} 223 224; ============================================================================== 225; 2 x i64 226; ============================================================================== 227declare i32 @llvm.wasm.anytrue.v2i64(<2 x i64>) 228declare i32 @llvm.wasm.alltrue.v2i64(<2 x i64>) 229 230; CHECK-LABEL: any_v2i64_trunc: 231; CHECK-NEXT: .functype any_v2i64_trunc (v128) -> (i32){{$}} 232; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}} 233; CHECK-NEXT: return $pop[[R]]{{$}} 234define i32 @any_v2i64_trunc(<2 x i64> %x) { 235 %a = call i32 @llvm.wasm.anytrue.v2i64(<2 x i64> %x) 236 %b = trunc i32 %a to i1 237 %c = zext i1 %b to i32 238 ret i32 %c 239} 240 241; CHECK-LABEL: any_v2i64_ne: 242; CHECK-NEXT: .functype any_v2i64_ne (v128) -> (i32){{$}} 243; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}} 244; CHECK-NEXT: return $pop[[R]]{{$}} 245define i32 @any_v2i64_ne(<2 x i64> %x) { 246 %a = call i32 @llvm.wasm.anytrue.v2i64(<2 x i64> %x) 247 %b = icmp ne i32 %a, 0 248 %c = zext i1 %b to i32 249 ret i32 %c 250} 251 252; CHECK-LABEL: any_v2i64_eq: 253; CHECK-NEXT: .functype any_v2i64_eq (v128) -> (i32){{$}} 254; CHECK-NEXT: v128.any_true $push[[R:[0-9]+]]=, $0{{$}} 255; CHECK-NEXT: return $pop[[R]]{{$}} 256define i32 @any_v2i64_eq(<2 x i64> %x) { 257 %a = call i32 @llvm.wasm.anytrue.v2i64(<2 x i64> %x) 258 %b = icmp eq i32 %a, 1 259 %c = zext i1 %b to i32 260 ret i32 %c 261} 262 263; CHECK-LABEL: all_v2i64_trunc: 264; CHECK-NEXT: .functype all_v2i64_trunc (v128) -> (i32){{$}} 265; CHECK-NEXT: i64x2.all_true $push[[R:[0-9]+]]=, $0{{$}} 266; CHECK-NEXT: return $pop[[R]]{{$}} 267define i32 @all_v2i64_trunc(<2 x i64> %x) { 268 %a = call i32 @llvm.wasm.alltrue.v2i64(<2 x i64> %x) 269 %b = trunc i32 %a to i1 270 %c = zext i1 %b to i32 271 ret i32 %c 272} 273 274; CHECK-LABEL: all_v2i64_ne: 275; CHECK-NEXT: .functype all_v2i64_ne (v128) -> (i32){{$}} 276; CHECK-NEXT: i64x2.all_true $push[[R:[0-9]+]]=, $0{{$}} 277; CHECK-NEXT: return $pop[[R]]{{$}} 278define i32 @all_v2i64_ne(<2 x i64> %x) { 279 %a = call i32 @llvm.wasm.alltrue.v2i64(<2 x i64> %x) 280 %b = icmp ne i32 %a, 0 281 %c = zext i1 %b to i32 282 ret i32 %c 283} 284 285; CHECK-LABEL: all_v2i64_eq: 286; CHECK-NEXT: .functype all_v2i64_eq (v128) -> (i32){{$}} 287; CHECK-NEXT: i64x2.all_true $push[[R:[0-9]+]]=, $0{{$}} 288; CHECK-NEXT: return $pop[[R]]{{$}} 289define i32 @all_v2i64_eq(<2 x i64> %x) { 290 %a = call i32 @llvm.wasm.alltrue.v2i64(<2 x i64> %x) 291 %b = icmp eq i32 %a, 1 292 %c = zext i1 %b to i32 293 ret i32 %c 294} 295