Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions cranelift/codegen/meta/src/shared/legalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ pub(crate) fn define(insts: &InstructionGroup, imm: &Immediates) -> TransformGro
let iconst = insts.by_name("iconst");
let ifcmp = insts.by_name("ifcmp");
let ifcmp_imm = insts.by_name("ifcmp_imm");
let imax = insts.by_name("imax");
let imin = insts.by_name("imin");
let imul = insts.by_name("imul");
let imul_imm = insts.by_name("imul_imm");
let ireduce = insts.by_name("ireduce");
Expand Down Expand Up @@ -117,6 +119,8 @@ pub(crate) fn define(insts: &InstructionGroup, imm: &Immediates) -> TransformGro
let uextend = insts.by_name("uextend");
let uload8 = insts.by_name("uload8");
let uload16 = insts.by_name("uload16");
let umax = insts.by_name("umax");
let umin = insts.by_name("umin");
let umulhi = insts.by_name("umulhi");
let ushr = insts.by_name("ushr");
let ushr_imm = insts.by_name("ushr_imm");
Expand Down Expand Up @@ -745,6 +749,21 @@ pub(crate) fn define(insts: &InstructionGroup, imm: &Immediates) -> TransformGro
);
}

// Expand scalar [i,u] min/max using icmp and select.
for &(inst, cc) in &[(imin, "slt"), (imax, "sgt"), (umin, "ult"), (umax, "ugt")] {
let w_cc = Literal::enumerator_for(&imm.intcc, cc);
expand.legalize(
def!(a = inst(x, y)),
vec![def!(c = icmp(w_cc, x, y)), def!(a = select(c, x, y))],
);
for &int_ty in &[I8, I16] {
widen.legalize(
def!(a = inst.int_ty(x, y)),
vec![def!(c = icmp(w_cc, x, y)), def!(a = select(c, x, y))],
)
}
}

expand.legalize(
def!(a = icmp_imm(cc, x, y)),
vec![def!(a1 = iconst(y)), def!(a = icmp(cc, x, a1))],
Expand Down
68 changes: 68 additions & 0 deletions cranelift/filetests/filetests/isa/x86/scalar-minmax-run.clif
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
test run
target x86_64

function %imax8(i8, i8) -> i8 {
block0(v0:i8, v1:i8):
v2 = imax v0, v1
return v2
}
; run: %imax8(1, 10) == 10
; run: %imax8(-1, 1) == 1

function %imin8(i8, i8) -> i8 {
block0(v0:i8, v1:i8):
v2 = imin v0, v1
return v2
}
; run: %imin8(1, 10) == 1
; run: %imin8(-1, 1) == -1

function %umin8(i8, i8) -> i8 {
block0(v0:i8, v1:i8):
v2 = umin v0, v1
return v2
}
; run: %umin8(1, 10) == 1
; run: %umin8(-1, 1) == 1

function %umax8(i8, i8) -> i8 {
block0(v0:i8, v1:i8):
v2 = umax v0, v1
return v2
}
; run: %umax8(1, 10) == 10
; run: %umax8(-1, 1) == -1

function %imin32(i32, i32) -> i32 {
block0(v0:i32, v1:i32):
v2 = imin v0, v1
return v2
}
; run: %imin32(1, 10) == 1
; run: %imin32(-1, 1) == -1

function %imax32(i32, i32) -> i32 {
block0(v0:i32, v1:i32):
v2 = imax v0, v1
return v2
}
; run: %imin32(1, 10) == 10
; run: %imin32(-1, 1) == 1


function %umin32(i32, i32) -> i32 {
block0(v0:i32, v1:i32):
v2 = umin v0, v1
return v2
}
; run: %umin32(1, 10) == 1
; run: %umin32(-1, 1) == 1


function %umax32(i32, i32) -> i32 {
block0(v0:i32, v1:i32):
v2 = umax v0, v1
return v2
}
; run: %umax32(1, 10) == 10
; run: %umax32(-1, 1) == -1