llvm/clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/rvv-tuple-type.c

// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
// REQUIRES: riscv-registered-target
// RUN: %clang_cc1 -triple riscv64 -target-feature +zve32x -O0 \
// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=O0
// RUN: %clang_cc1 -triple riscv64 -target-feature +zve32x -disable-O0-optnone \
// RUN:   -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck %s --check-prefix=AFTER_MEM2REG

// This test case tests the lowering of RVV tuple types into LLVM IR.

#include <riscv_vector.h>

// Declare local variable
// O0-LABEL: define dso_local void @foo
// O0-SAME: () #[[ATTR0:[0-9]+]] {
// O0-NEXT:  entry:
// O0-NEXT:    [[V_TUPLE:%.*]] = alloca target("riscv.vector.tuple", <vscale x 8 x i8>, 2), align 4
// O0-NEXT:    ret void
//
// AFTER_MEM2REG-LABEL: define dso_local void @foo
// AFTER_MEM2REG-SAME: () #[[ATTR0:[0-9]+]] {
// AFTER_MEM2REG-NEXT:  entry:
// AFTER_MEM2REG-NEXT:    ret void
//
void foo() {
  __rvv_int32m1x2_t v_tuple;
}

// Declare local variable and return
// O0-LABEL: define dso_local target("riscv.vector.tuple", <vscale x 8 x i8>, 2) @bar
// O0-SAME: () #[[ATTR0]] {
// O0-NEXT:  entry:
// O0-NEXT:    [[V_TUPLE:%.*]] = alloca target("riscv.vector.tuple", <vscale x 8 x i8>, 2), align 4
// O0-NEXT:    [[TMP0:%.*]] = load target("riscv.vector.tuple", <vscale x 8 x i8>, 2), ptr [[V_TUPLE]], align 4
// O0-NEXT:    ret target("riscv.vector.tuple", <vscale x 8 x i8>, 2) [[TMP0]]
//
// AFTER_MEM2REG-LABEL: define dso_local target("riscv.vector.tuple", <vscale x 8 x i8>, 2) @bar
// AFTER_MEM2REG-SAME: () #[[ATTR0]] {
// AFTER_MEM2REG-NEXT:  entry:
// AFTER_MEM2REG-NEXT:    ret target("riscv.vector.tuple", <vscale x 8 x i8>, 2) undef
//
__rvv_int32m1x2_t bar() {
  __rvv_int32m1x2_t v_tuple;
  return v_tuple;
}

// Pass as function parameter
// O0-LABEL: define dso_local void @baz
// O0-SAME: (target("riscv.vector.tuple", <vscale x 8 x i8>, 2) [[V_TUPLE:%.*]]) #[[ATTR0]] {
// O0-NEXT:  entry:
// O0-NEXT:    [[V_TUPLE_ADDR:%.*]] = alloca target("riscv.vector.tuple", <vscale x 8 x i8>, 2), align 4
// O0-NEXT:    store target("riscv.vector.tuple", <vscale x 8 x i8>, 2) [[V_TUPLE]], ptr [[V_TUPLE_ADDR]], align 4
// O0-NEXT:    ret void
//
// AFTER_MEM2REG-LABEL: define dso_local void @baz
// AFTER_MEM2REG-SAME: (target("riscv.vector.tuple", <vscale x 8 x i8>, 2) [[V_TUPLE:%.*]]) #[[ATTR0]] {
// AFTER_MEM2REG-NEXT:  entry:
// AFTER_MEM2REG-NEXT:    ret void
//
void baz(__rvv_int32m1x2_t v_tuple) {
}

// Pass as function parameter and return
// O0-LABEL: define dso_local target("riscv.vector.tuple", <vscale x 8 x i8>, 2) @qux
// O0-SAME: (target("riscv.vector.tuple", <vscale x 8 x i8>, 2) [[V_TUPLE:%.*]]) #[[ATTR0]] {
// O0-NEXT:  entry:
// O0-NEXT:    [[V_TUPLE_ADDR:%.*]] = alloca target("riscv.vector.tuple", <vscale x 8 x i8>, 2), align 4
// O0-NEXT:    store target("riscv.vector.tuple", <vscale x 8 x i8>, 2) [[V_TUPLE]], ptr [[V_TUPLE_ADDR]], align 4
// O0-NEXT:    [[TMP0:%.*]] = load target("riscv.vector.tuple", <vscale x 8 x i8>, 2), ptr [[V_TUPLE_ADDR]], align 4
// O0-NEXT:    ret target("riscv.vector.tuple", <vscale x 8 x i8>, 2) [[TMP0]]
//
// AFTER_MEM2REG-LABEL: define dso_local target("riscv.vector.tuple", <vscale x 8 x i8>, 2) @qux
// AFTER_MEM2REG-SAME: (target("riscv.vector.tuple", <vscale x 8 x i8>, 2) [[V_TUPLE:%.*]]) #[[ATTR0]] {
// AFTER_MEM2REG-NEXT:  entry:
// AFTER_MEM2REG-NEXT:    ret target("riscv.vector.tuple", <vscale x 8 x i8>, 2) [[V_TUPLE]]
//
__rvv_int32m1x2_t qux(__rvv_int32m1x2_t v_tuple) {
  return v_tuple;
}

// O0-LABEL: define dso_local target("riscv.vector.tuple", <vscale x 8 x i8>, 2) @quux
// O0-SAME: (target("riscv.vector.tuple", <vscale x 8 x i8>, 2) [[V_TUPLE:%.*]]) #[[ATTR0]] {
// O0-NEXT:  entry:
// O0-NEXT:    [[V_TUPLE_ADDR:%.*]] = alloca target("riscv.vector.tuple", <vscale x 8 x i8>, 2), align 4
// O0-NEXT:    store target("riscv.vector.tuple", <vscale x 8 x i8>, 2) [[V_TUPLE]], ptr [[V_TUPLE_ADDR]], align 4
// O0-NEXT:    [[TMP0:%.*]] = load target("riscv.vector.tuple", <vscale x 8 x i8>, 2), ptr [[V_TUPLE_ADDR]], align 4
// O0-NEXT:    [[CALL:%.*]] = call target("riscv.vector.tuple", <vscale x 8 x i8>, 2) @qux(target("riscv.vector.tuple", <vscale x 8 x i8>, 2) [[TMP0]])
// O0-NEXT:    ret target("riscv.vector.tuple", <vscale x 8 x i8>, 2) [[CALL]]
//
// AFTER_MEM2REG-LABEL: define dso_local target("riscv.vector.tuple", <vscale x 8 x i8>, 2) @quux
// AFTER_MEM2REG-SAME: (target("riscv.vector.tuple", <vscale x 8 x i8>, 2) [[V_TUPLE:%.*]]) #[[ATTR0]] {
// AFTER_MEM2REG-NEXT:  entry:
// AFTER_MEM2REG-NEXT:    [[CALL:%.*]] = call target("riscv.vector.tuple", <vscale x 8 x i8>, 2) @qux(target("riscv.vector.tuple", <vscale x 8 x i8>, 2) [[V_TUPLE]])
// AFTER_MEM2REG-NEXT:    ret target("riscv.vector.tuple", <vscale x 8 x i8>, 2) [[CALL]]
//
__rvv_int32m1x2_t quux(__rvv_int32m1x2_t v_tuple) {
  return qux(v_tuple);
}