Skip to content

Commit a3f974f

Browse files
committed
[WebAssembly] SIMD bitmask intrinsics and builtin functions
Summary: These experimental new instructions are proposed in WebAssembly/simd#201. Reviewers: aheejin Subscribers: dschuff, sbc100, jgravelle-google, hiraditya, sunfish, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D76397
1 parent 678da7b commit a3f974f

File tree

7 files changed

+85
-0
lines changed

7 files changed

+85
-0
lines changed

clang/include/clang/Basic/BuiltinsWebAssembly.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ TARGET_BUILTIN(__builtin_wasm_all_true_i16x8, "iV8s", "nc", "simd128")
125125
TARGET_BUILTIN(__builtin_wasm_all_true_i32x4, "iV4i", "nc", "simd128")
126126
TARGET_BUILTIN(__builtin_wasm_all_true_i64x2, "iV2LLi", "nc", "unimplemented-simd128")
127127

128+
TARGET_BUILTIN(__builtin_wasm_bitmask_i8x16, "iV16c", "nc", "simd128")
129+
TARGET_BUILTIN(__builtin_wasm_bitmask_i16x8, "iV8s", "nc", "simd128")
130+
TARGET_BUILTIN(__builtin_wasm_bitmask_i32x4, "iV4i", "nc", "simd128")
131+
128132
TARGET_BUILTIN(__builtin_wasm_abs_f32x4, "V4fV4f", "nc", "simd128")
129133
TARGET_BUILTIN(__builtin_wasm_abs_f64x2, "V2dV2d", "nc", "simd128")
130134

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15142,6 +15142,14 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
1514215142
Function *Callee = CGM.getIntrinsic(IntNo, Vec->getType());
1514315143
return Builder.CreateCall(Callee, {Vec});
1514415144
}
15145+
case WebAssembly::BI__builtin_wasm_bitmask_i8x16:
15146+
case WebAssembly::BI__builtin_wasm_bitmask_i16x8:
15147+
case WebAssembly::BI__builtin_wasm_bitmask_i32x4: {
15148+
Value *Vec = EmitScalarExpr(E->getArg(0));
15149+
Function *Callee =
15150+
CGM.getIntrinsic(Intrinsic::wasm_bitmask, Vec->getType());
15151+
return Builder.CreateCall(Callee, {Vec});
15152+
}
1514515153
case WebAssembly::BI__builtin_wasm_abs_f32x4:
1514615154
case WebAssembly::BI__builtin_wasm_abs_f64x2: {
1514715155
Value *Vec = EmitScalarExpr(E->getArg(0));

clang/test/CodeGen/builtins-wasm.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,24 @@ int all_true_i64x2(i64x2 x) {
511511
// WEBASSEMBLY: ret
512512
}
513513

514+
int bitmask_i8x16(i8x16 x) {
515+
return __builtin_wasm_bitmask_i8x16(x);
516+
// WEBASSEMBLY: call i32 @llvm.wasm.bitmask.v16i8(<16 x i8> %x)
517+
// WEBASSEMBLY: ret
518+
}
519+
520+
int bitmask_i16x8(i16x8 x) {
521+
return __builtin_wasm_bitmask_i16x8(x);
522+
// WEBASSEMBLY: call i32 @llvm.wasm.bitmask.v8i16(<8 x i16> %x)
523+
// WEBASSEMBLY: ret
524+
}
525+
526+
int bitmask_i32x4(i32x4 x) {
527+
return __builtin_wasm_bitmask_i32x4(x);
528+
// WEBASSEMBLY: call i32 @llvm.wasm.bitmask.v4i32(<4 x i32> %x)
529+
// WEBASSEMBLY: ret
530+
}
531+
514532
f32x4 abs_f32x4(f32x4 x) {
515533
return __builtin_wasm_abs_f32x4(x);
516534
// WEBASSEMBLY: call <4 x float> @llvm.fabs.v4f32(<4 x float> %x)

llvm/include/llvm/IR/IntrinsicsWebAssembly.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ def int_wasm_alltrue :
129129
Intrinsic<[llvm_i32_ty],
130130
[llvm_anyvector_ty],
131131
[IntrNoMem, IntrSpeculatable]>;
132+
def int_wasm_bitmask :
133+
Intrinsic<[llvm_i32_ty],
134+
[llvm_anyvector_ty],
135+
[IntrNoMem, IntrSpeculatable]>;
132136
def int_wasm_qfma :
133137
Intrinsic<[llvm_anyvector_ty],
134138
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],

llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,18 @@ def : Pat<(i32 (seteq
606606
(i32 (!cast<NI>(reduction[1]#"_"#ty) (ty V128:$x)))>;
607607
}
608608

609+
multiclass SIMDBitmask<ValueType vec_t, string vec, bits<32> simdop> {
610+
defm _#vec_t : SIMD_I<(outs I32:$dst), (ins V128:$vec), (outs), (ins),
611+
[(set I32:$dst,
612+
(i32 (int_wasm_bitmask (vec_t V128:$vec)))
613+
)],
614+
vec#".bitmask\t$dst, $vec", vec#".bitmask", simdop>;
615+
}
616+
617+
defm BITMASK : SIMDBitmask<v16i8, "i8x16", 228>;
618+
defm BITMASK : SIMDBitmask<v8i16, "i16x8", 229>;
619+
defm BITMASK : SIMDBitmask<v4i32, "i32x4", 230>;
620+
609621
//===----------------------------------------------------------------------===//
610622
// Bit shifts
611623
//===----------------------------------------------------------------------===//

llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,16 @@ define i32 @all_v16i8(<16 x i8> %x) {
9595
ret i32 %a
9696
}
9797

98+
; CHECK-LABEL: bitmask_v16i8:
99+
; SIMD128-NEXT: .functype bitmask_v16i8 (v128) -> (i32){{$}}
100+
; SIMD128-NEXT: i8x16.bitmask $push[[R:[0-9]+]]=, $0{{$}}
101+
; SIMD128-NEXT: return $pop[[R]]{{$}}
102+
declare i32 @llvm.wasm.bitmask.v16i8(<16 x i8>)
103+
define i32 @bitmask_v16i8(<16 x i8> %x) {
104+
%a = call i32 @llvm.wasm.bitmask.v16i8(<16 x i8> %x)
105+
ret i32 %a
106+
}
107+
98108
; CHECK-LABEL: bitselect_v16i8:
99109
; SIMD128-NEXT: .functype bitselect_v16i8 (v128, v128, v128) -> (v128){{$}}
100110
; SIMD128-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $0, $1, $2{{$}}
@@ -208,6 +218,16 @@ define i32 @all_v8i16(<8 x i16> %x) {
208218
ret i32 %a
209219
}
210220

221+
; CHECK-LABEL: bitmask_v8i16:
222+
; SIMD128-NEXT: .functype bitmask_v8i16 (v128) -> (i32){{$}}
223+
; SIMD128-NEXT: i16x8.bitmask $push[[R:[0-9]+]]=, $0{{$}}
224+
; SIMD128-NEXT: return $pop[[R]]{{$}}
225+
declare i32 @llvm.wasm.bitmask.v8i16(<8 x i16>)
226+
define i32 @bitmask_v8i16(<8 x i16> %x) {
227+
%a = call i32 @llvm.wasm.bitmask.v8i16(<8 x i16> %x)
228+
ret i32 %a
229+
}
230+
211231
; CHECK-LABEL: bitselect_v8i16:
212232
; SIMD128-NEXT: .functype bitselect_v8i16 (v128, v128, v128) -> (v128){{$}}
213233
; SIMD128-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $0, $1, $2{{$}}
@@ -317,6 +337,16 @@ define i32 @all_v4i32(<4 x i32> %x) {
317337
ret i32 %a
318338
}
319339

340+
; CHECK-LABEL: bitmask_v4i32:
341+
; SIMD128-NEXT: .functype bitmask_v4i32 (v128) -> (i32){{$}}
342+
; SIMD128-NEXT: i32x4.bitmask $push[[R:[0-9]+]]=, $0{{$}}
343+
; SIMD128-NEXT: return $pop[[R]]{{$}}
344+
declare i32 @llvm.wasm.bitmask.v4i32(<4 x i32>)
345+
define i32 @bitmask_v4i32(<4 x i32> %x) {
346+
%a = call i32 @llvm.wasm.bitmask.v4i32(<4 x i32> %x)
347+
ret i32 %a
348+
}
349+
320350
; CHECK-LABEL: bitselect_v4i32:
321351
; SIMD128-NEXT: .functype bitselect_v4i32 (v128, v128, v128) -> (v128){{$}}
322352
; SIMD128-NEXT: v128.bitselect $push[[R:[0-9]+]]=, $0, $1, $2{{$}}

llvm/test/MC/WebAssembly/simd-encodings.s

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,4 +580,13 @@ main:
580580
# CHECK: i32x4.dot_i16x8_s # encoding: [0xfd,0xdb,0x01]
581581
i32x4.dot_i16x8_s
582582

583+
# CHECK: i8x16.bitmask # encoding: [0xfd,0xe4,0x01]
584+
i8x16.bitmask
585+
586+
# CHECK: i16x8.bitmask # encoding: [0xfd,0xe5,0x01]
587+
i16x8.bitmask
588+
589+
# CHECK: i32x4.bitmask # encoding: [0xfd,0xe6,0x01]
590+
i32x4.bitmask
591+
583592
end_function

0 commit comments

Comments
 (0)