Skip to content

Commit

Permalink
[WebAssembly] Codegen for i64x2.extend_{low,high}_i32x4_{s,u}
Browse files Browse the repository at this point in the history
Removes the builtins and intrinsics used to opt in to using these instructions
and replaces them with normal ISel patterns now that they are no longer
prototypes.

Differential Revision: https://reviews.llvm.org/D100402
  • Loading branch information
tlively authored and alexcrichton committed Apr 19, 2021
1 parent fd7d65a commit 6ffbea3
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 116 deletions.
5 changes: 0 additions & 5 deletions clang/include/clang/Basic/BuiltinsWebAssembly.def
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,6 @@ TARGET_BUILTIN(__builtin_wasm_narrow_u_i8x16_i16x8, "V16UcV8UsV8Us", "nc", "simd
TARGET_BUILTIN(__builtin_wasm_narrow_s_i16x8_i32x4, "V8sV4iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_narrow_u_i16x8_i32x4, "V8UsV4UiV4Ui", "nc", "simd128")

TARGET_BUILTIN(__builtin_wasm_extend_low_s_i32x4_i64x2, "V2LLiV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extend_high_s_i32x4_i64x2, "V2LLiV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extend_low_u_i32x4_i64x2, "V2LLUiV4Ui", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extend_high_u_i32x4_i64x2, "V2LLUiV4Ui", "nc", "simd128")

TARGET_BUILTIN(__builtin_wasm_trunc_sat_zero_s_f64x2_i32x4, "V4iV2d", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_trunc_sat_zero_u_f64x2_i32x4, "V4UiV2d", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_demote_zero_f64x2_f32x4, "V4fV2d", "nc", "simd128")
Expand Down
23 changes: 0 additions & 23 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17158,29 +17158,6 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
CGM.getIntrinsic(IntNo, {ConvertType(E->getType()), Low->getType()});
return Builder.CreateCall(Callee, {Low, High});
}
case WebAssembly::BI__builtin_wasm_extend_low_s_i32x4_i64x2:
case WebAssembly::BI__builtin_wasm_extend_high_s_i32x4_i64x2:
case WebAssembly::BI__builtin_wasm_extend_low_u_i32x4_i64x2:
case WebAssembly::BI__builtin_wasm_extend_high_u_i32x4_i64x2: {
Value *Vec = EmitScalarExpr(E->getArg(0));
unsigned IntNo;
switch (BuiltinID) {
case WebAssembly::BI__builtin_wasm_extend_low_s_i32x4_i64x2:
IntNo = Intrinsic::wasm_extend_low_signed;
break;
case WebAssembly::BI__builtin_wasm_extend_high_s_i32x4_i64x2:
IntNo = Intrinsic::wasm_extend_high_signed;
break;
case WebAssembly::BI__builtin_wasm_extend_low_u_i32x4_i64x2:
IntNo = Intrinsic::wasm_extend_low_unsigned;
break;
case WebAssembly::BI__builtin_wasm_extend_high_u_i32x4_i64x2:
IntNo = Intrinsic::wasm_extend_high_unsigned;
break;
}
Function *Callee = CGM.getIntrinsic(IntNo);
return Builder.CreateCall(Callee, Vec);
}
case WebAssembly::BI__builtin_wasm_trunc_sat_zero_s_f64x2_i32x4:
case WebAssembly::BI__builtin_wasm_trunc_sat_zero_u_f64x2_i32x4: {
Value *Vec = EmitScalarExpr(E->getArg(0));
Expand Down
24 changes: 0 additions & 24 deletions clang/test/CodeGen/builtins-wasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -890,30 +890,6 @@ u16x8 narrow_u_i16x8_i32x4(u32x4 low, u32x4 high) {
// WEBASSEMBLY: ret
}

i64x2 extend_low_s_i32x4_i64x2(i32x4 x) {
return __builtin_wasm_extend_low_s_i32x4_i64x2(x);
// WEBASSEMBLY: call <2 x i64> @llvm.wasm.extend.low.signed(<4 x i32> %x)
// WEBASSEMBLY: ret
}

i64x2 extend_high_s_i32x4_i64x2(i32x4 x) {
return __builtin_wasm_extend_high_s_i32x4_i64x2(x);
// WEBASSEMBLY: call <2 x i64> @llvm.wasm.extend.high.signed(<4 x i32> %x)
// WEBASSEMBLY: ret
}

u64x2 extend_low_u_i32x4_i64x2(u32x4 x) {
return __builtin_wasm_extend_low_u_i32x4_i64x2(x);
// WEBASSEMBLY: call <2 x i64> @llvm.wasm.extend.low.unsigned(<4 x i32> %x)
// WEBASSEMBLY: ret
}

u64x2 extend_high_u_i32x4_i64x2(u32x4 x) {
return __builtin_wasm_extend_high_u_i32x4_i64x2(x);
// WEBASSEMBLY: call <2 x i64> @llvm.wasm.extend.high.unsigned(<4 x i32> %x)
// WEBASSEMBLY: ret
}

i32x4 trunc_sat_zero_s_f64x2_i32x4(f64x2 x) {
return __builtin_wasm_trunc_sat_zero_s_f64x2_i32x4(x);
// WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.sat.zero.signed(<2 x double> %x)
Expand Down
11 changes: 0 additions & 11 deletions llvm/include/llvm/IR/IntrinsicsWebAssembly.td
Original file line number Diff line number Diff line change
Expand Up @@ -157,17 +157,6 @@ def int_wasm_narrow_unsigned :
[llvm_anyvector_ty, LLVMMatchType<1>],
[IntrNoMem, IntrSpeculatable]>;

// TODO: Replace these intrinsics with normal ISel patterns once i32x4 to i64x2
// extending is merged to the proposal.
def int_wasm_extend_low_signed :
Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem, IntrSpeculatable]>;
def int_wasm_extend_high_signed :
Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem, IntrSpeculatable]>;
def int_wasm_extend_low_unsigned :
Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem, IntrSpeculatable]>;
def int_wasm_extend_high_unsigned :
Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty], [IntrNoMem, IntrSpeculatable]>;

