s390x: Support scalar min/max clif instructions (#5762)
We don't have ISA instructions for that, so simply expand them to icmp + select. Also enable fuzzing for those clif instructions now.
This commit is contained in:
@@ -238,20 +238,35 @@
|
|||||||
|
|
||||||
;;;; Rules for `umax` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;; Rules for `umax` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;; Unsigned maximum of two scalar integers - expand to icmp + select.
|
||||||
|
(rule 1 (lower (has_type (ty_int ty) (umax x y)))
|
||||||
|
(let ((cond ProducesBool (icmp_val $false (IntCC.UnsignedLessThan) x y)))
|
||||||
|
(select_bool_reg ty cond y x)))
|
||||||
|
|
||||||
;; Unsigned maximum of two vector registers.
|
;; Unsigned maximum of two vector registers.
|
||||||
(rule (lower (has_type (ty_vec128 ty) (umax x y)))
|
(rule 0 (lower (has_type (ty_vec128 ty) (umax x y)))
|
||||||
(vec_umax ty x y))
|
(vec_umax ty x y))
|
||||||
|
|
||||||
|
|
||||||
;;;; Rules for `umin` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;; Rules for `umin` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;; Unsigned minimum of two scalar integers - expand to icmp + select.
|
||||||
|
(rule 1 (lower (has_type (ty_int ty) (umin x y)))
|
||||||
|
(let ((cond ProducesBool (icmp_val $false (IntCC.UnsignedGreaterThan) x y)))
|
||||||
|
(select_bool_reg ty cond y x)))
|
||||||
|
|
||||||
;; Unsigned minimum of two vector registers.
|
;; Unsigned minimum of two vector registers.
|
||||||
(rule (lower (has_type (ty_vec128 ty) (umin x y)))
|
(rule 0 (lower (has_type (ty_vec128 ty) (umin x y)))
|
||||||
(vec_umin ty x y))
|
(vec_umin ty x y))
|
||||||
|
|
||||||
|
|
||||||
;;;; Rules for `smax` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;; Rules for `smax` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;; Signed maximum of two scalar integers - expand to icmp + select.
|
||||||
|
(rule 1 (lower (has_type (ty_int ty) (smax x y)))
|
||||||
|
(let ((cond ProducesBool (icmp_val $false (IntCC.SignedLessThan) x y)))
|
||||||
|
(select_bool_reg ty cond y x)))
|
||||||
|
|
||||||
;; Signed maximum of two vector registers.
|
;; Signed maximum of two vector registers.
|
||||||
(rule (lower (has_type (ty_vec128 ty) (smax x y)))
|
(rule (lower (has_type (ty_vec128 ty) (smax x y)))
|
||||||
(vec_smax ty x y))
|
(vec_smax ty x y))
|
||||||
@@ -259,6 +274,11 @@
|
|||||||
|
|
||||||
;;;; Rules for `smin` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;; Rules for `smin` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;; Signed minimum of two scalar integers - expand to icmp + select.
|
||||||
|
(rule 1 (lower (has_type (ty_int ty) (smin x y)))
|
||||||
|
(let ((cond ProducesBool (icmp_val $false (IntCC.SignedGreaterThan) x y)))
|
||||||
|
(select_bool_reg ty cond y x)))
|
||||||
|
|
||||||
;; Signed minimum of two vector registers.
|
;; Signed minimum of two vector registers.
|
||||||
(rule (lower (has_type (ty_vec128 ty) (smin x y)))
|
(rule (lower (has_type (ty_vec128 ty) (smin x y)))
|
||||||
(vec_smin ty x y))
|
(vec_smin ty x y))
|
||||||
|
|||||||
251
cranelift/filetests/filetests/isa/s390x/minmax.clif
Normal file
251
cranelift/filetests/filetests/isa/s390x/minmax.clif
Normal file
@@ -0,0 +1,251 @@
|
|||||||
|
test compile precise-output
|
||||||
|
target s390x
|
||||||
|
|
||||||
|
function %umax_i128(i128, i128) -> i128 {
|
||||||
|
block0(v0: i128, v1: i128):
|
||||||
|
v2 = umax.i128 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; vl %v5, 0(%r3)
|
||||||
|
; vl %v3, 0(%r4)
|
||||||
|
; veclg %v5, %v3 ; jne 10 ; vchlgs %v6, %v3, %v5
|
||||||
|
; jnl 10 ; vlr %v5, %v3
|
||||||
|
; vst %v5, 0(%r2)
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %umax_i64(i64, i64) -> i64 {
|
||||||
|
block0(v0: i64, v1: i64):
|
||||||
|
v2 = umax.i64 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; clgr %r2, %r3
|
||||||
|
; locgrl %r2, %r3
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %umax_i32(i32, i32) -> i32 {
|
||||||
|
block0(v0: i32, v1: i32):
|
||||||
|
v2 = umax.i32 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; clr %r2, %r3
|
||||||
|
; locrl %r2, %r3
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %umax_i16(i16, i16) -> i16 {
|
||||||
|
block0(v0: i16, v1: i16):
|
||||||
|
v2 = umax.i16 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; llhr %r5, %r2
|
||||||
|
; llhr %r4, %r3
|
||||||
|
; clr %r5, %r4
|
||||||
|
; locrl %r2, %r3
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %umax_i8(i8, i8) -> i8 {
|
||||||
|
block0(v0: i8, v1: i8):
|
||||||
|
v2 = umax.i8 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; llcr %r5, %r2
|
||||||
|
; llcr %r4, %r3
|
||||||
|
; clr %r5, %r4
|
||||||
|
; locrl %r2, %r3
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %umin_i128(i128, i128) -> i128 {
|
||||||
|
block0(v0: i128, v1: i128):
|
||||||
|
v2 = umin.i128 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; vl %v5, 0(%r3)
|
||||||
|
; vl %v3, 0(%r4)
|
||||||
|
; veclg %v3, %v5 ; jne 10 ; vchlgs %v6, %v5, %v3
|
||||||
|
; jnl 10 ; vlr %v5, %v3
|
||||||
|
; vst %v5, 0(%r2)
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %umin_i64(i64, i64) -> i64 {
|
||||||
|
block0(v0: i64, v1: i64):
|
||||||
|
v2 = umin.i64 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; clgr %r2, %r3
|
||||||
|
; locgrh %r2, %r3
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %umin_i32(i32, i32) -> i32 {
|
||||||
|
block0(v0: i32, v1: i32):
|
||||||
|
v2 = umin.i32 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; clr %r2, %r3
|
||||||
|
; locrh %r2, %r3
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %umin_i16(i16, i16) -> i16 {
|
||||||
|
block0(v0: i16, v1: i16):
|
||||||
|
v2 = umin.i16 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; llhr %r5, %r2
|
||||||
|
; llhr %r4, %r3
|
||||||
|
; clr %r5, %r4
|
||||||
|
; locrh %r2, %r3
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %umin_i8(i8, i8) -> i8 {
|
||||||
|
block0(v0: i8, v1: i8):
|
||||||
|
v2 = umin.i8 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; llcr %r5, %r2
|
||||||
|
; llcr %r4, %r3
|
||||||
|
; clr %r5, %r4
|
||||||
|
; locrh %r2, %r3
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %smax_i128(i128, i128) -> i128 {
|
||||||
|
block0(v0: i128, v1: i128):
|
||||||
|
v2 = smax.i128 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; vl %v5, 0(%r3)
|
||||||
|
; vl %v3, 0(%r4)
|
||||||
|
; vecg %v5, %v3 ; jne 10 ; vchlgs %v6, %v3, %v5
|
||||||
|
; jnl 10 ; vlr %v5, %v3
|
||||||
|
; vst %v5, 0(%r2)
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %smax_i64(i64, i64) -> i64 {
|
||||||
|
block0(v0: i64, v1: i64):
|
||||||
|
v2 = smax.i64 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; cgr %r2, %r3
|
||||||
|
; locgrl %r2, %r3
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %smax_i32(i32, i32) -> i32 {
|
||||||
|
block0(v0: i32, v1: i32):
|
||||||
|
v2 = smax.i32 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; cr %r2, %r3
|
||||||
|
; locrl %r2, %r3
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %smax_i16(i16, i16) -> i16 {
|
||||||
|
block0(v0: i16, v1: i16):
|
||||||
|
v2 = smax.i16 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; lhr %r5, %r2
|
||||||
|
; lhr %r4, %r3
|
||||||
|
; cr %r5, %r4
|
||||||
|
; locrl %r2, %r3
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %smax_i8(i8, i8) -> i8 {
|
||||||
|
block0(v0: i8, v1: i8):
|
||||||
|
v2 = smax.i8 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; lbr %r5, %r2
|
||||||
|
; lbr %r4, %r3
|
||||||
|
; cr %r5, %r4
|
||||||
|
; locrl %r2, %r3
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %smin_i128(i128, i128) -> i128 {
|
||||||
|
block0(v0: i128, v1: i128):
|
||||||
|
v2 = smin.i128 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; vl %v5, 0(%r3)
|
||||||
|
; vl %v3, 0(%r4)
|
||||||
|
; vecg %v3, %v5 ; jne 10 ; vchlgs %v6, %v5, %v3
|
||||||
|
; jnl 10 ; vlr %v5, %v3
|
||||||
|
; vst %v5, 0(%r2)
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %smin_i64(i64, i64) -> i64 {
|
||||||
|
block0(v0: i64, v1: i64):
|
||||||
|
v2 = smin.i64 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; cgr %r2, %r3
|
||||||
|
; locgrh %r2, %r3
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %smin_i32(i32, i32) -> i32 {
|
||||||
|
block0(v0: i32, v1: i32):
|
||||||
|
v2 = smin.i32 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; cr %r2, %r3
|
||||||
|
; locrh %r2, %r3
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %smin_i16(i16, i16) -> i16 {
|
||||||
|
block0(v0: i16, v1: i16):
|
||||||
|
v2 = smin.i16 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; lhr %r5, %r2
|
||||||
|
; lhr %r4, %r3
|
||||||
|
; cr %r5, %r4
|
||||||
|
; locrh %r2, %r3
|
||||||
|
; br %r14
|
||||||
|
|
||||||
|
function %smin_i8(i8, i8) -> i8 {
|
||||||
|
block0(v0: i8, v1: i8):
|
||||||
|
v2 = smin.i8 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; lbr %r5, %r2
|
||||||
|
; lbr %r4, %r3
|
||||||
|
; cr %r5, %r4
|
||||||
|
; locrh %r2, %r3
|
||||||
|
; br %r14
|
||||||
|
|
||||||
@@ -509,10 +509,6 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
|
|||||||
(Opcode::Sdiv, &[I128, I128]),
|
(Opcode::Sdiv, &[I128, I128]),
|
||||||
(Opcode::Urem, &[I128, I128]),
|
(Opcode::Urem, &[I128, I128]),
|
||||||
(Opcode::Srem, &[I128, I128]),
|
(Opcode::Srem, &[I128, I128]),
|
||||||
(Opcode::Smin),
|
|
||||||
(Opcode::Smax),
|
|
||||||
(Opcode::Umin),
|
|
||||||
(Opcode::Umax),
|
|
||||||
(Opcode::Band, &[F32, F32]),
|
(Opcode::Band, &[F32, F32]),
|
||||||
(Opcode::Band, &[F64, F64]),
|
(Opcode::Band, &[F64, F64]),
|
||||||
(Opcode::Bor, &[F32, F32]),
|
(Opcode::Bor, &[F32, F32]),
|
||||||
|
|||||||
Reference in New Issue
Block a user