blob: b2862a900d4f0a43ded62766ccf3cb1cfe2ae26c [file] [edit]
// REQUIRES: riscv-registered-target
// RUN: %clang_cc1 -std=c++11 -triple riscv64-none-linux-gnu -target-feature +v \
// RUN: -mvscale-min=4 -mvscale-max=4 -emit-llvm -o - %s | FileCheck %s
#include <riscv_vector.h>
typedef vint32m1_t fixed_int32m1_t __attribute__((riscv_rvv_vector_bits(__riscv_v_fixed_vlen)));
//===----------------------------------------------------------------------===//
// Eligible cases work in C++ the same as C
//===----------------------------------------------------------------------===//
struct st_1field { fixed_int32m1_t x; };
// CHECK-LABEL: @test_1field(
// CHECK-SAME: <vscale x 2 x i32>
extern "C" void test_1field(st_1field s) {}
struct st_2field { fixed_int32m1_t x; fixed_int32m1_t y; };
// CHECK-LABEL: @test_2field(
// CHECK-SAME: target("riscv.vector.tuple", <vscale x 8 x i8>, 2)
extern "C" void test_2field(st_2field s) {}
//===----------------------------------------------------------------------===//
// Ineligible: struct with base class → passed indirectly
//
// detectHomogeneousRVVFixedLengthStruct rejects any struct with base classes
// to avoid having to reason about their layout contribution.
//===----------------------------------------------------------------------===//
struct empty_base {};
struct derived_1field : empty_base { fixed_int32m1_t x; };
// CHECK-LABEL: @test_base_class(
// CHECK-SAME: ptr
extern "C" void test_base_class(derived_1field s) {}
//===----------------------------------------------------------------------===//
// Ineligible: non-trivial copy constructor → passed indirectly
//
// Handled by getRecordArgABI before detectHomogeneousRVVFixedLengthStruct
// is ever consulted.
//===----------------------------------------------------------------------===//
struct nontrivial_copy {
fixed_int32m1_t x;
nontrivial_copy(const nontrivial_copy &) {}
};
// CHECK-LABEL: @test_nontrivial_copy(
// CHECK-SAME: ptr
extern "C" void test_nontrivial_copy(nontrivial_copy s) {}
//===----------------------------------------------------------------------===//
// Ineligible: non-trivial destructor → passed indirectly
//
// Also handled by getRecordArgABI before reaching our function.
//===----------------------------------------------------------------------===//
struct nontrivial_dtor {
fixed_int32m1_t x;
~nontrivial_dtor() {}
};
// CHECK-LABEL: @test_nontrivial_dtor(
// CHECK-SAME: ptr
extern "C" void test_nontrivial_dtor(nontrivial_dtor s) {}