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:
@@ -4375,9 +4375,20 @@
|
|||||||
(let ((size OperandSize (raw_operand_size_of_type ty)))
|
(let ((size OperandSize (raw_operand_size_of_type ty)))
|
||||||
(icmp_cond_result (x64_cmp size a b) (intcc_reverse cc))))
|
(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
|
;; For I128 values (held in two GPRs), the instruction sequences depend on what
|
||||||
;; kind of condition is tested.
|
;; 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))
|
(let ((a_lo Gpr (value_regs_get_gpr a 0))
|
||||||
(a_hi Gpr (value_regs_get_gpr a 1))
|
(a_hi Gpr (value_regs_get_gpr a 1))
|
||||||
(b_lo Gpr (value_regs_get_gpr b 0))
|
(b_lo Gpr (value_regs_get_gpr b 0))
|
||||||
@@ -4398,7 +4409,7 @@
|
|||||||
(x64_test (OperandSize.Size64) (RegMemImm.Imm 1) cmp)
|
(x64_test (OperandSize.Size64) (RegMemImm.Imm 1) cmp)
|
||||||
(CC.NZ))))
|
(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))
|
(let ((a_lo Gpr (value_regs_get_gpr a 0))
|
||||||
(a_hi Gpr (value_regs_get_gpr a 1))
|
(a_hi Gpr (value_regs_get_gpr a 1))
|
||||||
(b_lo Gpr (value_regs_get_gpr b 0))
|
(b_lo Gpr (value_regs_get_gpr b 0))
|
||||||
@@ -4413,7 +4424,7 @@
|
|||||||
|
|
||||||
;; Result = (a_hi <> b_hi) ||
|
;; Result = (a_hi <> b_hi) ||
|
||||||
;; (a_hi == b_hi && a_lo <> b_lo)
|
;; (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))
|
(let ((a_lo Gpr (value_regs_get_gpr a 0))
|
||||||
(a_hi Gpr (value_regs_get_gpr a 1))
|
(a_hi Gpr (value_regs_get_gpr a 1))
|
||||||
(b_lo Gpr (value_regs_get_gpr b 0))
|
(b_lo Gpr (value_regs_get_gpr b 0))
|
||||||
|
|||||||
@@ -383,7 +383,7 @@ block2:
|
|||||||
; pushq %rbp
|
; pushq %rbp
|
||||||
; movq %rsp, %rbp
|
; movq %rsp, %rbp
|
||||||
; block0:
|
; block0:
|
||||||
; cmpq $0, %rdi
|
; testq %rdi, %rdi
|
||||||
; jl label2; j label1
|
; jl label2; j label1
|
||||||
; block1:
|
; block1:
|
||||||
; xorl %eax, %eax, %eax
|
; xorl %eax, %eax, %eax
|
||||||
@@ -401,14 +401,14 @@ block2:
|
|||||||
; pushq %rbp
|
; pushq %rbp
|
||||||
; movq %rsp, %rbp
|
; movq %rsp, %rbp
|
||||||
; block1: ; offset 0x4
|
; block1: ; offset 0x4
|
||||||
; cmpq $0, %rdi
|
; testq %rdi, %rdi
|
||||||
; jl 0x15
|
; jl 0x14
|
||||||
; block2: ; offset 0xe
|
; block2: ; offset 0xd
|
||||||
; xorl %eax, %eax
|
; xorl %eax, %eax
|
||||||
; movq %rbp, %rsp
|
; movq %rbp, %rsp
|
||||||
; popq %rbp
|
; popq %rbp
|
||||||
; retq
|
; retq
|
||||||
; block3: ; offset 0x15
|
; block3: ; offset 0x14
|
||||||
; movl $1, %eax
|
; movl $1, %eax
|
||||||
; movq %rbp, %rsp
|
; movq %rbp, %rsp
|
||||||
; popq %rbp
|
; popq %rbp
|
||||||
@@ -431,7 +431,7 @@ block2:
|
|||||||
; pushq %rbp
|
; pushq %rbp
|
||||||
; movq %rsp, %rbp
|
; movq %rsp, %rbp
|
||||||
; block0:
|
; block0:
|
||||||
; cmpl $0, %edi
|
; testl %edi, %edi
|
||||||
; jl label2; j label1
|
; jl label2; j label1
|
||||||
; block1:
|
; block1:
|
||||||
; xorl %eax, %eax, %eax
|
; xorl %eax, %eax, %eax
|
||||||
@@ -449,8 +449,152 @@ block2:
|
|||||||
; pushq %rbp
|
; pushq %rbp
|
||||||
; movq %rsp, %rbp
|
; movq %rsp, %rbp
|
||||||
; block1: ; offset 0x4
|
; block1: ; offset 0x4
|
||||||
; cmpl $0, %edi
|
; testl %edi, %edi
|
||||||
; jl 0x14
|
; 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
|
; block2: ; offset 0xd
|
||||||
; xorl %eax, %eax
|
; xorl %eax, %eax
|
||||||
; movq %rbp, %rsp
|
; movq %rbp, %rsp
|
||||||
|
|||||||
@@ -238,3 +238,33 @@ block0(v0: i64):
|
|||||||
; popq %rbp
|
; popq %rbp
|
||||||
; retq
|
; 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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user