def int_wasm_q15mulr_sat_signed :
Intrinsic<[llvm_v8i16_ty],
[llvm_v8i16_ty, llvm_v8i16_ty],
Expand Down
8 changes: 6 additions & 2 deletions llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1994,8 +1994,8 @@ performVectorExtendCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI) {
return SDValue();
auto Index = IndexNode->getZExtValue();

// Only v8i8 and v4i16 extracts can be widened, and only if the extracted
// subvector is the low or high half of its source.
// Only v8i8, v4i16, and v2i32 extracts can be widened, and only if the
// extracted subvector is the low or high half of its source.
EVT ResVT = N->getValueType(0);
if (ResVT == MVT::v8i16) {
if (Extract.getValueType() != MVT::v8i8 ||
Expand All @@ -2005,6 +2005,10 @@ performVectorExtendCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI) {
if (Extract.getValueType() != MVT::v4i16 ||
Source.getValueType() != MVT::v8i16 || (Index != 0 && Index != 4))
return SDValue();
} else if (ResVT == MVT::v2i64) {
if (Extract.getValueType() != MVT::v2i32 ||
Source.getValueType() != MVT::v4i32 || (Index != 0 && Index != 2))
return SDValue();
} else {
return SDValue();
}
Expand Down
14 changes: 3 additions & 11 deletions llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
Original file line number Diff line number Diff line change
Expand Up @@ -1138,17 +1138,9 @@ multiclass SIMDExtend<Vec vec, bits<32> baseInst> {
"extend_high_"#vec.split.prefix#"_u", !add(baseInst, 3)>;
}

defm "" : SIMDExtend<I16x8, 135>;
defm "" : SIMDExtend<I32x4, 167>;

defm "" : SIMDConvert<I64x2, I32x4, int_wasm_extend_low_signed,
"extend_low_i32x4_s", 199>;
defm "" : SIMDConvert<I64x2, I32x4, int_wasm_extend_high_signed,
"extend_high_i32x4_s", 200>;
defm "" : SIMDConvert<I64x2, I32x4, int_wasm_extend_low_unsigned,
"extend_low_i32x4_u", 201>;
defm "" : SIMDConvert<I64x2, I32x4, int_wasm_extend_high_unsigned,
"extend_high_i32x4_u", 202>;
defm "" : SIMDExtend<I16x8, 0x87>;
defm "" : SIMDExtend<I32x4, 0xa7>;
defm "" : SIMDExtend<I64x2, 0xc7>;

// Narrowing operations
multiclass SIMDNarrow<Vec vec, bits<32> baseInst> {
Expand Down
52 changes: 52 additions & 0 deletions llvm/test/CodeGen/WebAssembly/simd-extending.ll
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,58 @@ define <4 x i32> @extend_high_i16x8_u(<8 x i16> %v) {
ret <4 x i32> %extended
}

define <2 x i64> @extend_low_i32x4_s(<4 x i32> %v) {
; CHECK-LABEL: extend_low_i32x4_s:
; CHECK: .functype extend_low_i32x4_s (v128) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i64x2.extend_low_i32x4_s
; CHECK-NEXT: # fallthrough-return
%low = shufflevector <4 x i32> %v, <4 x i32> undef,
<2 x i32> <i32 0, i32 1>
%extended = sext <2 x i32> %low to <2 x i64>
ret <2 x i64> %extended
}

define <2 x i64> @extend_low_i32x4_u(<4 x i32> %v) {
; CHECK-LABEL: extend_low_i32x4_u:
; CHECK: .functype extend_low_i32x4_u (v128) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i64x2.extend_low_i32x4_u
; CHECK-NEXT: # fallthrough-return
%low = shufflevector <4 x i32> %v, <4 x i32> undef,
<2 x i32> <i32 0, i32 1>
%extended = zext <2 x i32> %low to <2 x i64>
ret <2 x i64> %extended
}

define <2 x i64> @extend_high_i32x4_s(<4 x i32> %v) {
; CHECK-LABEL: extend_high_i32x4_s:
; CHECK: .functype extend_high_i32x4_s (v128) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i64x2.extend_high_i32x4_s
; CHECK-NEXT: # fallthrough-return
%low = shufflevector <4 x i32> %v, <4 x i32> undef,
<2 x i32> <i32 2, i32 3>
%extended = sext <2 x i32> %low to <2 x i64>
ret <2 x i64> %extended
}

define <2 x i64> @extend_high_i32x4_u(<4 x i32> %v) {
; CHECK-LABEL: extend_high_i32x4_u:
; CHECK: .functype extend_high_i32x4_u (v128) -> (v128)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i64x2.extend_high_i32x4_u
; CHECK-NEXT: # fallthrough-return
%low = shufflevector <4 x i32> %v, <4 x i32> undef,
<2 x i32> <i32 2, i32 3>
%extended = zext <2 x i32> %low to <2 x i64>
ret <2 x i64> %extended
}

;; Also test that similar patterns with offsets not corresponding to
;; the low or high half are correctly expanded.

Expand Down
40 changes: 0 additions & 40 deletions llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll
Original file line number Diff line number Diff line change
Expand Up @@ -553,46 +553,6 @@ define <4 x i32> @trunc_sat_zero_unsigned_v4i32(<2 x double> %a) {
; ==============================================================================
; 2 x i64
; ==============================================================================
; CHECK-LABEL: extend_low_s_v2i64:
; CHECK-NEXT: .functype extend_low_s_v2i64 (v128) -> (v128){{$}}
; CHECK-NEXT: i64x2.extend_low_i32x4_s $push[[R:[0-9]+]]=, $0{{$}}
; CHECK-NEXT: return $pop[[R]]{{$}}
declare <2 x i64> @llvm.wasm.extend.low.signed(<4 x i32>)
define <2 x i64> @extend_low_s_v2i64(<4 x i32> %x) {
%a = call <2 x i64> @llvm.wasm.extend.low.signed(<4 x i32> %x)
ret <2 x i64> %a
}

; CHECK-LABEL: extend_high_s_v2i64:
; CHECK-NEXT: .functype extend_high_s_v2i64 (v128) -> (v128){{$}}
; CHECK-NEXT: i64x2.extend_high_i32x4_s $push[[R:[0-9]+]]=, $0{{$}}
; CHECK-NEXT: return $pop[[R]]{{$}}
declare <2 x i64> @llvm.wasm.extend.high.signed(<4 x i32>)
define <2 x i64> @extend_high_s_v2i64(<4 x i32> %x) {
%a = call <2 x i64> @llvm.wasm.extend.high.signed(<4 x i32> %x)
ret <2 x i64> %a
}

; CHECK-LABEL: extend_low_u_v2i64:
; CHECK-NEXT: .functype extend_low_u_v2i64 (v128) -> (v128){{$}}
; CHECK-NEXT: i64x2.extend_low_i32x4_u $push[[R:[0-9]+]]=, $0{{$}}
; CHECK-NEXT: return $pop[[R]]{{$}}
declare <2 x i64> @llvm.wasm.extend.low.unsigned(<4 x i32>)
define <2 x i64> @extend_low_u_v2i64(<4 x i32> %x) {
%a = call <2 x i64> @llvm.wasm.extend.low.unsigned(<4 x i32> %x)
ret <2 x i64> %a
}

; CHECK-LABEL: extend_high_u_v2i64:
; CHECK-NEXT: .functype extend_high_u_v2i64 (v128) -> (v128){{$}}
; CHECK-NEXT: i64x2.extend_high_i32x4_u $push[[R:[0-9]+]]=, $0{{$}}
; CHECK-NEXT: return $pop[[R]]{{$}}
declare <2 x i64> @llvm.wasm.extend.high.unsigned(<4 x i32>)
define <2 x i64> @extend_high_u_v2i64(<4 x i32> %x) {
%a = call <2 x i64> @llvm.wasm.extend.high.unsigned(<4 x i32> %x)
ret <2 x i64> %a
}

; CHECK-LABEL: extmul_low_s_v2i64:
; CHECK-NEXT: .functype extmul_low_s_v2i64 (v128, v128) -> (v128){{$}}
; CHECK-NEXT: i64x2.extmul_low_i32x4_s $push[[R:[0-9]+]]=, $0, $1{{$}}
Expand Down

0 comments on commit 6ffbea3

Please sign in to comment.