Skip to content

Function gets optimized away unless marked #[inline(never)] pub fn #122516

Closed
@spcan

Description

@spcan

I am using this function to decode gray coded u64 into decimal values (also u64).

fn decimal(mut gray: u64) -> u64 {
    // Copy the gray value.
    let mut temp = gray;

    while temp != 0 {
        // Shift right temp.
        temp >>= 1;

        // XOR the gray value.
        gray ^= temp;
    }

    gray
}

Target architecture is thumbv8.main-none-eabihf with RUSTFLAGS:

rustflags = [
    "-C", "link-arg=--nmagic",
    "-C", "link-arg=-Tlink.x",
    #"-C", "link-arg=-Tmemory.x",
    "-C", "link-arg=-Tdefmt.x",

    # Code optimizations
    #"-Z", "trap-unreachable=no",
    #"-C", "inline-threshold=5",
    #"-C", "no-vectorize-loops",

    # Fixes LLVM bug on function outlining
    "-C", "llvm-args=--enable-machine-outliner=never",
]

The resulting code should be a function that transforms the input gray code into a decimal. Instead, the function gets optimized to directly return the input u64. The final assembly of this function is:

00001190 <_ZN7lpc55006timers7ostimer7decimal17h543acbca5175c913E>:
    1190:	4770      	bx	lr

To make the code correctly appear, the function must be marked with #[inline(never)], #[no_mangle] and extern "Rust". Additionally, if the function is a member of a struct impl not matter what it always get optimized away.

Correct function signature:

#[inline(never)]
#[no_mangle]
extern "Rust" fn decimal(mut gray: u64) -> u64 {}

Correct assembly:

00001190 <decimal>:
    1190:	ea50 0201 	orrs.w	r2, r0, r1
    1194:	bf02      	ittt	eq
    1196:	2000      	moveq	r0, #0
    1198:	2100      	moveq	r1, #0
    119a:	4770      	bxeq	lr
    119c:	b5d0      	push	{r4, r6, r7, lr}
    119e:	af02      	add	r7, sp, #8
    11a0:	4604      	mov	r4, r0
    11a2:	460b      	mov	r3, r1
    11a4:	ea5f 0c53 	movs.w	ip, r3, lsr #1
    11a8:	ea81 010c 	eor.w	r1, r1, ip
    11ac:	ea4f 0e34 	mov.w	lr, r4, rrx
    11b0:	ea80 000e 	eor.w	r0, r0, lr
    11b4:	ea5e 020c 	orrs.w	r2, lr, ip
    11b8:	d01d      	beq.n	11f6 <decimal+0x66>
    11ba:	08a2      	lsrs	r2, r4, #2
    11bc:	ea81 0193 	eor.w	r1, r1, r3, lsr #2
    11c0:	ea42 7283 	orr.w	r2, r2, r3, lsl #30
    11c4:	4050      	eors	r0, r2
    11c6:	ea52 0293 	orrs.w	r2, r2, r3, lsr #2
    11ca:	bf1f      	itttt	ne
    11cc:	ea81 01d3 	eorne.w	r1, r1, r3, lsr #3
    11d0:	08e2      	lsrne	r2, r4, #3
    11d2:	ea42 7243 	orrne.w	r2, r2, r3, lsl #29
    11d6:	4050      	eorne	r0, r2
    11d8:	bf18      	it	ne
    11da:	ea52 02d3 	orrsne.w	r2, r2, r3, lsr #3
    11de:	d00a      	beq.n	11f6 <decimal+0x66>
    11e0:	0922      	lsrs	r2, r4, #4
    11e2:	ea42 7403 	orr.w	r4, r2, r3, lsl #28
    11e6:	ea81 1113 	eor.w	r1, r1, r3, lsr #4
    11ea:	4060      	eors	r0, r4
    11ec:	ea54 1213 	orrs.w	r2, r4, r3, lsr #4
    11f0:	ea4f 1313 	mov.w	r3, r3, lsr #4
    11f4:	d1d6      	bne.n	11a4 <decimal+0x14>
    11f6:	bdd0      	pop	{r4, r6, r7, pc}

Meta

rustc --version --verbose:

rustc 1.78.0-nightly (3cbb93223 2024-03-13)
binary: rustc
commit-hash: 3cbb93223f33024db464a4df27a13c7cce870173
commit-date: 2024-03-13
host: x86_64-unknown-linux-gnu
release: 1.78.0-nightly
LLVM version: 18.1.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions