[llvm] [WebAssembly] Use generic pseudo_fmin/pseudo_fmax opcodes (PR #208454)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 9 05:51:50 PDT 2026
https://github.com/nikic created https://github.com/llvm/llvm-project/pull/208454
The pmin/pmax instructions are equivalent to these with operands swapped.
The existing matching code for these instructions was incorrect, because it failed to handle signed zeros and NaNs properly. You can't treat strict and non-strict comparisons the same in this context.
>From def8b09004b4594098cbd099b27e691ad1eeba95 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Thu, 9 Jul 2026 14:47:23 +0200
Subject: [PATCH] [WebAssembly] Use generic pseudo_fmin/pseudo_fmax opcodes
The pmin/pmax instructions are equivalent to these with operands
swapped.
The existing matching code for these instructions was incorrect,
because it failed to handle signed zeros and NaNs properly. You
can't treat strict and non-strict comparisons the same in this
context.
---
.../WebAssembly/WebAssemblyISelLowering.cpp | 4 ++
.../WebAssembly/WebAssemblyInstrSIMD.td | 27 ++-----
llvm/test/CodeGen/WebAssembly/simd-arith.ll | 16 ++---
.../CodeGen/WebAssembly/simd-relaxed-fmax.ll | 72 ++++++++++++-------
.../CodeGen/WebAssembly/simd-relaxed-fmin.ll | 64 +++++++++++------
.../test/CodeGen/WebAssembly/vector-reduce.ll | 16 ++---
6 files changed, 119 insertions(+), 80 deletions(-)
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index b7b0f180b9f09..da6bc0a2d3762 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -152,6 +152,10 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
// Support minimum and maximum, which otherwise default to expand.
setOperationAction(ISD::FMINIMUM, T, Legal);
setOperationAction(ISD::FMAXIMUM, T, Legal);
+ if (MVT(T).isVector()) {
+ setOperationAction(ISD::PSEUDO_FMIN, T, Legal);
+ setOperationAction(ISD::PSEUDO_FMAX, T, Legal);
+ }
// When experimental v8f16 support is enabled these instructions don't need
// to be expanded.
if (T != MVT::v8f16) {
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
index bbc1d15a8ba51..75a67d62322ce 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
@@ -1344,29 +1344,16 @@ defm MIN : SIMDBinaryFP<fminimum, "min", 232>;
defm MAX : SIMDBinaryFP<fmaximum, "max", 233>;
// Pseudo-minimum: pmin
-def pmin : PatFrags<(ops node:$lhs, node:$rhs), [
- (vselect (setolt $rhs, $lhs), $rhs, $lhs),
- (vselect (setole $rhs, $lhs), $rhs, $lhs),
- (vselect (setogt $lhs, $rhs), $rhs, $lhs),
- (vselect (setoge $lhs, $rhs), $rhs, $lhs),
- (vselect (setlt $lhs, $rhs), $lhs, $rhs),
- (vselect (setle $lhs, $rhs), $lhs, $rhs),
- (vselect (setgt $lhs, $rhs), $rhs, $lhs),
- (vselect (setge $lhs, $rhs), $rhs, $lhs)
-]>;
+// The operand order is swapped relative to the generic opcode.
+def pmin : PatFrags<(ops node:$lhs, node:$rhs),
+ [(pseudo_fmin node:$rhs, node:$lhs)]>;
defm PMIN : SIMDBinaryFP<pmin, "pmin", 234>;
+
// Pseudo-maximum: pmax
-def pmax : PatFrags<(ops node:$lhs, node:$rhs), [
- (vselect (setogt $rhs, $lhs), $rhs, $lhs),
- (vselect (setoge $rhs, $lhs), $rhs, $lhs),
- (vselect (setolt $lhs, $rhs), $rhs, $lhs),
- (vselect (setole $lhs, $rhs), $rhs, $lhs),
- (vselect (setgt $lhs, $rhs), $lhs, $rhs),
- (vselect (setge $lhs, $rhs), $lhs, $rhs),
- (vselect (setlt $lhs, $rhs), $rhs, $lhs),
- (vselect (setle $lhs, $rhs), $rhs, $lhs)
-]>;
+// The operand order is swapped relative to the generic opcode.
+def pmax : PatFrags<(ops node:$lhs, node:$rhs),
+ [(pseudo_fmax node:$rhs, node:$lhs)]>;
defm PMAX : SIMDBinaryFP<pmax, "pmax", 235>;
multiclass PMinMaxInt<Vec vec, NI baseMinInst, NI baseMaxInst> {
diff --git a/llvm/test/CodeGen/WebAssembly/simd-arith.ll b/llvm/test/CodeGen/WebAssembly/simd-arith.ll
index 5fcbd2bee5861..14e9adaa9818b 100644
--- a/llvm/test/CodeGen/WebAssembly/simd-arith.ll
+++ b/llvm/test/CodeGen/WebAssembly/simd-arith.ll
@@ -12942,13 +12942,13 @@ define <4 x float> @pmin_v4f32_fast_olt(<4 x float> %x, <4 x float> %y) {
; SIMD128-LABEL: pmin_v4f32_fast_olt:
; SIMD128: .functype pmin_v4f32_fast_olt (v128, v128) -> (v128)
; SIMD128-NEXT: # %bb.0:
-; SIMD128-NEXT: f32x4.pmin $push0=, $1, $0
+; SIMD128-NEXT: f32x4.pmin $push0=, $0, $1
; SIMD128-NEXT: return $pop0
;
; SIMD128-FAST-LABEL: pmin_v4f32_fast_olt:
; SIMD128-FAST: .functype pmin_v4f32_fast_olt (v128, v128) -> (v128)
; SIMD128-FAST-NEXT: # %bb.0:
-; SIMD128-FAST-NEXT: f32x4.pmin $push0=, $1, $0
+; SIMD128-FAST-NEXT: f32x4.pmin $push0=, $0, $1
; SIMD128-FAST-NEXT: return $pop0
;
; NO-SIMD128-LABEL: pmin_v4f32_fast_olt:
@@ -13095,13 +13095,13 @@ define <4 x float> @pmin_v4f32_fast_oge(<4 x float> %x, <4 x float> %y) {
; SIMD128-LABEL: pmin_v4f32_fast_oge:
; SIMD128: .functype pmin_v4f32_fast_oge (v128, v128) -> (v128)
; SIMD128-NEXT: # %bb.0:
-; SIMD128-NEXT: f32x4.pmin $push0=, $0, $1
+; SIMD128-NEXT: f32x4.pmin $push0=, $1, $0
; SIMD128-NEXT: return $pop0
;
; SIMD128-FAST-LABEL: pmin_v4f32_fast_oge:
; SIMD128-FAST: .functype pmin_v4f32_fast_oge (v128, v128) -> (v128)
; SIMD128-FAST-NEXT: # %bb.0:
-; SIMD128-FAST-NEXT: f32x4.pmin $push0=, $0, $1
+; SIMD128-FAST-NEXT: f32x4.pmin $push0=, $1, $0
; SIMD128-FAST-NEXT: return $pop0
;
; NO-SIMD128-LABEL: pmin_v4f32_fast_oge:
@@ -13266,13 +13266,13 @@ define <4 x float> @pmax_v4f32_fast_ogt(<4 x float> %x, <4 x float> %y) {
; SIMD128-LABEL: pmax_v4f32_fast_ogt:
; SIMD128: .functype pmax_v4f32_fast_ogt (v128, v128) -> (v128)
; SIMD128-NEXT: # %bb.0:
-; SIMD128-NEXT: f32x4.pmax $push0=, $0, $1
+; SIMD128-NEXT: f32x4.pmax $push0=, $1, $0
; SIMD128-NEXT: return $pop0
;
; SIMD128-FAST-LABEL: pmax_v4f32_fast_ogt:
; SIMD128-FAST: .functype pmax_v4f32_fast_ogt (v128, v128) -> (v128)
; SIMD128-FAST-NEXT: # %bb.0:
-; SIMD128-FAST-NEXT: f32x4.pmax $push0=, $0, $1
+; SIMD128-FAST-NEXT: f32x4.pmax $push0=, $1, $0
; SIMD128-FAST-NEXT: return $pop0
;
; NO-SIMD128-LABEL: pmax_v4f32_fast_ogt:
@@ -13419,13 +13419,13 @@ define <4 x float> @pmax_v4f32_fast_ole(<4 x float> %x, <4 x float> %y) {
; SIMD128-LABEL: pmax_v4f32_fast_ole:
; SIMD128: .functype pmax_v4f32_fast_ole (v128, v128) -> (v128)
; SIMD128-NEXT: # %bb.0:
-; SIMD128-NEXT: f32x4.pmax $push0=, $0, $1
+; SIMD128-NEXT: f32x4.pmax $push0=, $1, $0
; SIMD128-NEXT: return $pop0
;
; SIMD128-FAST-LABEL: pmax_v4f32_fast_ole:
; SIMD128-FAST: .functype pmax_v4f32_fast_ole (v128, v128) -> (v128)
; SIMD128-FAST-NEXT: # %bb.0:
-; SIMD128-FAST-NEXT: f32x4.pmax $push0=, $0, $1
+; SIMD128-FAST-NEXT: f32x4.pmax $push0=, $1, $0
; SIMD128-FAST-NEXT: return $pop0
;
; NO-SIMD128-LABEL: pmax_v4f32_fast_ole:
diff --git a/llvm/test/CodeGen/WebAssembly/simd-relaxed-fmax.ll b/llvm/test/CodeGen/WebAssembly/simd-relaxed-fmax.ll
index 0a217b8927437..511e0dccb667f 100644
--- a/llvm/test/CodeGen/WebAssembly/simd-relaxed-fmax.ll
+++ b/llvm/test/CodeGen/WebAssembly/simd-relaxed-fmax.ll
@@ -318,9 +318,12 @@ define <4 x float> @test_pmax_v4f32_ole(<4 x float> %x, <4 x float> %y) {
; CHECK-LABEL: test_pmax_v4f32_ole:
; CHECK: .functype test_pmax_v4f32_ole (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
-; CHECK-NEXT: f32x4.pmax
+; CHECK-NEXT: f32x4.le
+; CHECK-NEXT: v128.bitselect
; CHECK-NEXT: # fallthrough-return
%c = fcmp ole <4 x float> %x, %y
%a = select <4 x i1> %c, <4 x float> %y, <4 x float> %x
@@ -344,9 +347,12 @@ define <4 x float> @test_pmax_v4f32_oge(<4 x float> %x, <4 x float> %y) {
; CHECK-LABEL: test_pmax_v4f32_oge:
; CHECK: .functype test_pmax_v4f32_oge (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
-; CHECK-NEXT: f32x4.pmax
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: f32x4.ge
+; CHECK-NEXT: v128.bitselect
; CHECK-NEXT: # fallthrough-return
%c = fcmp oge <4 x float> %y, %x
%a = select <4 x i1> %c, <4 x float> %y, <4 x float> %x
@@ -372,8 +378,8 @@ define <4 x float> @test_pmax_v4f32_fast_ole(<4 x float> %x, <4 x float> %y) {
; CHECK-LABEL: test_pmax_v4f32_fast_ole:
; CHECK: .functype test_pmax_v4f32_fast_ole (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f32x4.pmax
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ole <4 x float> %x, %y
@@ -386,8 +392,8 @@ define <4 x float> @test_pmax_v4f32_fast_ogt(<4 x float> %x, <4 x float> %y) {
; CHECK-LABEL: test_pmax_v4f32_fast_ogt:
; CHECK: .functype test_pmax_v4f32_fast_ogt (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f32x4.pmax
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ogt <4 x float> %x, %y
@@ -441,9 +447,12 @@ define <2 x double> @test_pmax_v2f64_ole(<2 x double> %x, <2 x double> %y) {
; CHECK-LABEL: test_pmax_v2f64_ole:
; CHECK: .functype test_pmax_v2f64_ole (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
-; CHECK-NEXT: f64x2.pmax
+; CHECK-NEXT: f64x2.le
+; CHECK-NEXT: v128.bitselect
; CHECK-NEXT: # fallthrough-return
%c = fcmp ole <2 x double> %x, %y
%a = select <2 x i1> %c, <2 x double> %y, <2 x double> %x
@@ -466,9 +475,12 @@ define <2 x double> @test_pmax_v2f64_oge(<2 x double> %x, <2 x double> %y) {
; CHECK-LABEL: test_pmax_v2f64_oge:
; CHECK: .functype test_pmax_v2f64_oge (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
-; CHECK-NEXT: f64x2.pmax
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: f64x2.ge
+; CHECK-NEXT: v128.bitselect
; CHECK-NEXT: # fallthrough-return
%c = fcmp oge <2 x double> %x, %y
%a = select <2 x i1> %c, <2 x double> %x, <2 x double> %y
@@ -494,8 +506,8 @@ define <2 x double> @test_pmax_v2f64_fast_ole(<2 x double> %x, <2 x double> %y)
; CHECK-LABEL: test_pmax_v2f64_fast_ole:
; CHECK: .functype test_pmax_v2f64_fast_ole (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f64x2.pmax
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ole <2 x double> %x, %y
@@ -507,8 +519,8 @@ define <2 x double> @test_pmax_v2f64_fast_ogt(<2 x double> %x, <2 x double> %y)
; CHECK-LABEL: test_pmax_v2f64_fast_ogt:
; CHECK: .functype test_pmax_v2f64_fast_ogt (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f64x2.pmax
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ogt <2 x double> %x, %y
@@ -549,9 +561,12 @@ define <4 x float> @test_pmax_v4f32_ult(<4 x float> %x, <4 x float> %y) {
; CHECK-LABEL: test_pmax_v4f32_ult:
; CHECK: .functype test_pmax_v4f32_ult (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
-; CHECK-NEXT: f32x4.pmax
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: f32x4.ge
+; CHECK-NEXT: v128.bitselect
; CHECK-NEXT: # fallthrough-return
%c = fcmp ult <4 x float> %x, %y
%a = select <4 x i1> %c, <4 x float> %y, <4 x float> %x
@@ -575,9 +590,12 @@ define <4 x float> @test_pmax_v4f32_ugt(<4 x float> %x, <4 x float> %y) {
; CHECK-LABEL: test_pmax_v4f32_ugt:
; CHECK: .functype test_pmax_v4f32_ugt (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
-; CHECK-NEXT: f32x4.pmax
+; CHECK-NEXT: f32x4.le
+; CHECK-NEXT: v128.bitselect
; CHECK-NEXT: # fallthrough-return
%c = fcmp ugt <4 x float> %y, %x
%a = select <4 x i1> %c, <4 x float> %y, <4 x float> %x
@@ -616,8 +634,8 @@ define <4 x float> @test_pmax_v4f32_fast_ule(<4 x float> %x, <4 x float> %y) {
; CHECK-LABEL: test_pmax_v4f32_fast_ule:
; CHECK: .functype test_pmax_v4f32_fast_ule (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f32x4.pmax
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ule <4 x float> %x, %y
@@ -630,8 +648,8 @@ define <4 x float> @test_pmax_v4f32_fast_ugt(<4 x float> %x, <4 x float> %y) {
; CHECK-LABEL: test_pmax_v4f32_fast_ugt:
; CHECK: .functype test_pmax_v4f32_fast_ugt (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f32x4.pmax
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ugt <4 x float> %x, %y
@@ -675,9 +693,12 @@ define <2 x double> @test_pmax_v2f64_ult(<2 x double> %x, <2 x double> %y) {
; CHECK-LABEL: test_pmax_v2f64_ult:
; CHECK: .functype test_pmax_v2f64_ult (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
-; CHECK-NEXT: f64x2.pmax
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: f64x2.ge
+; CHECK-NEXT: v128.bitselect
; CHECK-NEXT: # fallthrough-return
%c = fcmp ult <2 x double> %x, %y
%a = select <2 x i1> %c, <2 x double> %y, <2 x double> %x
@@ -701,9 +722,12 @@ define <2 x double> @test_pmax_v2f64_ugt(<2 x double> %x, <2 x double> %y) {
; CHECK-LABEL: test_pmax_v2f64_ugt:
; CHECK: .functype test_pmax_v2f64_ugt (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
-; CHECK-NEXT: f64x2.pmax
+; CHECK-NEXT: f64x2.le
+; CHECK-NEXT: v128.bitselect
; CHECK-NEXT: # fallthrough-return
%c = fcmp ugt <2 x double> %x, %y
%a = select <2 x i1> %c, <2 x double> %x, <2 x double> %y
@@ -742,8 +766,8 @@ define <2 x double> @test_pmax_v2f64_fast_ule(<2 x double> %x, <2 x double> %y)
; CHECK-LABEL: test_pmax_v2f64_fast_ule:
; CHECK: .functype test_pmax_v2f64_fast_ule (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f64x2.pmax
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ule <2 x double> %x, %y
@@ -755,8 +779,8 @@ define <2 x double> @test_pmax_v2f64_fast_ugt(<2 x double> %x, <2 x double> %y)
; CHECK-LABEL: test_pmax_v2f64_fast_ugt:
; CHECK: .functype test_pmax_v2f64_fast_ugt (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f64x2.pmax
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ugt <2 x double> %x, %y
@@ -867,8 +891,8 @@ define <4 x float> @test_pmax_v4f32_fast_ole_nsz_nnan(<4 x float> %x, <4 x float
; CHECK-LABEL: test_pmax_v4f32_fast_ole_nsz_nnan:
; CHECK: .functype test_pmax_v4f32_fast_ole_nsz_nnan (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f32x4.relaxed_max
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ole <4 x float> %x, %y
@@ -881,8 +905,8 @@ define <4 x float> @test_pmax_v4f32_fast_ogt_nsz_nnan(<4 x float> %x, <4 x float
; CHECK-LABEL: test_pmax_v4f32_fast_ogt_nsz_nnan:
; CHECK: .functype test_pmax_v4f32_fast_ogt_nsz_nnan (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f32x4.relaxed_max
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ogt <4 x float> %x, %y
@@ -923,8 +947,8 @@ define <2 x double> @test_pmax_v2f64_fast_ole_nsz_nnan(<2 x double> %x, <2 x dou
; CHECK-LABEL: test_pmax_v2f64_fast_ole_nsz_nnan:
; CHECK: .functype test_pmax_v2f64_fast_ole_nsz_nnan (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f64x2.relaxed_max
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ole <2 x double> %x, %y
@@ -936,8 +960,8 @@ define <2 x double> @test_pmax_v2f64_fast_ogt_nsz_nnan(<2 x double> %x, <2 x dou
; CHECK-LABEL: test_pmax_v2f64_fast_ogt_nsz_nnan:
; CHECK: .functype test_pmax_v2f64_fast_ogt_nsz_nnan (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f64x2.relaxed_max
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ogt <2 x double> %x, %y
@@ -1030,8 +1054,8 @@ define <4 x float> @test_pmax_v4f32_fast_ule_nsz_nnan(<4 x float> %x, <4 x float
; CHECK-LABEL: test_pmax_v4f32_fast_ule_nsz_nnan:
; CHECK: .functype test_pmax_v4f32_fast_ule_nsz_nnan (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f32x4.relaxed_max
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ule <4 x float> %x, %y
@@ -1044,8 +1068,8 @@ define <4 x float> @test_pmax_v4f32_fast_ugt_nsz_nnan(<4 x float> %x, <4 x float
; CHECK-LABEL: test_pmax_v4f32_fast_ugt_nsz_nnan:
; CHECK: .functype test_pmax_v4f32_fast_ugt_nsz_nnan (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f32x4.relaxed_max
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ugt <4 x float> %x, %y
@@ -1086,8 +1110,8 @@ define <2 x double> @test_pmax_v2f64_fast_ule_nsz_nnan(<2 x double> %x, <2 x dou
; CHECK-LABEL: test_pmax_v2f64_fast_ule_nsz_nnan:
; CHECK: .functype test_pmax_v2f64_fast_ule_nsz_nnan (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f64x2.relaxed_max
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ule <2 x double> %x, %y
@@ -1099,8 +1123,8 @@ define <2 x double> @test_pmax_v2f64_fast_ugt_nsz_nnan(<2 x double> %x, <2 x dou
; CHECK-LABEL: test_pmax_v2f64_fast_ugt_nsz_nnan:
; CHECK: .functype test_pmax_v2f64_fast_ugt_nsz_nnan (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f64x2.relaxed_max
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ugt <2 x double> %x, %y
diff --git a/llvm/test/CodeGen/WebAssembly/simd-relaxed-fmin.ll b/llvm/test/CodeGen/WebAssembly/simd-relaxed-fmin.ll
index 86c859b54478f..2de1deac1f5b7 100644
--- a/llvm/test/CodeGen/WebAssembly/simd-relaxed-fmin.ll
+++ b/llvm/test/CodeGen/WebAssembly/simd-relaxed-fmin.ll
@@ -315,9 +315,12 @@ define <4 x float> @test_pmin_v4f32_ole(<4 x float> %x, <4 x float> %y) {
; CHECK-LABEL: test_pmin_v4f32_ole:
; CHECK: .functype test_pmin_v4f32_ole (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
-; CHECK-NEXT: f32x4.pmin
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: f32x4.le
+; CHECK-NEXT: v128.bitselect
; CHECK-NEXT: # fallthrough-return
%c = fcmp ole <4 x float> %y, %x
%a = select <4 x i1> %c, <4 x float> %y, <4 x float> %x
@@ -341,9 +344,12 @@ define <4 x float> @test_pmin_v4f32_oge(<4 x float> %x, <4 x float> %y) {
; CHECK-LABEL: test_pmin_v4f32_oge:
; CHECK: .functype test_pmin_v4f32_oge (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
-; CHECK-NEXT: f32x4.pmin
+; CHECK-NEXT: f32x4.ge
+; CHECK-NEXT: v128.bitselect
; CHECK-NEXT: # fallthrough-return
%c = fcmp oge <4 x float> %x, %y
%a = select <4 x i1> %c, <4 x float> %y, <4 x float> %x
@@ -355,8 +361,8 @@ define <4 x float> @pmin_v4f32_fast_olt(<4 x float> %x, <4 x float> %y) {
; CHECK-LABEL: pmin_v4f32_fast_olt:
; CHECK: .functype pmin_v4f32_fast_olt (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
+; CHECK-NEXT: local.get 1
; CHECK-NEXT: f32x4.pmin
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast olt <4 x float> %y, %x
@@ -397,8 +403,8 @@ define <4 x float> @test_pmin_v4f32_fast_oge(<4 x float> %x, <4 x float> %y) {
; CHECK-LABEL: test_pmin_v4f32_fast_oge:
; CHECK: .functype test_pmin_v4f32_fast_oge (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f32x4.pmin
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast oge <4 x float> %x, %y
@@ -438,9 +444,12 @@ define <2 x double> @test_pmin_v2f64_ole(<2 x double> %x, <2 x double> %y) {
; CHECK-LABEL: test_pmin_v2f64_ole:
; CHECK: .functype test_pmin_v2f64_ole (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
-; CHECK-NEXT: f64x2.pmin
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: f64x2.le
+; CHECK-NEXT: v128.bitselect
; CHECK-NEXT: # fallthrough-return
%c = fcmp ole <2 x double> %y, %x
%a = select <2 x i1> %c, <2 x double> %y, <2 x double> %x
@@ -464,9 +473,12 @@ define <2 x double> @test_pmin_v2f64_oge(<2 x double> %x, <2 x double> %y) {
; CHECK-LABEL: test_pmin_v2f64_oge:
; CHECK: .functype test_pmin_v2f64_oge (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
-; CHECK-NEXT: f64x2.pmin
+; CHECK-NEXT: f64x2.ge
+; CHECK-NEXT: v128.bitselect
; CHECK-NEXT: # fallthrough-return
%c = fcmp oge <2 x double> %x, %y
%a = select <2 x i1> %c, <2 x double> %y, <2 x double> %x
@@ -478,8 +490,8 @@ define <2 x double> @pmin_v2f64_fast_olt(<2 x double> %x, <2 x double> %y) {
; CHECK-LABEL: pmin_v2f64_fast_olt:
; CHECK: .functype pmin_v2f64_fast_olt (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
+; CHECK-NEXT: local.get 1
; CHECK-NEXT: f64x2.pmin
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast olt <2 x double> %y, %x
@@ -520,8 +532,8 @@ define <2 x double> @test_pmin_v2f64_fast_oge(<2 x double> %x, <2 x double> %y)
; CHECK-LABEL: test_pmin_v2f64_fast_oge:
; CHECK: .functype test_pmin_v2f64_fast_oge (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f64x2.pmin
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast oge <2 x double> %x, %y
@@ -548,9 +560,12 @@ define <4 x float> @test_pmin_v4f32_ult(<4 x float> %x, <4 x float> %y) {
; CHECK-LABEL: test_pmin_v4f32_ult:
; CHECK: .functype test_pmin_v4f32_ult (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
-; CHECK-NEXT: f32x4.pmin
+; CHECK-NEXT: f32x4.ge
+; CHECK-NEXT: v128.bitselect
; CHECK-NEXT: # fallthrough-return
%c = fcmp ult <4 x float> %y, %x
%a = select <4 x i1> %c, <4 x float> %y, <4 x float> %x
@@ -574,9 +589,12 @@ define <4 x float> @test_pmin_v4f32_ugt(<4 x float> %x, <4 x float> %y) {
; CHECK-LABEL: test_pmin_v4f32_ugt:
; CHECK: .functype test_pmin_v4f32_ugt (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
-; CHECK-NEXT: f32x4.pmin
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: f32x4.le
+; CHECK-NEXT: v128.bitselect
; CHECK-NEXT: # fallthrough-return
%c = fcmp ugt <4 x float> %x, %y
%a = select <4 x i1> %c, <4 x float> %y, <4 x float> %x
@@ -601,8 +619,8 @@ define <4 x float> @pmin_v4f32_fast_ult(<4 x float> %x, <4 x float> %y) {
; CHECK-LABEL: pmin_v4f32_fast_ult:
; CHECK: .functype pmin_v4f32_fast_ult (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
+; CHECK-NEXT: local.get 1
; CHECK-NEXT: f32x4.pmin
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ult <4 x float> %y, %x
@@ -643,8 +661,8 @@ define <4 x float> @test_pmin_v4f32_fast_uge(<4 x float> %x, <4 x float> %y) {
; CHECK-LABEL: test_pmin_v4f32_fast_uge:
; CHECK: .functype test_pmin_v4f32_fast_uge (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f32x4.pmin
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast uge <4 x float> %x, %y
@@ -674,9 +692,12 @@ define <2 x double> @test_pmin_v2f64_ult(<2 x double> %x, <2 x double> %y) {
; CHECK-LABEL: test_pmin_v2f64_ult:
; CHECK: .functype test_pmin_v2f64_ult (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
-; CHECK-NEXT: f64x2.pmin
+; CHECK-NEXT: f64x2.ge
+; CHECK-NEXT: v128.bitselect
; CHECK-NEXT: # fallthrough-return
%c = fcmp ult <2 x double> %y, %x
%a = select <2 x i1> %c, <2 x double> %y, <2 x double> %x
@@ -700,9 +721,12 @@ define <2 x double> @test_pmin_v2f64_ugt(<2 x double> %x, <2 x double> %y) {
; CHECK-LABEL: test_pmin_v2f64_ugt:
; CHECK: .functype test_pmin_v2f64_ugt (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
-; CHECK-NEXT: f64x2.pmin
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: f64x2.le
+; CHECK-NEXT: v128.bitselect
; CHECK-NEXT: # fallthrough-return
%c = fcmp ugt <2 x double> %x, %y
%a = select <2 x i1> %c, <2 x double> %y, <2 x double> %x
@@ -727,8 +751,8 @@ define <2 x double> @pmin_v2f64_fast_ult(<2 x double> %x, <2 x double> %y) {
; CHECK-LABEL: pmin_v2f64_fast_ult:
; CHECK: .functype pmin_v2f64_fast_ult (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
+; CHECK-NEXT: local.get 1
; CHECK-NEXT: f64x2.pmin
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ult <2 x double> %y, %x
@@ -769,8 +793,8 @@ define <2 x double> @test_pmin_v2f64_fast_uge(<2 x double> %x, <2 x double> %y)
; CHECK-LABEL: test_pmin_v2f64_fast_uge:
; CHECK: .functype test_pmin_v2f64_fast_uge (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f64x2.pmin
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast uge <2 x double> %x, %y
@@ -853,8 +877,8 @@ define <4 x float> @pmin_v4f32_fast_ult_nsz_nnan(<4 x float> %x, <4 x float> %y)
; CHECK-LABEL: pmin_v4f32_fast_ult_nsz_nnan:
; CHECK: .functype pmin_v4f32_fast_ult_nsz_nnan (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
+; CHECK-NEXT: local.get 1
; CHECK-NEXT: f32x4.relaxed_min
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ult <4 x float> %y, %x
@@ -895,8 +919,8 @@ define <4 x float> @test_pmin_v4f32_fast_uge_nsz_nnan(<4 x float> %x, <4 x float
; CHECK-LABEL: test_pmin_v4f32_fast_uge_nsz_nnan:
; CHECK: .functype test_pmin_v4f32_fast_uge_nsz_nnan (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f32x4.relaxed_min
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast uge <4 x float> %x, %y
@@ -961,8 +985,8 @@ define <2 x double> @pmin_v2f64_fast_ult_nsz_nnan(<2 x double> %x, <2 x double>
; CHECK-LABEL: pmin_v2f64_fast_ult_nsz_nnan:
; CHECK: .functype pmin_v2f64_fast_ult_nsz_nnan (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 1
; CHECK-NEXT: local.get 0
+; CHECK-NEXT: local.get 1
; CHECK-NEXT: f64x2.relaxed_min
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast ult <2 x double> %y, %x
@@ -1003,8 +1027,8 @@ define <2 x double> @test_pmin_v2f64_fast_uge_nsz_nnan(<2 x double> %x, <2 x dou
; CHECK-LABEL: test_pmin_v2f64_fast_uge_nsz_nnan:
; CHECK: .functype test_pmin_v2f64_fast_uge_nsz_nnan (v128, v128) -> (v128)
; CHECK-NEXT: # %bb.0:
-; CHECK-NEXT: local.get 0
; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 0
; CHECK-NEXT: f64x2.relaxed_min
; CHECK-NEXT: # fallthrough-return
%c = fcmp fast uge <2 x double> %x, %y
diff --git a/llvm/test/CodeGen/WebAssembly/vector-reduce.ll b/llvm/test/CodeGen/WebAssembly/vector-reduce.ll
index 4c30a3adf2378..18172c46af8f1 100644
--- a/llvm/test/CodeGen/WebAssembly/vector-reduce.ll
+++ b/llvm/test/CodeGen/WebAssembly/vector-reduce.ll
@@ -780,7 +780,7 @@ define double @pairwise_max_v2f64_fast(<2 x double> %arg) {
; SIMD128: .functype pairwise_max_v2f64_fast (v128) -> (f64)
; SIMD128-NEXT: # %bb.0:
; SIMD128-NEXT: i8x16.shuffle $push0=, $0, $0, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7
-; SIMD128-NEXT: f64x2.pmax $push1=, $0, $pop0
+; SIMD128-NEXT: f64x2.pmax $push1=, $pop0, $0
; SIMD128-NEXT: f64x2.extract_lane $push2=, $pop1, 0
; SIMD128-NEXT: return $pop2
%res = tail call fast double @llvm.vector.reduce.fmax.v2f64(<2 x double> %arg)
@@ -808,10 +808,10 @@ define float @pairwise_max_v4f32_fast(<4 x float> %arg) {
; SIMD128: .functype pairwise_max_v4f32_fast (v128) -> (f32)
; SIMD128-NEXT: # %bb.0:
; SIMD128-NEXT: i8x16.shuffle $push0=, $0, $0, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3
-; SIMD128-NEXT: f32x4.pmax $push5=, $0, $pop0
+; SIMD128-NEXT: f32x4.pmax $push5=, $pop0, $0
; SIMD128-NEXT: local.tee $push4=, $0=, $pop5
-; SIMD128-NEXT: i8x16.shuffle $push1=, $0, $0, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3
-; SIMD128-NEXT: f32x4.pmax $push2=, $pop4, $pop1
+; SIMD128-NEXT: i8x16.shuffle $push1=, $pop4, $0, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3
+; SIMD128-NEXT: f32x4.pmax $push2=, $pop1, $0
; SIMD128-NEXT: f32x4.extract_lane $push3=, $pop2, 0
; SIMD128-NEXT: return $pop3
%res = tail call fast float @llvm.vector.reduce.fmax.v4f32(<4 x float> %arg)
@@ -851,7 +851,7 @@ define double @pairwise_min_v2f64_fast(<2 x double> %arg) {
; SIMD128: .functype pairwise_min_v2f64_fast (v128) -> (f64)
; SIMD128-NEXT: # %bb.0:
; SIMD128-NEXT: i8x16.shuffle $push0=, $0, $0, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7
-; SIMD128-NEXT: f64x2.pmin $push1=, $0, $pop0
+; SIMD128-NEXT: f64x2.pmin $push1=, $pop0, $0
; SIMD128-NEXT: f64x2.extract_lane $push2=, $pop1, 0
; SIMD128-NEXT: return $pop2
%res = tail call fast double @llvm.vector.reduce.fmin.v2f64(<2 x double> %arg)
@@ -879,10 +879,10 @@ define float @pairwise_min_v4f32_fast(<4 x float> %arg) {
; SIMD128: .functype pairwise_min_v4f32_fast (v128) -> (f32)
; SIMD128-NEXT: # %bb.0:
; SIMD128-NEXT: i8x16.shuffle $push0=, $0, $0, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 0, 1, 2, 3
-; SIMD128-NEXT: f32x4.pmin $push5=, $0, $pop0
+; SIMD128-NEXT: f32x4.pmin $push5=, $pop0, $0
; SIMD128-NEXT: local.tee $push4=, $0=, $pop5
-; SIMD128-NEXT: i8x16.shuffle $push1=, $0, $0, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3
-; SIMD128-NEXT: f32x4.pmin $push2=, $pop4, $pop1
+; SIMD128-NEXT: i8x16.shuffle $push1=, $pop4, $0, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3
+; SIMD128-NEXT: f32x4.pmin $push2=, $pop1, $0
; SIMD128-NEXT: f32x4.extract_lane $push3=, $pop2, 0
; SIMD128-NEXT: return $pop3
%res = tail call fast float @llvm.vector.reduce.fmin.v4f32(<4 x float> %arg)
More information about the llvm-commits
mailing list