diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td index 49af78bce68c3..0dd5e30ed9c86 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -1692,6 +1692,26 @@ defm SIMD_RELAXED_FMIN : defm SIMD_RELAXED_FMAX : RelaxedBinary; +// Transform standard fminimum/fmaximum to relaxed versions +// AddedComplexity ensures these patterns match before the standard MIN/MAX +let AddedComplexity = 1 in { +def : Pat<(v4f32 (fminimum (v4f32 V128:$lhs), (v4f32 V128:$rhs))), + (SIMD_RELAXED_FMIN_F32x4 V128:$lhs, V128:$rhs)>, + Requires<[HasRelaxedSIMD]>; + +def : Pat<(v4f32 (fmaximum (v4f32 V128:$lhs), (v4f32 V128:$rhs))), + (SIMD_RELAXED_FMAX_F32x4 V128:$lhs, V128:$rhs)>, + Requires<[HasRelaxedSIMD]>; + +def : Pat<(v2f64 (fminimum (v2f64 V128:$lhs), (v2f64 V128:$rhs))), + (SIMD_RELAXED_FMIN_F64x2 V128:$lhs, V128:$rhs)>, + Requires<[HasRelaxedSIMD]>; + +def : Pat<(v2f64 (fmaximum (v2f64 V128:$lhs), (v2f64 V128:$rhs))), + (SIMD_RELAXED_FMAX_F64x2 V128:$lhs, V128:$rhs)>, + Requires<[HasRelaxedSIMD]>; +} + //===----------------------------------------------------------------------===// // Relaxed rounding q15 multiplication //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/WebAssembly/simd-relaxed-fmax.ll b/llvm/test/CodeGen/WebAssembly/simd-relaxed-fmax.ll new file mode 100644 index 0000000000000..1339f3a730150 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/simd-relaxed-fmax.ll @@ -0,0 +1,35 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 + +; RUN: llc < %s -mtriple=wasm32-unknown-unknown -mattr=+simd128,+relaxed-simd | FileCheck %s + +; Test that fminimum and fmaximum get transformed to relaxed_min and relaxed_max + +target triple = "wasm32" + +define <4 x float> @test_max_f32x4(<4 x float> %a, <4 x float> %b) { +; CHECK-LABEL: test_max_f32x4: +; CHECK: .functype test_max_f32x4 (v128, v128) -> (v128) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: f32x4.relaxed_max +; CHECK-NEXT: # fallthrough-return + %result = call <4 x float> @llvm.maximum.v4f32(<4 x float> %a, <4 x float> %b) + ret <4 x float> %result +} + + +define <2 x double> @test_max_f64x2(<2 x double> %a, <2 x double> %b) { +; CHECK-LABEL: test_max_f64x2: +; CHECK: .functype test_max_f64x2 (v128, v128) -> (v128) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: f64x2.relaxed_max +; CHECK-NEXT: # fallthrough-return + %result = call <2 x double> @llvm.maximum.v2f64(<2 x double> %a, <2 x double> %b) + ret <2 x double> %result +} + +declare <4 x float> @llvm.maximum.v4f32(<4 x float>, <4 x float>) +declare <2 x double> @llvm.maximum.v2f64(<2 x double>, <2 x double>) diff --git a/llvm/test/CodeGen/WebAssembly/simd-relaxed-fmin.ll b/llvm/test/CodeGen/WebAssembly/simd-relaxed-fmin.ll new file mode 100644 index 0000000000000..799cc4a45144c --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/simd-relaxed-fmin.ll @@ -0,0 +1,34 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 +; RUN: llc < %s -mtriple=wasm32-unknown-unknown -mattr=+simd128,+relaxed-simd | FileCheck %s + +; Test that fminimum and fmaximum get transformed to relaxed_min and relaxed_max + +target triple = "wasm32" + +define <4 x float> @test_min_f32x4(<4 x float> %a, <4 x float> %b) { +; CHECK-LABEL: test_min_f32x4: +; CHECK: .functype test_min_f32x4 (v128, v128) -> (v128) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: f32x4.relaxed_min +; CHECK-NEXT: # fallthrough-return + %result = call <4 x float> @llvm.minimum.v4f32(<4 x float> %a, <4 x float> %b) + ret <4 x float> %result +} + + +define <2 x double> @test_min_f64x2(<2 x double> %a, <2 x double> %b) { +; CHECK-LABEL: test_min_f64x2: +; CHECK: .functype test_min_f64x2 (v128, v128) -> (v128) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: f64x2.relaxed_min +; CHECK-NEXT: # fallthrough-return + %result = call <2 x double> @llvm.minimum.v2f64(<2 x double> %a, <2 x double> %b) + ret <2 x double> %result +} + +declare <4 x float> @llvm.minimum.v4f32(<4 x float>, <4 x float>) +declare <2 x double> @llvm.minimum.v2f64(<2 x double>, <2 x double>)