Skip to content

Commit 94585f6

Browse files
badumbatishaokblast
authored andcommitted
[WebAssembly] [Codegen] Add pattern for relaxed min max from fminimum/fmaximum over v4f32 and v2f64 (llvm#162948)
Related to llvm#55932
1 parent 07c440b commit 94585f6

File tree

4 files changed

+141
-0
lines changed

4 files changed

+141
-0
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,11 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
183183
for (auto T : {MVT::i32, MVT::i64})
184184
setOperationAction(Op, T, Custom);
185185

186+
if (Subtarget->hasRelaxedSIMD()) {
187+
setOperationAction(
188+
{ISD::FMINNUM, ISD::FMINIMUMNUM, ISD::FMAXNUM, ISD::FMAXIMUMNUM},
189+
{MVT::v4f32, MVT::v2f64}, Legal);
190+
}
186191
// SIMD-specific configuration
187192
if (Subtarget->hasSIMD128()) {
188193

llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1742,6 +1742,23 @@ defm SIMD_RELAXED_FMIN :
17421742
defm SIMD_RELAXED_FMAX :
17431743
RelaxedBinary<F64x2, int_wasm_relaxed_max, "relaxed_max", 0x110>;
17441744

1745+
let Predicates = [HasRelaxedSIMD] in {
1746+
foreach vec = [F32x4, F64x2] in {
1747+
defvar relaxed_min = !cast<NI>("SIMD_RELAXED_FMIN_"#vec);
1748+
defvar relaxed_max = !cast<NI>("SIMD_RELAXED_FMAX_"#vec);
1749+
1750+
// Transform standard fminimum/fmaximum to relaxed versions
1751+
def : Pat<(vec.vt (fminnum (vec.vt V128:$lhs), (vec.vt V128:$rhs))),
1752+
(relaxed_min V128:$lhs, V128:$rhs)>;
1753+
def : Pat<(vec.vt (fminimumnum (vec.vt V128:$lhs), (vec.vt V128:$rhs))),
1754+
(relaxed_min V128:$lhs, V128:$rhs)>;
1755+
def : Pat<(vec.vt (fmaxnum (vec.vt V128:$lhs), (vec.vt V128:$rhs))),
1756+
(relaxed_max V128:$lhs, V128:$rhs)>;
1757+
def : Pat<(vec.vt (fmaximumnum (vec.vt V128:$lhs), (vec.vt V128:$rhs))),
1758+
(relaxed_max V128:$lhs, V128:$rhs)>;
1759+
}
1760+
}
1761+
17451762
//===----------------------------------------------------------------------===//
17461763
// Relaxed rounding q15 multiplication
17471764
//===----------------------------------------------------------------------===//
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
2+
3+
; RUN: llc < %s -mtriple=wasm32-unknown-unknown -mattr=+simd128,+relaxed-simd | FileCheck %s
4+
5+
; Test that fmaxnum and fmaximumnum get transformed to relaxed_max
6+
7+
target triple = "wasm32"
8+
9+
define <4 x float> @test_maxnum_f32x4(<4 x float> %a, <4 x float> %b) {
10+
; CHECK-LABEL: test_maxnum_f32x4:
11+
; CHECK: .functype test_maxnum_f32x4 (v128, v128) -> (v128)
12+
; CHECK-NEXT: # %bb.0:
13+
; CHECK-NEXT: local.get 0
14+
; CHECK-NEXT: local.get 1
15+
; CHECK-NEXT: f32x4.relaxed_max
16+
; CHECK-NEXT: # fallthrough-return
17+
%result = call <4 x float> @llvm.maxnum.v4f32(<4 x float> %a, <4 x float> %b)
18+
ret <4 x float> %result
19+
}
20+
21+
define <4 x float> @test_maximumnum_f32x4(<4 x float> %a, <4 x float> %b) {
22+
; CHECK-LABEL: test_maximumnum_f32x4:
23+
; CHECK: .functype test_maximumnum_f32x4 (v128, v128) -> (v128)
24+
; CHECK-NEXT: # %bb.0:
25+
; CHECK-NEXT: local.get 0
26+
; CHECK-NEXT: local.get 1
27+
; CHECK-NEXT: f32x4.relaxed_max
28+
; CHECK-NEXT: # fallthrough-return
29+
%result = call <4 x float> @llvm.maximumnum.v4f32(<4 x float> %a, <4 x float> %b)
30+
ret <4 x float> %result
31+
}
32+
33+
define <2 x double> @test_maxnum_f64x2(<2 x double> %a, <2 x double> %b) {
34+
; CHECK-LABEL: test_maxnum_f64x2:
35+
; CHECK: .functype test_maxnum_f64x2 (v128, v128) -> (v128)
36+
; CHECK-NEXT: # %bb.0:
37+
; CHECK-NEXT: local.get 0
38+
; CHECK-NEXT: local.get 1
39+
; CHECK-NEXT: f64x2.relaxed_max
40+
; CHECK-NEXT: # fallthrough-return
41+
%result = call <2 x double> @llvm.maxnum.v2f64(<2 x double> %a, <2 x double> %b)
42+
ret <2 x double> %result
43+
}
44+
45+
define <2 x double> @test_minimumnum_f64x2(<2 x double> %a, <2 x double> %b) {
46+
; CHECK-LABEL: test_minimumnum_f64x2:
47+
; CHECK: .functype test_minimumnum_f64x2 (v128, v128) -> (v128)
48+
; CHECK-NEXT: # %bb.0:
49+
; CHECK-NEXT: local.get 0
50+
; CHECK-NEXT: local.get 1
51+
; CHECK-NEXT: f64x2.relaxed_max
52+
; CHECK-NEXT: # fallthrough-return
53+
%result = call <2 x double> @llvm.maximumnum.v2f64(<2 x double> %a, <2 x double> %b)
54+
ret <2 x double> %result
55+
}
56+
57+
declare <4 x float> @llvm.maxnum.v4f32(<4 x float>, <4 x float>)
58+
declare <4 x float> @llvm.maximumnum.v4f32(<4 x float>, <4 x float>)
59+
declare <2 x double> @llvm.maxnum.v2f64(<2 x double>, <2 x double>)
60+
declare <2 x double> @llvm.maximumnum.v2f64(<2 x double>, <2 x double>)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
2+
; RUN: llc < %s -mtriple=wasm32-unknown-unknown -mattr=+simd128,+relaxed-simd | FileCheck %s
3+
4+
; Test that fminnum and fminimumnum get transformed to relaxed_min
5+
6+
target triple = "wasm32"
7+
8+
define <4 x float> @test_minnum_f32x4(<4 x float> %a, <4 x float> %b) {
9+
; CHECK-LABEL: test_minnum_f32x4:
10+
; CHECK: .functype test_minnum_f32x4 (v128, v128) -> (v128)
11+
; CHECK-NEXT: # %bb.0:
12+
; CHECK-NEXT: local.get 0
13+
; CHECK-NEXT: local.get 1
14+
; CHECK-NEXT: f32x4.relaxed_min
15+
; CHECK-NEXT: # fallthrough-return
16+
%result = call <4 x float> @llvm.minnum.v4f32(<4 x float> %a, <4 x float> %b)
17+
ret <4 x float> %result
18+
}
19+
20+
define <4 x float> @test_minimumnum_f32x4(<4 x float> %a, <4 x float> %b) {
21+
; CHECK-LABEL: test_minimumnum_f32x4:
22+
; CHECK: .functype test_minimumnum_f32x4 (v128, v128) -> (v128)
23+
; CHECK-NEXT: # %bb.0:
24+
; CHECK-NEXT: local.get 0
25+
; CHECK-NEXT: local.get 1
26+
; CHECK-NEXT: f32x4.relaxed_min
27+
; CHECK-NEXT: # fallthrough-return
28+
%result = call <4 x float> @llvm.minimumnum.v4f32(<4 x float> %a, <4 x float> %b)
29+
ret <4 x float> %result
30+
}
31+
32+
define <2 x double> @test_minnum_f64x2(<2 x double> %a, <2 x double> %b) {
33+
; CHECK-LABEL: test_minnum_f64x2:
34+
; CHECK: .functype test_minnum_f64x2 (v128, v128) -> (v128)
35+
; CHECK-NEXT: # %bb.0:
36+
; CHECK-NEXT: local.get 0
37+
; CHECK-NEXT: local.get 1
38+
; CHECK-NEXT: f64x2.relaxed_min
39+
; CHECK-NEXT: # fallthrough-return
40+
%result = call <2 x double> @llvm.minnum.v2f64(<2 x double> %a, <2 x double> %b)
41+
ret <2 x double> %result
42+
}
43+
44+
define <2 x double> @test_minimumnum_f64x2(<2 x double> %a, <2 x double> %b) {
45+
; CHECK-LABEL: test_minimumnum_f64x2:
46+
; CHECK: .functype test_minimumnum_f64x2 (v128, v128) -> (v128)
47+
; CHECK-NEXT: # %bb.0:
48+
; CHECK-NEXT: local.get 0
49+
; CHECK-NEXT: local.get 1
50+
; CHECK-NEXT: f64x2.relaxed_min
51+
; CHECK-NEXT: # fallthrough-return
52+
%result = call <2 x double> @llvm.minimumnum.v2f64(<2 x double> %a, <2 x double> %b)
53+
ret <2 x double> %result
54+
}
55+
56+
declare <4 x float> @llvm.minnum.v4f32(<4 x float>, <4 x float>)
57+
declare <4 x float> @llvm.fminimumnum.v4f32(<4 x float>, <4 x float>)
58+
declare <2 x double> @llvm.minnum.v2f64(<2 x double>, <2 x double>)
59+
declare <2 x double> @llvm.fminimumnum.v2f64(<2 x double>, <2 x double>)

0 commit comments

Comments
 (0)