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:
Ulrich Weigand
2023-02-15 12:45:09 +01:00
committed by GitHub
parent 255fd6be0a
commit e10094dcd6
3 changed files with 273 additions and 6 deletions

View File

@@ -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))

View 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

View File

@@ -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]),