Skip to content

RISC-V Codegen Problem with type information #114508

Closed
@coastalwhite

Description

@coastalwhite

Codegen for riscv64gc-unknown-linux-gnu sends wrong type information to LLVM.

When I compile on godbolt.org with the following flags.

GodBolt Link

--target=riscv64gc-unknown-linux-gnu -C target-feature=+zbb -C opt-level=3

I tried this code:

fn max(a: u32, b: u32) -> u32 {
    u32::max(a, b)
}

It outputs:

example::max:
        sext.w  a1, a1
        sext.w  a0, a0
        maxu    a0, a0, a1
        ret

It definitely does not need to sign extend a0 or a1 and in fact, when we inspect the LLVM IR, it seems to assume that the numbers are i32s instead of u32s. Is this a problem with Rust's codegen output?

LLVM IR:

; example::max
define noundef i32 @example::max(i32 noundef %a, i32 noundef %b) unnamed_addr personality ptr @rust_eh_personality {
start:
  %.0.sroa.speculated.i = tail call i32 @llvm.umax.i32(i32 %a, i32 %b)
  ret i32 %.0.sroa.speculated.i
}

declare noundef signext i32 @rust_eh_personality(i32 noundef signext, i32 noundef signext, i64 noundef, ptr noundef, ptr noundef) unnamed_addr #1

declare i32 @llvm.umax.i32(i32, i32) #2

Properly optimized code would be:

example::max:
        maxu    a0, a0, a1
        ret

Metadata

Metadata

Assignees

Labels

A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-codegenArea: Code generationC-bugCategory: This is a bug.O-riscvTarget: RISC-V architectureT-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