Skip to content

[RISCV] Clang implements lp64d ABI incorrectly for inherited structs #57084

Closed
llvm/llvm-project-release-prs
#120
@SixWeining

Description

@SixWeining

As the ABI described: A struct containing one floating-point real and one integer (or bitfield), in either order, is passed in a floating-point register and an integer register, provided the floating-point real is no more than ABI_FLEN bits wide and the integer is no more than XLEN bits wide, and at least one floating-point argument register and at least one integer argument register is available.

Values are returned in the same manner as a first named argument of the same type would be passed.

But for this C++ code:

// test.cpp
struct Parent {
  int i;
};

struct Child : Parent {
  float f;
};

struct Child foo(struct Child x) {
  return x;
}
; $ ./build/bin/clang++ --target=riscv64 -mabi=lp64d -emit-llvm -S test.cpp -o -
; ModuleID = 'test.cpp'
source_filename = "test.cpp"
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128"
target triple = "riscv64"

%struct.Child = type { %struct.Parent, float }
%struct.Parent = type { i32 }

; Function Attrs: mustprogress noinline nounwind optnone
define dso_local float @_Z3foo5Child(float %0) #0 {                       ;;;;;;;;;;;; Error: Only the float is passed and returned.
entry:
  %retval = alloca %struct.Child, align 4
  %x = alloca %struct.Child, align 4
  %1 = getelementptr inbounds <{ [4 x i8], float }>, ptr %x, i32 0, i32 1
  store float %0, ptr %1, align 4
  %i = getelementptr inbounds %struct.Parent, ptr %retval, i32 0, i32 0
  store i32 1, ptr %i, align 4
  %2 = getelementptr inbounds <{ [4 x i8], float }>, ptr %retval, i32 0, i32 1
  %3 = load float, ptr %2, align 4
  ret float %3
}

attributes #0 = { mustprogress noinline nounwind optnone "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+64bit,+a,+c,+d,+f,+m,+relax,-save-restore" }

!llvm.module.flags = !{!0, !1, !2, !3}
!llvm.ident = !{!4}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 1, !"target-abi", !"lp64d"}
!2 = !{i32 7, !"frame-pointer", i32 2}
!3 = !{i32 1, !"SmallDataLimit", i32 8}
!4 = !{!"clang version 16.0.0 (...)"}

Metadata

Metadata

Assignees

Type

No type

Projects

Status

Done

Relationships

None yet

Development

No branches or pull requests

Issue actions