x64: emit_cmp: use x64_test for comparisons with 0 (#6086)

* x64: emit_cmp: use x64_test for comparisons with 0

See #5869

* fixup! x64: emit_cmp: use x64_test for comparisons with 0
This commit is contained in:
Maja Kądziołka
2023-03-27 17:38:48 +02:00
committed by GitHub
parent dd9804514d
commit db07988ccb
3 changed files with 196 additions and 11 deletions

View File

@@ -4375,9 +4375,20 @@
(let ((size OperandSize (raw_operand_size_of_type ty)))
(icmp_cond_result (x64_cmp size a b) (intcc_reverse cc))))
;; Special case: use the test instruction for comparisons with 0.
(rule 2 (emit_cmp cc a @ (value_type ty) (u64_from_iconst 0))
(let ((size OperandSize (raw_operand_size_of_type ty))
(a Gpr (put_in_reg a)))
(icmp_cond_result (x64_test size a a) cc)))
(rule 3 (emit_cmp cc (u64_from_iconst 0) b @ (value_type ty))
(let ((size OperandSize (raw_operand_size_of_type ty))
(b Gpr (put_in_reg b)))
(icmp_cond_result (x64_test size b b) (intcc_reverse cc))))
;; For I128 values (held in two GPRs), the instruction sequences depend on what
;; kind of condition is tested.
(rule 3 (emit_cmp (IntCC.Equal) a @ (value_type $I128) b)
(rule 5 (emit_cmp (IntCC.Equal) a @ (value_type $I128) b)
(let ((a_lo Gpr (value_regs_get_gpr a 0))
(a_hi Gpr (value_regs_get_gpr a 1))
(b_lo Gpr (value_regs_get_gpr b 0))
@@ -4398,7 +4409,7 @@
(x64_test (OperandSize.Size64) (RegMemImm.Imm 1) cmp)
(CC.NZ))))
(rule 3 (emit_cmp (IntCC.NotEqual) a @ (value_type $I128) b)
(rule 5 (emit_cmp (IntCC.NotEqual) a @ (value_type $I128) b)
(let ((a_lo Gpr (value_regs_get_gpr a 0))
(a_hi Gpr (value_regs_get_gpr a 1))
(b_lo Gpr (value_regs_get_gpr b 0))
@@ -4413,7 +4424,7 @@
;; Result = (a_hi <> b_hi) ||
;; (a_hi == b_hi && a_lo <> b_lo)
(rule 2 (emit_cmp cc a @ (value_type $I128) b)
(rule 4 (emit_cmp cc a @ (value_type $I128) b)
(let ((a_lo Gpr (value_regs_get_gpr a 0))
(a_hi Gpr (value_regs_get_gpr a 1))
(b_lo Gpr (value_regs_get_gpr b 0))

View File

@@ -383,7 +383,7 @@ block2:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; cmpq $0, %rdi
; testq %rdi, %rdi
; jl label2; j label1
; block1:
; xorl %eax, %eax, %eax
@@ -401,14 +401,14 @@ block2:
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; cmpq $0, %rdi
; jl 0x15
; block2: ; offset 0xe
; testq %rdi, %rdi
; jl 0x14
; block2: ; offset 0xd
; xorl %eax, %eax
; movq %rbp, %rsp
; popq %rbp
; retq
; block3: ; offset 0x15
; block3: ; offset 0x14
; movl $1, %eax
; movq %rbp, %rsp
; popq %rbp
@@ -431,7 +431,7 @@ block2:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; cmpl $0, %edi
; testl %edi, %edi
; jl label2; j label1
; block1:
; xorl %eax, %eax, %eax
@@ -449,8 +449,152 @@ block2:
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; cmpl $0, %edi
; jl 0x14
; testl %edi, %edi
; jl 0x13
; block2: ; offset 0xc
; xorl %eax, %eax
; movq %rbp, %rsp
; popq %rbp
; retq
; block3: ; offset 0x13
; movl $1, %eax
; movq %rbp, %rsp
; popq %rbp
; retq
function %f8(i64) -> i8 {
block0(v0: i64):
v1 = iconst.i64 0
v2 = icmp eq v0, v1
brif v2, block1, block2
block1:
v3 = iconst.i8 1
return v3
block2:
v4 = iconst.i8 0
return v4
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; testq %rdi, %rdi
; jz label2; j label1
; block1:
; xorl %eax, %eax, %eax
; movq %rbp, %rsp
; popq %rbp
; ret
; block2:
; movl $1, %eax
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; testq %rdi, %rdi
; je 0x14
; block2: ; offset 0xd
; xorl %eax, %eax
; movq %rbp, %rsp
; popq %rbp
; retq
; block3: ; offset 0x14
; movl $1, %eax
; movq %rbp, %rsp
; popq %rbp
; retq
function %f9(i32) -> i8 {
block0(v0: i32):
v1 = iconst.i32 0
v2 = icmp eq v0, v1
brif v2, block1, block2
block1:
v3 = iconst.i8 1
return v3
block2:
v4 = iconst.i8 0
return v4
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; testl %edi, %edi
; jz label2; j label1
; block1:
; xorl %eax, %eax, %eax
; movq %rbp, %rsp
; popq %rbp
; ret
; block2:
; movl $1, %eax
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; testl %edi, %edi
; je 0x13
; block2: ; offset 0xc
; xorl %eax, %eax
; movq %rbp, %rsp
; popq %rbp
; retq
; block3: ; offset 0x13
; movl $1, %eax
; movq %rbp, %rsp
; popq %rbp
; retq
function %f10(i64) -> i8 {
block0(v0: i64):
v1 = iconst.i64 0
v2 = icmp slt v1, v0
brif v2, block1, block2
block1:
v3 = iconst.i8 1
return v3
block2:
v4 = iconst.i8 0
return v4
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; testq %rdi, %rdi
; jnle label2; j label1
; block1:
; xorl %eax, %eax, %eax
; movq %rbp, %rsp
; popq %rbp
; ret
; block2:
; movl $1, %eax
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; testq %rdi, %rdi
; jg 0x14
; block2: ; offset 0xd
; xorl %eax, %eax
; movq %rbp, %rsp

View File

@@ -238,3 +238,33 @@ block0(v0: i64):
; popq %rbp
; retq
function %cmp_mem_zero(i64) -> i8 {
block0(v0: i64):
v1 = load.i64 v0
v2 = icmp_imm eq v1, 0
return v2
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; movq 0(%rdi), %rcx
; testq %rcx, %rcx
; setz %al
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; movq (%rdi), %rcx ; trap: heap_oob
; testq %rcx, %rcx
; sete %al
; movq %rbp, %rsp
; popq %rbp
; retq