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` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; 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.
|
||||
(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))
|
||||
|
||||
|
||||
;;;; 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.
|
||||
(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))
|
||||
|
||||
|
||||
;;;; 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.
|
||||
(rule (lower (has_type (ty_vec128 ty) (smax x y)))
|
||||
(vec_smax ty x y))
|
||||
@@ -259,6 +274,11 @@
|
||||
|
||||
;;;; 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.
|
||||
(rule (lower (has_type (ty_vec128 ty) (smin 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::Urem, &[I128, I128]),
|
||||
(Opcode::Srem, &[I128, I128]),
|
||||
(Opcode::Smin),
|
||||
(Opcode::Smax),
|
||||
(Opcode::Umin),
|
||||
(Opcode::Umax),
|
||||
(Opcode::Band, &[F32, F32]),
|
||||
(Opcode::Band, &[F64, F64]),
|
||||
(Opcode::Bor, &[F32, F32]),
|
||||
|
||||
Reference in New Issue
Block a user