Skip to content
Merged
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
10 changes: 10 additions & 0 deletions cranelift/codegen/src/isa/x64/inst.isle
Original file line number Diff line number Diff line change
Expand Up @@ -1080,6 +1080,9 @@
(decl cc_invert (CC) CC)
(extern constructor cc_invert cc_invert)

(decl intcc_reverse (IntCC) IntCC)
(extern constructor intcc_reverse intcc_reverse)

(decl floatcc_inverse (FloatCC) FloatCC)
(extern constructor floatcc_inverse floatcc_inverse)

Expand Down Expand Up @@ -3178,6 +3181,13 @@
(let ((size OperandSize (raw_operand_size_of_type ty)))
(icmp_cond_result (x64_cmp size b a) cc)))

;; As a special case, reverse the arguments to the comparison when the LHS is a
;; constant. This ensures that we avoid moving the constant into a register when
;; performing the comparison.
(rule (emit_cmp cc (and (simm32_from_value a) (value_type ty)) b)
(let ((size OperandSize (raw_operand_size_of_type ty)))
(icmp_cond_result (x64_cmp size a b) (intcc_reverse cc))))

;; For I128 values (held in two GPRs), the instruction sequences depend on what
;; kind of condition is tested.
(rule (emit_cmp (IntCC.Equal) a @ (value_type $I128) b)
Expand Down
5 changes: 5 additions & 0 deletions cranelift/codegen/src/isa/x64/lower/isle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,11 @@ where
}
}

#[inline]
fn intcc_reverse(&mut self, cc: &IntCC) -> IntCC {
cc.reverse()
}

#[inline]
fn floatcc_inverse(&mut self, cc: &FloatCC) -> FloatCC {
cc.inverse()
Expand Down
64 changes: 64 additions & 0 deletions cranelift/filetests/filetests/isa/x64/b1.clif
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,70 @@ block2:
; popq %rbp
; ret

function %f3(i64) -> i32 {
block0(v0: i64):
v1 = iconst.i32 1
v2 = load.i32 v0
v3 = icmp eq v1, v2
brnz v3, block1
jump block2
block1:
v4 = iconst.i32 1
return v4
block2:
v5 = iconst.i32 1
return v5
}

; pushq %rbp
; movq %rsp, %rbp
; block0:
; movl 0(%rdi), %r8d
; cmpl $1, %r8d
; jz label1; j label2
; block1:
; movl $1, %eax
; movq %rbp, %rsp
; popq %rbp
; ret
; block2:
; movl $1, %eax
; movq %rbp, %rsp
; popq %rbp
; ret

function %f4(i64) -> i32 {
block0(v0: i64):
v1 = iconst.i32 1
v2 = load.i32 v0
v3 = icmp eq v2, v1
brnz v3, block1
jump block2
block1:
v4 = iconst.i32 1
return v4
block2:
v5 = iconst.i32 1
return v5
}

; pushq %rbp
; movq %rsp, %rbp
; block0:
; movl 0(%rdi), %r8d
; cmpl $1, %r8d
; jz label1; j label2
; block1:
; movl $1, %eax
; movq %rbp, %rsp
; popq %rbp
; ret
; block2:
; movl $1, %eax
; movq %rbp, %rsp
; popq %rbp
; ret

function %test_x_slt_0_i64(i64) -> b1 {
block0(v0: i64):
v1 = iconst.i64 0
Expand Down