Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ptrtoint / inttoptr issues? #283

Open
Chobbes opened this issue Jul 25, 2022 · 1 comment
Open

Ptrtoint / inttoptr issues? #283

Chobbes opened this issue Jul 25, 2022 · 1 comment

Comments

@Chobbes
Copy link
Member

Chobbes commented Jul 25, 2022

This test program returns 0 in vellvm (which is what I expect), and 144 with clang:

define  i8 @main() {
b0:
    %v0 = alloca i32
    store i32 0, i32* %v0, align 1
    %v1 = ptrtoint i32* %v0 to i64
    %v2 = inttoptr i64 %v1 to <{<3 x i8>, [0 x double], i8}>*
    br label %b1

b1:
    %v3 = load <{<3 x i8>, [0 x double], i8}>, <{<3 x i8>, [0 x double], i8}>* %v2, align 1
    %v4 = extractvalue <{<3 x i8>, [0 x double], i8}> %v3, 2
    ret i8 %v4
}

Not sure what clang is doing. The issue persists even without the size 0 memory of the structure:

define  i8 @main() {
b0:
    %v0 = alloca i32
    store i32 0, i32* %v0, align 1
    %v1 = ptrtoint i32* %v0 to i64
    %v2 = inttoptr i64 %v1 to <{<3 x i8>, i8}>*
    br label %b1

b1:
    %v3 = load <{<3 x i8>, i8}>, <{<3 x i8>, i8}>* %v2, align 1
    %v4 = extractvalue <{<3 x i8>, i8}> %v3, 2
    ret i8 %v4
}

However, the issue disappears when directly allocating a packed structure, instead of using ptoi / itop to cast to a packed structure.

@Chobbes Chobbes self-assigned this Jul 25, 2022
@Chobbes
Copy link
Member Author

Chobbes commented Jul 25, 2022

I've tried a couple of different combinations of types instead of <3 x i8>, and I don't understand the results:

  • i24: Issue persists, 144 is returned.
  • [3 x i8]: 0 is returned (expected result).
  • <{i8, i8, i8}>: 0 is returned.

Interestingly the assembly language for the i24 and <3 x i8> cases is different, but returns the same bogus value. both seem to copy a 32-bit dword value of 0 to the stack, and then read the fifth byte ([rax + 4]) into al. I believe this should be the fourth byte instead ([rax + 3]). Though the registers end up being different, in the array and packed structure cases (which produce identical assembly) this is the case.

<3 x i8> assembly:

	.text
	.intel_syntax noprefix
	.file	"temporary_vellvm.ll"
	.globl	main                            # -- Begin function main
	.p2align	4, 0x90
	.type	main,@function
main:                                   # @main
	.cfi_startproc
# %bb.0:                                # %b0
	mov	dword ptr [rsp - 4], 0
	lea	rax, [rsp - 4]
	mov	qword ptr [rsp - 32], rax       # 8-byte Spill
# %bb.1:                                # %b1
	mov	rax, qword ptr [rsp - 32]       # 8-byte Reload
	movzx	ecx, word ptr [rax]
	movd	xmm0, ecx
	movaps	xmmword ptr [rsp - 24], xmm0
	mov	cl, byte ptr [rax + 2]
	mov	al, byte ptr [rax + 4]
	mov	cl, byte ptr [rsp - 24]
	mov	cl, byte ptr [rsp - 23]
	ret
.Lfunc_end0:
	.size	main, .Lfunc_end0-main
	.cfi_endproc
                                        # -- End function
	.section	".note.GNU-stack","",@progbits
	.addrsig

i24 assembly:

	.text
	.intel_syntax noprefix
	.file	"temporary_vellvm.ll"
	.globl	main                            # -- Begin function main
	.p2align	4, 0x90
	.type	main,@function
main:                                   # @main
	.cfi_startproc
# %bb.0:                                # %b0
	mov	dword ptr [rsp - 4], 0
	lea	rax, [rsp - 4]
	mov	qword ptr [rsp - 16], rax       # 8-byte Spill
# %bb.1:                                # %b1
	mov	rax, qword ptr [rsp - 16]       # 8-byte Reload
	movzx	ecx, word ptr [rax]
	movzx	edx, byte ptr [rax + 2]
	shl	edx, 16
	or	ecx, edx
	mov	al, byte ptr [rax + 4]
	ret
.Lfunc_end0:
	.size	main, .Lfunc_end0-main
	.cfi_endproc
                                        # -- End function
	.section	".note.GNU-stack","",@progbits
	.addrsig

<{i8, i8, i8}> / [3 x i8] assembly:

	.text
	.intel_syntax noprefix
	.file	"temporary_vellvm.ll"
	.globl	main                            # -- Begin function main
	.p2align	4, 0x90
	.type	main,@function
main:                                   # @main
	.cfi_startproc
# %bb.0:                                # %b0
	mov	dword ptr [rsp - 4], 0
	lea	rax, [rsp - 4]
	mov	qword ptr [rsp - 16], rax       # 8-byte Spill
# %bb.1:                                # %b1
	mov	rcx, qword ptr [rsp - 16]       # 8-byte Reload
	mov	al, byte ptr [rcx + 3]
	mov	dl, byte ptr [rcx + 2]
	mov	dl, byte ptr [rcx]
	mov	cl, byte ptr [rcx + 1]
	ret
.Lfunc_end0:
	.size	main, .Lfunc_end0-main
	.cfi_endproc
                                        # -- End function
	.section	".note.GNU-stack","",@progbits
	.addrsig

Is this a bug in LLVM with how i24 and vector members of packed structs are handled with extractvalue? Are the pointer / integer casts illegal?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant