// #target: linux-riscv64
module test;

struct Large {
  long a, b, c, d;
}
// Scalars passed on the stack should not have signext/zeroext attributes
// (they are anyext).
typedef Char32V = char[<32>] @simd;

fn int f_scalar_stack_1(int a, int128 b, double c, float128 d, Char32V e, char f, ichar g, char h)
{
	return g + h;
}

// Ensure that scalars passed on the stack are still determined correctly in
// the presence of large return values that consume a register due to the need
// to pass a pointer.

fn Large f_scalar_stack_2(double a, int128 b, float128 c, Char32V d, char e, ichar f, char g)
{
	return {(long)a, e, f, g};
}

/* #expect: test.ll

define signext i32 @test.f_scalar_stack_1(i32 signext %0, i128 %1, double %2, fp128 %3, ptr align 32 %4, i8 zeroext %5, i8 %6, i8 %7) #0 {
entry:
  %sext = sext i8 %6 to i32
  %zext = zext i8 %7 to i32
  %add = add i32 %sext, %zext
  ret i32 %add
}

; Function Attrs:
define void @test.f_scalar_stack_2(ptr noalias sret(%Large) align 8 %0, double %1, i128 %2, fp128 %3, ptr align 32 %4, i8 zeroext %5, i8 %6, i8 %7) #0 {
entry:
  %literal = alloca %Large, align 8
  %fpsi = fptosi double %1 to i64
  store i64 %fpsi, ptr %literal, align 8
  %ptradd = getelementptr inbounds i8, ptr %literal, i64 8
  %zext = zext i8 %5 to i64
  store i64 %zext, ptr %ptradd, align 8
  %ptradd1 = getelementptr inbounds i8, ptr %literal, i64 16
  %sext = sext i8 %6 to i64
  store i64 %sext, ptr %ptradd1, align 8
  %ptradd2 = getelementptr inbounds i8, ptr %literal, i64 24
  %zext3 = zext i8 %7 to i64
  store i64 %zext3, ptr %ptradd2, align 8
  call void @llvm.memcpy.p0.p0.i32(ptr align 8 %0, ptr align 8 %literal, i32 32, i1 false)
  ret void
}