Skip to content

Commit

Permalink
x64: Remove unnecessary register use when comparing against constants (
Browse files Browse the repository at this point in the history
  • Loading branch information
elliottt authored Aug 9, 2022
1 parent 4d2a2cf commit 63c2d1e
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 0 deletions.
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

0 comments on commit 63c2d1e

Please sign in to comment.