Skip to content

Commit 63c2d1e

Browse files
authored
x64: Remove unnecessary register use when comparing against constants (#4645)
#4645
1 parent 4d2a2cf commit 63c2d1e

3 files changed

Lines changed: 79 additions & 0 deletions

File tree

cranelift/codegen/src/isa/x64/inst.isle

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,9 @@
10801080
(decl cc_invert (CC) CC)
10811081
(extern constructor cc_invert cc_invert)
10821082

1083+
(decl intcc_reverse (IntCC) IntCC)
1084+
(extern constructor intcc_reverse intcc_reverse)
1085+
10831086
(decl floatcc_inverse (FloatCC) FloatCC)
10841087
(extern constructor floatcc_inverse floatcc_inverse)
10851088

@@ -3178,6 +3181,13 @@
31783181
(let ((size OperandSize (raw_operand_size_of_type ty)))
31793182
(icmp_cond_result (x64_cmp size b a) cc)))
31803183

3184+
;; As a special case, reverse the arguments to the comparison when the LHS is a
3185+
;; constant. This ensures that we avoid moving the constant into a register when
3186+
;; performing the comparison.
3187+
(rule (emit_cmp cc (and (simm32_from_value a) (value_type ty)) b)
3188+
(let ((size OperandSize (raw_operand_size_of_type ty)))
3189+
(icmp_cond_result (x64_cmp size a b) (intcc_reverse cc))))
3190+
31813191
;; For I128 values (held in two GPRs), the instruction sequences depend on what
31823192
;; kind of condition is tested.
31833193
(rule (emit_cmp (IntCC.Equal) a @ (value_type $I128) b)

cranelift/codegen/src/isa/x64/lower/isle.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,11 @@ where
610610
}
611611
}
612612

613+
#[inline]
614+
fn intcc_reverse(&mut self, cc: &IntCC) -> IntCC {
615+
cc.reverse()
616+
}
617+
613618
#[inline]
614619
fn floatcc_inverse(&mut self, cc: &FloatCC) -> FloatCC {
615620
cc.inverse()

cranelift/filetests/filetests/isa/x64/b1.clif

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,70 @@ block2:
7373
; popq %rbp
7474
; ret
7575

76+
function %f3(i64) -> i32 {
77+
block0(v0: i64):
78+
v1 = iconst.i32 1
79+
v2 = load.i32 v0
80+
v3 = icmp eq v1, v2
81+
brnz v3, block1
82+
jump block2
83+
block1:
84+
v4 = iconst.i32 1
85+
return v4
86+
block2:
87+
v5 = iconst.i32 1
88+
return v5
89+
}
90+
91+
; pushq %rbp
92+
; movq %rsp, %rbp
93+
; block0:
94+
; movl 0(%rdi), %r8d
95+
; cmpl $1, %r8d
96+
; jz label1; j label2
97+
; block1:
98+
; movl $1, %eax
99+
; movq %rbp, %rsp
100+
; popq %rbp
101+
; ret
102+
; block2:
103+
; movl $1, %eax
104+
; movq %rbp, %rsp
105+
; popq %rbp
106+
; ret
107+
108+
function %f4(i64) -> i32 {
109+
block0(v0: i64):
110+
v1 = iconst.i32 1
111+
v2 = load.i32 v0
112+
v3 = icmp eq v2, v1
113+
brnz v3, block1
114+
jump block2
115+
block1:
116+
v4 = iconst.i32 1
117+
return v4
118+
block2:
119+
v5 = iconst.i32 1
120+
return v5
121+
}
122+
123+
; pushq %rbp
124+
; movq %rsp, %rbp
125+
; block0:
126+
; movl 0(%rdi), %r8d
127+
; cmpl $1, %r8d
128+
; jz label1; j label2
129+
; block1:
130+
; movl $1, %eax
131+
; movq %rbp, %rsp
132+
; popq %rbp
133+
; ret
134+
; block2:
135+
; movl $1, %eax
136+
; movq %rbp, %rsp
137+
; popq %rbp
138+
; ret
139+
76140
function %test_x_slt_0_i64(i64) -> b1 {
77141
block0(v0: i64):
78142
v1 = iconst.i64 0

0 commit comments

Comments
 (0)